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

游戏引擎

开发平台:

Visual C++

  1. /* Bump mapping with Parallax offset vertex program 
  2.    In this program, we want to calculate the tangent space light end eye vectors 
  3.    which will get passed to the fragment program to produce the per-pixel bump map 
  4.    with parallax offset effect. 
  5. */ 
  6. /* Vertex program that moves light and eye vectors into texture tangent space at vertex */ 
  7. void main_vp(float4 position   : POSITION, 
  8.               float3 normal      : NORMAL, 
  9.               float2 uv         : TEXCOORD0, 
  10.               float3 tangent     : TEXCOORD1, 
  11.               // outputs 
  12.               out float4 oPosition    : POSITION, 
  13.               out float2 oUv          : TEXCOORD0, 
  14.               out float3 oLightDir    : TEXCOORD1, // tangent space 
  15.              out float3 oEyeDir       : TEXCOORD2, // tangent space 
  16.              out float3 oHalfAngle    : TEXCOORD3, // 
  17.               // parameters 
  18.               uniform float4 lightPosition, // object space 
  19.               uniform float3 eyePosition,   // object space 
  20.               uniform float4x4 worldViewProj) 
  21. {  
  22.    // calculate output position 
  23.    oPosition = mul(worldViewProj, position); 
  24.    // pass the main uvs straight through unchanged 
  25.    oUv = uv; 
  26.    // calculate tangent space light vector 
  27.    // Get object space light direction 
  28.    float3 lightDir = normalize(lightPosition.xyz -  (position * lightPosition.w));
  29.    float3 eyeDir = eyePosition - position.xyz; 
  30.     
  31.    // Calculate the binormal (NB we assume both normal and tangent are 
  32.    // already normalised) 
  33.    // NB looks like nvidia cross params are BACKWARDS to what you'd expect 
  34.    // this equates to NxT, not TxN 
  35.    float3 binormal = cross(tangent, normal); 
  36.     
  37.    // Form a rotation matrix out of the vectors 
  38.    float3x3 rotation = float3x3(tangent, binormal, normal); 
  39.     
  40.    // Transform the light vector according to this matrix 
  41.    lightDir = normalize(mul(rotation, lightDir)); 
  42.    eyeDir = normalize(mul(rotation, eyeDir)); 
  43.    oLightDir = lightDir; 
  44.    oEyeDir = eyeDir; 
  45.    oHalfAngle = normalize(eyeDir + lightDir); 
  46. }
  47. // General functions
  48. // Expand a range-compressed vector
  49. float3 expand(float3 v)
  50. {
  51. return (v - 0.5) * 2;
  52. }
  53. void main_fp(float2 uv : TEXCOORD0,
  54. float3 lightDir : TEXCOORD1,
  55. float3 eyeDir : TEXCOORD2,
  56. float3 halfAngle : TEXCOORD3,
  57. uniform float3 lightDiffuse,
  58. uniform float3 lightSpecular,
  59. uniform float4 scaleBias,
  60. uniform sampler2D normalHeightMap,
  61. uniform sampler2D diffuseMap,
  62. out float4 oColor : COLOR)
  63. {
  64. // get the height using the tex coords
  65. float height = tex2D(normalHeightMap, uv).a;
  66. // scale and bias factors
  67. float scale = scaleBias.x;
  68. float bias = scaleBias.y;
  69. // calculate displacement
  70. float displacement = (height * scale) + bias;
  71. float3 uv2 = float3(uv, 1);
  72. // calculate the new tex coord to use for normal and diffuse
  73. float2 newTexCoord = ((eyeDir * displacement) + uv2).xy;
  74. // get the new normal and diffuse values
  75. float3 normal = expand(tex2D(normalHeightMap, newTexCoord).xyz);
  76. float3 diffuse = tex2D(diffuseMap, newTexCoord).xyz;
  77. float3 specular = pow(saturate(dot(normal, halfAngle)), 32) * lightSpecular;
  78. float3 col = diffuse * saturate(dot(normal, lightDir)) * lightDiffuse + specular;
  79. oColor = float4(col, 1);
  80. }