Reputation: 13532
I am rendering a scene to a texture and then drawing a water plane with that texture using projection. Most of the samples I have seen on the web pass in a view/projection matrix to the vertex shader and transform the vertex, then in the pixel shader they do :
projection.x = input.projectionCoords.x / input.projectionCoords.w / 2.0 + 0.5;
projection.y = input.projectionCoords.y / input.projectionCoords.w / 2.0 + 0.5;
I have a shader that does the following and it works too but I don't know where I found this particular code or how it gives the same results with the above code. Here is the code I have
Vertex shader : (world is an identityMatrix, viewProj is my cameras combined viewProjection matrix):
output.position3D = mul(float4(vsin.position,1.0), world).xyz;
output.position = mul(float4(output.position3D,1.0), viewProj);
output.reflectionTexCoord.x = 0.5 * (output.position.w + output.position.x);
output.reflectionTexCoord.y = 0.5 * (output.position.w - output.position.y);
output.reflectionTexCoord.z = output.position.w;
Pixel shader :
float2 projectedTexCoord = (input.reflectionTexCoord.xy / input.reflectionTexCoord.z);
What confuses me is the usage of 0.5 * (output.position.w + output.position.x)
and 0.5 * (output.position.w - output.position.y)
. How does this have the same effect and what does the w component mean here?
Upvotes: 2
Views: 2707
Reputation: 13532
After a while I realized that it ends up being the same thing :
0.5 * (output.position.w + output.position.x);
0.5 * output.position.w + 0.5 * output.position.x
Then in the pixel shader :
(0.5 * output.position.w + 0.5 * output.position.x) / output.position.w
(0.5 * output.position.w)/output.position.w + (0.5 * output.position.x) / output.position.w
The first part becomes 0.5 :
0.5 + 0.5 * ( output.position.x / output.position.w)
This is equal to :
(output.position.x / output.position.w) / 2 + 0.5
I believe moving this calculation to the vertex shader is more efficient so I will just leave it there.
To completely move the calculation out of the shader the matrix can be calculated on the client side :
XMMATRIX v = XMLoadFloat4x4(&view);
XMMATRIX p = XMLoadFloat4x4(&projection);
XMMATRIX t(
0.5f, 0.0f, 0.0f, 0.0f,
0.0f, -0.5f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.0f, 1.0f);
XMMATRIX reflectionTransform = v * p * t;
XMStoreFloat4x4(&_reflectionTransform, XMMatrixTranspose(reflectionTransform));
Then all the vertex shader has to do is :
output.reflectionTexCoord = mul(float4(output.position3D,1.0), reflectionProjectionMatrix);
Upvotes: 2