Project Reality: Shader Model 3.0 Considerations#

The Project Reality Team updated Project Reality to support Shader Model 3. The update gave Project Reality more graphical potential. This post considerations when porting shaders from Shader Model 2 to 3.

Fogging#

From Shader Model 3, fogging is no longer fixed-function. You must implement your fogging method in the pixel shader.

Output Register Count#

Input Register Format#

Register Assignments and Declarations#

If you encounter the following asm, with constants not declared in ASM.

VertexShader = asm
{
   vs.1.1

   dcl_position0 v0

   add r0.xyz, v0.xzw, -c[0].xyz
   mul r0.xyz, r0.xyz, c[1].xyw // z = 0, w = 1
   add oPos.x, r0.x, -c[1].w
   add oPos.y, r0.y, -c[1].w
   mov oPos.z, r0.z
   mov oPos.w, c[1].w // z = 0, w = 1
   add r1, v0.y, -c[2].x
   mul oD0, r1, c[2].y
   mov oD0.a, c[1].z // z = 0
};

PixelShader = asm
{
   ps.1.1
   mov r0, v0
};

The solution: use the : register() to a shader variable to a particular register. You can read more about it here.

// Assign variables to registers because DICE didn't do so in their ASM.
float4 Constant0 : register(c0); // c[0]
float4 Constant1 : register(c1); // c[1]
float4 Constant2 : register(c2); // c[2]

struct APP2PS_ProjectRoad
{
   float4 Pos : POSITION0;
};

struct VS2PS_ProjectRoad
{
   float4 HPos : POSITION;
   float4 Color : TEXCOORD0;
};

// VertexShader
VS2PS_ProjectRoad VS_ProjectRoad(APP2PS_ProjectRoad Input)
{
   VS2PS_ProjectRoad Output = (VS2PS_ProjectRoad)0.0;

   // add r0.xyz, v0.xzw, -c[0].xyz
   // mul r0.xyz, r0.xyz, c[1].xyw // z = 0, w = 1
   float3 ProjPos = Input.Pos.xzw - Constant0.xyz;
   ProjPos *= Constant1.xyw; // z = 0, w = 1

   // add oPos.x, r0.x, -c[1].w
   // add oPos.y, r0.y, -c[1].w
   // mov oPos.z, r0.z
   // mov oPos.w, c[1].w // z = 0, w = 1
   Output.HPos.x = ProjPos.x - Constant1.w;
   Output.HPos.y = ProjPos.y - Constant1.w;
   Output.HPos.z = ProjPos.z;
   Output.HPos.w = Constant1.w; // z = 0, w = 1

   // add r1, v0.y, -c[2].x
   // mul oD0, r1, c[2].y
   // mov oD0.a, c[1].z // z = 0
   float4 Color = Input.Pos.y - Constant2.x;
   Output.Color = Color * Constant2.y;
   Output.Color.a = Constant1.z; // z = 0
   Output.Color = saturate(Output.Color);

   return Output;
}

// PixelShader
float4 PS_ProjectRoad(VS2PS_ProjectRoad Input) : COLOR0
{
   // mov r0, v0
   return Input.Color;
}