Example_BumpMapping.cg
上传用户:xhbjoy
上传日期:2014-10-07
资源大小:38068k
文件大小:8k
源码类别:

游戏引擎

开发平台:

Visual C++

  1. // General functions
  2. // Expand a range-compressed vector
  3. float3 expand(float3 v)
  4. {
  5. return (v - 0.5) * 2;
  6. }
  7. /* Bump mapping vertex program
  8.    In this program, we want to calculate the tangent space light vector
  9.    on a per-vertex level which will get passed to the fragment program,
  10.    or to the fixed function dot3 operation, to produce the per-pixel
  11.    lighting effect. 
  12. */
  13. void main_vp(float4 position : POSITION,
  14.  float3 normal : NORMAL,
  15.  float2 uv : TEXCOORD0,
  16.  float3 tangent     : TEXCOORD1,
  17.  // outputs
  18.  out float4 oPosition    : POSITION,
  19.  out float2 oUv  : TEXCOORD0,
  20.  out float3 oTSLightDir  : TEXCOORD1,
  21.  // parameters
  22.  uniform float4 lightPosition, // object space
  23.  uniform float4x4 worldViewProj)
  24. {
  25. // calculate output position
  26. oPosition = mul(worldViewProj, position);
  27. // pass the main uvs straight through unchanged
  28. oUv = uv;
  29. // calculate tangent space light vector
  30. // Get object space light direction
  31. // Non-normalised since we'll do that in the fragment program anyway
  32. float3 lightDir = lightPosition.xyz -  (position * lightPosition.w);
  33. // Calculate the binormal (NB we assume both normal and tangent are
  34. // already normalised)
  35. // NB looks like nvidia cross params are BACKWARDS to what you'd expect
  36. // this equates to NxT, not TxN
  37. float3 binormal = cross(tangent, normal);
  38. // Form a rotation matrix out of the vectors
  39. float3x3 rotation = float3x3(tangent, binormal, normal);
  40. // Transform the light vector according to this matrix
  41. oTSLightDir = mul(rotation, lightDir);
  42. }
  43. /* Bump mapping vertex program for shadow receiving
  44.    In this program, we want to calculate the tangent space light vector
  45.    on a per-vertex level which will get passed to the fragment program,
  46.    or to the fixed function dot3 operation, to produce the per-pixel
  47.    lighting effect. 
  48. */
  49. void main_shadowreceiver_vp(float4 position : POSITION,
  50.  float3 normal : NORMAL,
  51.  float2 uv : TEXCOORD0,
  52.  float3 tangent     : TEXCOORD1,
  53.  
  54.  // outputs
  55.  out float4 oPosition    : POSITION,
  56.  out float4 uvproj  : TEXCOORD0,
  57.  out float2 oUv    : TEXCOORD1,
  58.  out float3 oTSLightDir  : TEXCOORD2,
  59.  
  60.  // parameters
  61.  uniform float4 lightPosition, // object space
  62.  uniform float4x4 worldViewProj,
  63.  uniform float4x4 worldMatrix,
  64.  uniform float4x4 texViewProj)
  65. {
  66. // calculate output position
  67. oPosition = mul(worldViewProj, position);
  68. // pass the main uvs straight through unchanged
  69. oUv = uv;
  70. // calculate tangent space light vector
  71. // Get object space light direction
  72. // Non-normalised since we'll do that in the fragment program anyway
  73. float3 lightDir = lightPosition.xyz -  (position * lightPosition.w);
  74. // Calculate the binormal (NB we assume both normal and tangent are
  75. // already normalised)
  76. // NB looks like nvidia cross params are BACKWARDS to what you'd expect
  77. // this equates to NxT, not TxN
  78. float3 binormal = cross(tangent, normal);
  79. // Form a rotation matrix out of the vectors
  80. float3x3 rotation = float3x3(tangent, binormal, normal);
  81. // Transform the light vector according to this matrix
  82. oTSLightDir = mul(rotation, lightDir);
  83. // Projection
  84.     uvproj = mul(worldMatrix, position);
  85. uvproj = mul(texViewProj, uvproj);
  86. }
  87. void main_fp( float2 uv : TEXCOORD0,
  88.   float3 TSlightDir : TEXCOORD1,
  89.   out float4 colour : COLOR,
  90.   uniform float4 lightDiffuse,
  91.   uniform sampler2D   normalMap : register(s0),
  92.   uniform samplerCUBE normalCubeMap : register(s1) )
  93. {
  94. // retrieve normalised light vector, expand from range-compressed
  95. float3 lightVec = expand(texCUBE(normalCubeMap, TSlightDir).xyz);
  96. // get bump map vector, again expand from range-compressed
  97. float3 bumpVec = expand(tex2D(normalMap, uv).xyz);
  98. // Calculate dot product
  99. colour = lightDiffuse * dot(bumpVec, lightVec);
  100. }
  101. void main_shadowreceiver_fp(
  102.   float4 uvproj : TEXCOORD0,
  103.   float2 uv : TEXCOORD1,
  104.   float3 TSlightDir : TEXCOORD2,
  105.   out float4 colour : COLOR,
  106.   uniform float4 lightDiffuse,
  107.   uniform sampler2D   shadowMap : register(s0),
  108.   uniform sampler2D   normalMap : register(s1),
  109.   uniform samplerCUBE normalCubeMap : register(s2))
  110. {
  111. // retrieve normalised light vector, expand from range-compressed
  112. float3 lightVec = expand(texCUBE(normalCubeMap, TSlightDir).xyz);
  113. // get bump map vector, again expand from range-compressed
  114. float3 bumpVec = expand(tex2D(normalMap, uv).xyz);
  115. // get shadow value
  116. float3 shadow = tex2Dproj(shadowMap, uvproj).xyz;
  117. // Calculate dot product
  118. colour = float4(shadow * lightDiffuse * dot(bumpVec, lightVec), 1.0f);
  119. }
  120. /* Vertex program which includes specular component */
  121. void specular_vp(float4 position : POSITION,
  122.    float3 normal : NORMAL,
  123.    float2 uv : TEXCOORD0,
  124.    float3 tangent     : TEXCOORD1,
  125.    // outputs
  126.    out float4 oPosition    : POSITION,
  127.    out float2 oUv  : TEXCOORD0,
  128.    out float3 oTSLightDir  : TEXCOORD1,
  129.  out float3 oTSHalfAngle : TEXCOORD2,
  130.    // parameters
  131.  uniform float4 lightPosition, // object space
  132.    uniform float3 eyePosition,   // object space
  133.    uniform float4x4 worldViewProj)
  134. {
  135. // calculate output position
  136. oPosition = mul(worldViewProj, position);
  137. // pass the main uvs straight through unchanged
  138. oUv = uv;
  139. // calculate tangent space light vector
  140. // Get object space light direction
  141. float3 lightDir = normalize(lightPosition.xyz -  (position * lightPosition.w));
  142. // Calculate the binormal (NB we assume both normal and tangent are
  143. // already normalised)
  144. // NB looks like nvidia cross params are BACKWARDS to what you'd expect
  145. // this equates to NxT, not TxN
  146. float3 binormal = cross(tangent, normal);
  147. // Form a rotation matrix out of the vectors
  148. float3x3 rotation = float3x3(tangent, binormal, normal);
  149. // Transform the light vector according to this matrix
  150. oTSLightDir = mul(rotation, lightDir);
  151. // Calculate half-angle in tangent space
  152. float3 eyeDir = normalize(eyePosition - position.xyz);
  153. float3 halfAngle = normalize(eyeDir + lightDir);
  154. oTSHalfAngle = mul(rotation, halfAngle);
  155. }
  156. /* Fragment program which supports specular component */
  157. void specular_fp( float2 uv : TEXCOORD0,
  158.   float3 TSlightDir : TEXCOORD1,
  159.   float3 TShalfAngle: TEXCOORD2,
  160.   out float4 colour : COLOR,
  161.   uniform float4 lightDiffuse,
  162.   uniform float4 lightSpecular,
  163.   uniform sampler2D   normalMap : register(s0),
  164.   uniform samplerCUBE normalCubeMap : register(s1), 
  165.   uniform samplerCUBE normalCubeMap2 : register(s2)) // we need this second binding to be compatible with ps_1_1, ps_2_0 could reuse the other
  166. {
  167. // retrieve normalised light vector, expand from range-compressed
  168. float3 lightVec = expand(texCUBE(normalCubeMap, TSlightDir).xyz);
  169. // retrieve half angle and normalise through cube map
  170. float3 halfAngle = expand(texCUBE(normalCubeMap2, TShalfAngle).xyz);
  171. // get bump map vector, again expand from range-compressed
  172. float3 bumpVec = expand(tex2D(normalMap, uv).xyz);
  173. // Pre-raise the specular exponent to the eight power
  174. // Note we have no 'pow' function in basic fragment programs, if we were willing to accept compatibility
  175. // with ps_2_0 / arbfp1 and above, we could have a variable shininess parameter
  176. // This is equivalent to 
  177. float specFactor = dot(bumpVec, halfAngle);
  178. for (int i = 0; i < 3; ++i)
  179. specFactor *= specFactor;
  180. // Calculate dot product for diffuse
  181. colour = (lightDiffuse * saturate(dot(bumpVec, lightVec))) + 
  182. (lightSpecular * specFactor);
  183. }
  184.