Is there an example showing how to compile shader code?


#1

I want to play around with shaders, how do I compile my BSL files?


#2

Just do this:

HShader shader = gImporter().import<Shader>("myShader.bsl");

If the compilation fails you will get errors in the output window/console.

And you can learn bsf syntax here, as well as the following few manuals.


#3

So I tried to do a shader similar to the bsl example but I don’t see anything on the screen. If I use the default shader I see my mesh so I think it’s ok. Here is my code:

#include “$ENGINE$\PerCameraData.bslinc”
#include “$ENGINE$\PerObjectData.bslinc”
#include “$ENGINE$\VertexInput.bslinc”

shader John
{
mixin PerCameraData;
mixin PerObjectData;
mixin VertexInput;

code
{	
	VStoFS vsmain(VertexInput_PO  input)
	{
		VStoFS output;
	
		float4 worldPosition = getVertexWorldPosition(input);
		
		output.worldPosition = worldPosition.xyz;
		output.position = mul(gMatViewProj, worldPosition);
					
		return output;
	}

	float4 fsmain(in VStoFS input) : SV_Target0
	{
		return float4(1.0f, 1.0f, 1.0f, 1.0f);
	}	
};

};

What am I missing?

Thanks!


#4

In the fragment shader you need to write to multiple render targets. Currently you are only writing to the albedo target, but normals, roughness and metalness are not written to and have undefined values, which results in the lighting calculation giving weird results. Using your shader I actually do get some output, only it’s a perfectly reflecting object - on your end it might look invisible depending on your scene setup and/or hardware.

This should work better:

#include "$ENGINE$\PerCameraData.bslinc"
#include "$ENGINE$\PerObjectData.bslinc"
#include "$ENGINE$\VertexInput.bslinc"
#include "$ENGINE$\GBufferOutput.bslinc"

shader John
{
	mixin PerCameraData;
	mixin PerObjectData;
	mixin VertexInput;
	mixin GBufferOutput;
	
	code
	{	
		VStoFS vsmain(VertexInput_PO  input)
		{
			VStoFS output;
		
			float4 worldPosition = getVertexWorldPosition(input);
			
			output.worldPosition = worldPosition.xyz;
			output.position = mul(gMatViewProj, worldPosition);
						
			return output;
		}

		void fsmain(
			in VStoFS input, 
			out float4 OutGBufferA : SV_Target0,
			out float4 OutGBufferB : SV_Target1,
			out float2 OutGBufferC : SV_Target2)
		{
			SurfaceData surfaceData;
			surfaceData.albedo = float4(1.0f, 1.0f, 1.0f, 1.0f);
			surfaceData.worldNormal.xyz = float3(0.0f, 1.0f, 0.0f);
			surfaceData.roughness = 1.0f;
			surfaceData.metalness = 0.0f;
			
			encodeGBuffer(surfaceData, OutGBufferA, OutGBufferB, OutGBufferC);
		}	
	};
};

The changes are the inclusion of the GBufferOutput mixin and different fsmain. Note your model will look all-black unless you also add some lights.

If you haven’t already check out the CustomMaterials example which showcases how to write custom surface & lighting shaders. If you just want to write raw shaders without needing to know about bsf renderer intricacies you can also take a look at the LowLevelRendering example - although this uses HLSL/GLSL for shader code it can be modified to use the imported BSL shader just as well.


#5

Thanks, that was very helpful.