v 0. Pasted by Zeux as cpp at 2007-10-28 23:35:17 MSK and set expiration to never.

Paste will expire never. Expiration is locked.

  1. #define LIGHT_SPACE "World"
  2. #include "bindings.h"
  3.  
  4. struct VS_IN
  5. {
  6.     float4 position: POSITION;
  7.  
  8.     float2 texcoord: TEXCOORD;
  9.  
  10.     float3 tangent: TANGENT;
  11.     float3 bitangent: BINORMAL;
  12.     float3 normal: NORMAL;
  13. };
  14.  
  15. struct VS_OUT
  16. {
  17.     float2 texcoord: TEXCOORD0;
  18.  
  19.     // position (world space)
  20.     float3 position: TEXCOORD1;
  21.  
  22.     // view vector (world space)
  23.     float3 view: TEXCOORD2;
  24.    
  25.     // tangent space->world space matrix
  26.     // pre-multiplied by (2 0 0 -1)
  27.     //                   (0 2 0 -1)
  28.     //                   (0 0 2 -1)
  29.     // (perform [0,1] -> [-1,1] expansion
  30.  
  31.     float3x4 TBN: TEXCOORD3;
  32. };
  33.  
  34. uniform float4x4 world: World;
  35. uniform float4x4 world_view_projection: WorldViewProjection;
  36. uniform float4x4 view_inverse: ViewInverse;
  37.  
  38. VS_OUT vs_main(VS_IN I, out float4 clippos: POSITION)
  39. {
  40.     clippos = mul(I.position, world_view_projection);
  41.  
  42.     VS_OUT O;
  43.    
  44.     O.texcoord = I.texcoord;
  45.    
  46.     O.position = mul(I.position, world);
  47.    
  48.     float3 eye_pos = mul(float4(0, 0, 0, 1), view_inverse);
  49.     O.view = normalize(O.position - eye_pos);
  50.    
  51.     // world space TBN basis
  52.     float3 tangent = mul(world, float4(I.tangent, 0));
  53.     float3 bitangent = mul(world, float4(I.bitangent, 0));
  54.     float3 normal = mul(world, float4(I.normal, 0));
  55.    
  56.     // tangent -> world space matrix
  57.     O.TBN[0] = float4(tangent.x, bitangent.x, normal.x, 0);
  58.     O.TBN[1] = float4(tangent.y, bitangent.y, normal.y, 0);
  59.     O.TBN[2] = float4(tangent.z, bitangent.z, normal.z, 0);
  60.    
  61.     // normal [0, 1] -> [-1, 1] expansion
  62.     O.TBN = mul(O.TBN, float4x4(2, 0, 0, -1,
  63.                                 0, 2, 0, -1,
  64.                                 0, 0, 2, -1,
  65.                                 0, 0, 0, 1));
  66.  
  67.     return O;
  68. }
  69.  
  70. // light position, world space
  71. static float3 light_positions[8] =
  72. {
  73.     Lamp1Pos, Lamp2Pos, Lamp3Pos, Lamp4Pos,
  74.     Lamp5Pos, Lamp6Pos, Lamp7Pos, Lamp8Pos
  75. };
  76.  
  77. // light colors
  78. static float3 light_colors[8] =
  79. {
  80.     Lamp1Col, Lamp2Col, Lamp3Col, Lamp4Col,
  81.     Lamp5Col, Lamp6Col, Lamp7Col, Lamp8Col
  82. };
  83.  
  84. // 1 / light radius^2
  85. uniform float4 light_radius_inv[2] =
  86. {
  87.     (1 / 0.25).xxxx,
  88.     (1 / 0.25).xxxx
  89. };
  90.  
  91. // specular power A, B constant
  92. // http://www.gamasutra.com/features/20020801/beaudoin_01.htm
  93. // m = 2, n = 18 => A = 6.645, B = -5.645
  94. static const float2 specular_ab = float2(6.645, -5.645);
  95.  
  96. texture diffuse_texture;
  97. uniform sampler2D diffuse_map = TRILINEAR_SAMPLER(diffuse_texture);
  98.  
  99. texture normal_texture;
  100. uniform sampler2D normal_map = TRILINEAR_SAMPLER(normal_texture);
  101.  
  102. texture specular_texture;
  103. uniform sampler2D specular_map = TRILINEAR_SAMPLER(specular_texture);
  104.  
  105. float4 compute_specular_power(float4 v)
  106. {
  107.     // originally: pow(v, N)
  108.     // x^N is roughly equal to (max(Ax+B, 0))^2
  109.     // A,B depend on N
  110.     float4 t = saturate(specular_ab.x * v + specular_ab.y);
  111.     return t * t;
  112. }
  113.  
  114. struct LightingData
  115. {
  116.     float4 diffuse;
  117.     float4 specular;
  118. };
  119.  
  120. LightingData computeLighting4(VS_OUT I, int light_bucket_index, float3 normal)
  121. {
  122.     float3 reflected = reflect(I.view, normal);
  123.  
  124.     float4 NdotL;
  125.     float4 RdotL;
  126.     float4 squared_distances;
  127.  
  128.     for (int i = 0; i < 4; ++i)
  129.     {
  130.         float3 light_vector = light_positions[i + light_bucket_index * 4] - I.position;
  131.  
  132.         float3 light_direction = normalize(light_vector);
  133.  
  134.         NdotL[i] = saturate(dot(light_direction, normal));
  135.         RdotL[i] = saturate(dot(light_direction, reflected));
  136.         squared_distances[i] = dot(light_vector, light_vector);
  137.     }
  138.    
  139.     // attenuation
  140.     // 1 - d^2 / r^2 for diffuse
  141.     float4 atten = squared_distances * light_radius_inv[light_bucket_index];
  142.    
  143.     // modulate diffuse by attenuation
  144.     NdotL = saturate(NdotL - NdotL * atten);
  145.  
  146.     // specular
  147.     float4 spec = compute_specular_power(RdotL);
  148.  
  149.     LightingData data;
  150.  
  151.     data.diffuse = NdotL;
  152.     data.specular = spec;
  153.  
  154.     return data;
  155. }
  156.  
  157. float4 ps_main(VS_OUT I): COLOR
  158. {
  159.     float4 normal_biased = tex2D(normal_map, I.texcoord);
  160.     float3 normal = mul(I.TBN, normal_biased);
  161.    
  162.     LightingData lights[2] =
  163.     {
  164.         computeLighting4(I, 0, normal),
  165.         computeLighting4(I, 1, normal)
  166.     };
  167.    
  168.     // final diffuse color
  169.     float3 diffuse = dot(lights[0].diffuse + lights[1].diffuse, 1).xxx;
  170.    
  171.     for (int i = 0; i < 8; ++i)
  172.     {
  173.         // diffuse += lights[i/4].diffuse[i%4] * light_colors[i];
  174.     }
  175.    
  176.     // final specular color
  177.     float4 specular_color = tex2D(specular_map, I.texcoord);
  178.  
  179.     float3 specular = specular_color.rgb * saturate(dot(lights[0].specular + lights[1].specular, 1));
  180.  
  181.     // final color
  182.     float4 albedo = tex2D(diffuse_map, I.texcoord);
  183.  
  184.     return float4(albedo.rgb * diffuse + specular, albedo.a);
  185. }
  186.  
  187. technique t0
  188. {
  189.     pass p0
  190.     {
  191.         VertexShader = compile vs_1_1 vs_main();
  192.         PixelShader = compile ps_2_a ps_main();
  193.     }
  194. }


Editing is locked.