/** * VDM -- View-dependent Displacement Mapping * L. Wang, X. Wang, X. Tong, S. Lin, S. Hu, B. Guo, HY. Shum * * HLSL implementation by Nico Galoppo * :: COMP 236 course project, Spring 2004 * :: University of North Carolina, Chapel Hill */ // Vertex shader struct v2f { float4 Position : POSITION; // clip space float2 TexCoord0 : TEXCOORD0; float2 TexCoord1 : TEXCOORD1; float3 L : TEXCOORD2; // tangent space float3 H : TEXCOORD3; float3 V : TEXCOORD4; float2 lightAngle : TEXCOORD5; float2 viewAngle : TEXCOORD6; }; v2f VDMVS(a2v IN, uniform float4x4 WorldViewProj, uniform float4x4 WorldMatrix, uniform float4x4 WorldIMatrix, uniform float4x4 viewIMatrix, uniform float3 LightDir, uniform float bumpScale ) { v2f OUT; // copy texture coordinates OUT.TexCoord0 = IN.TexCoord; OUT.TexCoord1 = IN.TexCoord; // transform position to clip space OUT.Position = mul(IN.Position, WorldViewProj); // compute the 3x3 tranform from object space to tangent space float3x3 objToTangentSpace; objToTangentSpace[0] = IN.Tangent * bumpScale; objToTangentSpace[1] = IN.Binormal * bumpScale; objToTangentSpace[2] = IN.Normal; float4 vertexPos = mul(IN.Position, WorldMatrix); // world space position // light vector float3 lightVec = -LightDir; lightVec = mul(lightVec, (float3x3) WorldIMatrix); // transform back to object space OUT.L = mul(objToTangentSpace, lightVec); // transform from object to tangent space // eye vector float3 eyeVec = viewIMatrix[3].xyz - vertexPos.xyz; // world space eye vector eyeVec = mul(eyeVec, (float3x3) WorldIMatrix); // transform back to object space eyeVec = normalize(eyeVec); float3 tangentEyeVec = mul(objToTangentSpace, eyeVec); tangentEyeVec = normalize(tangentEyeVec); // half-angle vector float3 H = normalize(lightVec + eyeVec); OUT.H = mul(objToTangentSpace, H); // transform to tangent space // vdm angles OUT.lightAngle = toSpherical(OUT.L); OUT.viewAngle = toSpherical(tangentEyeVec); OUT.V = tangentEyeVec; return OUT; }