donderdag 18 augustus 2011

Introduction to HLSL - Part 3

Diffuse lighting
In this part we're going to add some simple diffuse lighting. The new lines compared to the previous part are marked in bold.
// 1: Application inputs
float4x4 object_to_world: WORLD;
float4x4 object_to_clip: WORLDVIEWPROJECTION;
float3 light_pos: LIGHT_POS;
float3 light_color: LIGHT_COLOR;

float3x3 object_to_world3x3 = (float3x3)object_to_world;

// 2: Structures
struct vs_in {
   float4 pos_object: POSITION;
   float3 normal_object: NORMAL;
};

struct ps_in {
   float4 pos_clip: POSITION;
   float3 normal_world: TEXCOORD0;
   float3 light_world: TEXCOORD1;
};

// 3: Vertex Shaders
ps_in vs_main(vs_in input) {
   ps_in output;
   output.pos_clip = mul(input.pos_object, object_to_clip);
   output.normal_world =
      mul(input.normal_object, object_to_world3x3);
   float4 pos_world = mul(input.pos_object, object_to_world);
   output.light_world = light_pos - pos_world.xyz;
   return output;
}

// 4: Pixel Shaders
float4 ps_main(ps_in input) : COLOR {
   float3 result = light_world;
   float3 normal_world = normalize(input.normal_world);
   float3 light_world = normalize(input.light_world);
   result *= saturate(dot(normal_world, light_world));
   return float4(result, 1.f);
}

// 5: Techniques
technique main {
   pass p0 {
      VertexShader = compile vs_3_0 vs_main();
      PixelShader = compile ps_3_0 ps_main();
   }
}
In this example we add the normals (in object space) as inputs to the vertex shader. The vertex shader turns them into world space. Note that the full 4-by-4 transformation matrix includes translation, rotation and scale. For the transformation of normals we are only really interested in the rotation, so we use a reduced 3-by-3 matrix for the transformation. The vertex shader also calculates the vector from the surface of the object to the light source (in world space) and passes this information on to the pixel shader.

Geen opmerkingen:

Een reactie posten