Paste will expire never. Expiration is locked.
- #define LIGHT_SPACE "World"
- #include "bindings.h"
- struct VS_IN
- {
- float4 position: POSITION;
- float2 texcoord: TEXCOORD;
- float3 tangent: TANGENT;
- float3 bitangent: BINORMAL;
- float3 normal: NORMAL;
- };
- struct VS_OUT
- {
- float2 texcoord: TEXCOORD0;
- // position (world space)
- float3 position: TEXCOORD1;
- // view vector (world space)
- float3 view: TEXCOORD2;
- // tangent space->world space matrix
- // pre-multiplied by (2 0 0 -1)
- // (0 2 0 -1)
- // (0 0 2 -1)
- // (perform [0,1] -> [-1,1] expansion
- float3x4 TBN: TEXCOORD3;
- };
- uniform float4x4 world: World;
- uniform float4x4 world_view_projection: WorldViewProjection;
- uniform float4x4 view_inverse: ViewInverse;
- VS_OUT vs_main(VS_IN I, out float4 clippos: POSITION)
- {
- clippos = mul(I.position, world_view_projection);
- VS_OUT O;
- O.texcoord = I.texcoord;
- O.position = mul(I.position, world);
- float3 eye_pos = mul(float4(0, 0, 0, 1), view_inverse);
- O.view = normalize(O.position - eye_pos);
- // world space TBN basis
- float3 tangent = mul(world, float4(I.tangent, 0));
- float3 bitangent = mul(world, float4(I.bitangent, 0));
- float3 normal = mul(world, float4(I.normal, 0));
- // tangent -> world space matrix
- O.TBN[0] = float4(tangent.x, bitangent.x, normal.x, 0);
- O.TBN[1] = float4(tangent.y, bitangent.y, normal.y, 0);
- O.TBN[2] = float4(tangent.z, bitangent.z, normal.z, 0);
- // normal [0, 1] -> [-1, 1] expansion
- O.TBN = mul(O.TBN, float4x4(2, 0, 0, -1,
- 0, 2, 0, -1,
- 0, 0, 2, -1,
- 0, 0, 0, 1));
- return O;
- }
- // light position, world space
- static float3 light_positions[8] =
- {
- Lamp1Pos, Lamp2Pos, Lamp3Pos, Lamp4Pos,
- Lamp5Pos, Lamp6Pos, Lamp7Pos, Lamp8Pos
- };
- // light colors
- static float3 light_colors[8] =
- {
- Lamp1Col, Lamp2Col, Lamp3Col, Lamp4Col,
- Lamp5Col, Lamp6Col, Lamp7Col, Lamp8Col
- };
- // 1 / light radius^2
- uniform float4 light_radius_inv[2] =
- {
- (1 / 0.25).xxxx,
- (1 / 0.25).xxxx
- };
- // specular power A, B constant
- // http://www.gamasutra.com/features/20020801/beaudoin_01.htm
- // m = 2, n = 18 => A = 6.645, B = -5.645
- static const float2 specular_ab = float2(6.645, -5.645);
- texture diffuse_texture;
- uniform sampler2D diffuse_map = TRILINEAR_SAMPLER(diffuse_texture);
- texture normal_texture;
- uniform sampler2D normal_map = TRILINEAR_SAMPLER(normal_texture);
- texture specular_texture;
- uniform sampler2D specular_map = TRILINEAR_SAMPLER(specular_texture);
- float4 compute_specular_power(float4 v)
- {
- // originally: pow(v, N)
- // x^N is roughly equal to (max(Ax+B, 0))^2
- // A,B depend on N
- float4 t = saturate(specular_ab.x * v + specular_ab.y);
- return t * t;
- }
- struct LightingData
- {
- float4 diffuse;
- float4 specular;
- };
- LightingData computeLighting4(VS_OUT I, int light_bucket_index, float3 normal)
- {
- float3 reflected = reflect(I.view, normal);
- float4 NdotL;
- float4 RdotL;
- float4 squared_distances;
- for (int i = 0; i < 4; ++i)
- {
- float3 light_vector = light_positions[i + light_bucket_index * 4] - I.position;
- float3 light_direction = normalize(light_vector);
- NdotL[i] = saturate(dot(light_direction, normal));
- RdotL[i] = saturate(dot(light_direction, reflected));
- squared_distances[i] = dot(light_vector, light_vector);
- }
- // attenuation
- // 1 - d^2 / r^2 for diffuse
- float4 atten = squared_distances * light_radius_inv[light_bucket_index];
- // modulate diffuse by attenuation
- NdotL = saturate(NdotL - NdotL * atten);
- // specular
- float4 spec = compute_specular_power(RdotL);
- LightingData data;
- data.diffuse = NdotL;
- data.specular = spec;
- return data;
- }
- float4 ps_main(VS_OUT I): COLOR
- {
- float4 normal_biased = tex2D(normal_map, I.texcoord);
- float3 normal = mul(I.TBN, normal_biased);
- LightingData lights[2] =
- {
- computeLighting4(I, 0, normal),
- computeLighting4(I, 1, normal)
- };
- // final diffuse color
- float3 diffuse = dot(lights[0].diffuse + lights[1].diffuse, 1).xxx;
- for (int i = 0; i < 8; ++i)
- {
- // diffuse += lights[i/4].diffuse[i%4] * light_colors[i];
- }
- // final specular color
- float4 specular_color = tex2D(specular_map, I.texcoord);
- float3 specular = specular_color.rgb * saturate(dot(lights[0].specular + lights[1].specular, 1));
- // final color
- float4 albedo = tex2D(diffuse_map, I.texcoord);
- return float4(albedo.rgb * diffuse + specular, albedo.a);
- }
- technique t0
- {
- pass p0
- {
- VertexShader = compile vs_1_1 vs_main();
- PixelShader = compile ps_2_a ps_main();
- }
- }
Editing is locked.