Projective texture coordinates in water rendering

Started by
-1 comments, last by awingsoft 16 years, 2 months ago
When programing in water rendering, I've met a perplexing problem about projected texture coordinate. I render scene to a texture, then project to a surface to simulate water. So need generating texture coordinates for the surface in real time, I use vertex shader to do this (and no use pixel shader in whole water rendering). First, My vs codes is:

vs.1.0
m4x4 r0, v0, c4 //v0   - Vertex Position
                //c4-7 - Composite World-View-Projection Matrix
mov oPos,r0

//c0    - { 0.0,  0.5, 1.0, 2.0}
add r0.x, r0.w, r0.x // r0.x = (pos.w + pos.x) * 0.5
mul r0.x, r0.x, c0.y

add r0.y, r0.w, -r0.y // r0.y = (pos.w - pos.y ) * 0.5
mul r0.y, r0.y, c0.y

rcp r2.w, r0.w        // r0.xyz/=pos.w
mul r0.xyz, r0, r2.w

mov oT1, r0
mov oT3, r0



and texture stage states is:

  // stage1
  ColorOp[1] = SelectArg1;
  ColorArg1[1] = Texture;
  ...
  // stage3
  ColorOp[3] = BlendDiffuseAlpha;
  ColorArg1[3] = Texture;
  ColorArg2[3] = Current;



These codes gets a halfway success: when camera is faraway to water surface, everything looks well; but if camera close to water, the projected texture looks distorted and chapped. see below screenshot: After many attempts, I've found the solution finally: remove the w-division from vertex shader, and do the division by setting TextureStageState - D3DTSS_TEXTURETRANSFORMFLAGS. So the modified vs codes is:

vs.1.0
m4x4 r0, v0, c4 //v0   - Vertex Position
                //c4-7 - Composite World-View-Projection Matrix
mov oPos,r0

//c0    - { 0.0,  0.5, 1.0, 2.0}
add r0.x, r0.w, r0.x // r0.x = (pos.w + pos.x) * 0.5
mul r0.x, r0.x, c0.y

add r0.y, r0.w, -r0.y // r0.y = (pos.w - pos.y ) * 0.5
mul r0.y, r0.y, c0.y

mov oT1, r0
mov oT3, r0



and modified texture stage states is:

  // stage1
  ColorOp[1] = SelectArg1;
  ColorArg1[1] = Texture;
  TextureTransformFlags[1] = Count3|Projected;
  ...
  // stage3
  ColorOp[3] = BlendDiffuseAlpha;
  ColorArg1[3] = Texture;
  ColorArg2[3] = Current;
  TextureTransformFlags[3] = Count3|Projected;



This time the result is satisfying, the water looks well from anywhere: So I have a question: why do the w-division in vertex shader cause the distortion? (Is it perspective-correction correlative? Is there a method to disable perspective-correction in D3d 8.1?)

This topic is closed to new replies.

Advertisement