-
Notifications
You must be signed in to change notification settings - Fork 11
The basics
Johan Verwey edited this page May 24, 2018
·
11 revisions
Here is what a basic gouraud shader might look like written in F#.
type Shader(scene:SceneConstants,
obj:ObjectConstants,
mat:MaterialConstants) =
[<VertexShader>]
member m.vertex(input:VSInput) =
PSInput(input.Position * obj.WorldViewProjection,
input.Normal * float3x3(obj.World))
[<PixelShader>]
member m.pixel(input:PSInput) =
input.Normal
|> normalize
|> dot -scene.LightDirection
|> mul mat.Diffuse
|> saturate
|> withAlpha 1.0f
At runtime, this would be translated to the following HLSL:
PSInput vertex(VSInput input)
{
PSInput o;
o.PositionHS = mul(input.Position,WorldViewProjection);
o.Normal = mul(input.Normal,(float3x3)(World));
return o;
};
float4 pixel(PSInput input) : SV_TARGET
{
float3 temp = saturate(mul(Diffuse,dot(-(LightDirection),normalize(input.Normal))));
return float4(temp,1);
};
The shaders constants are defined below. Note that the ConstantPacking attribute will enforce the HLSL packing rules at compile time to facilitate marshalling data from the Cpu to the Gpu.
[<Struct; ConstantPacking>]
type SceneConstants(lightDir:float3) =
member m.LightDirection = lightDir
[<Struct; ConstantPacking>]
type MaterialConstants(diffuse:float3) =
member m.Diffuse = diffuse
[<Struct; ConstantPacking>]
type ObjectConstants(wvp:float4x4, w:float4x4) =
member m.WorldViewProjection = wvp
member m.World = w
[<Struct>]
type VSInput(p:float4, n:float3) =
member m.Position = p
member m.Normal = n
[<Struct>]
type PSInput(p:float4, n:float3) =
member m.PositionHS = p
member m.Normal = n