Help to get worldViewOnly in Vertex Shader
by elvince · in Torque 3D Professional · 01/28/2010 (3:57 pm) · 8 replies
Hi,
I would like to you the normal of each vertex in a vertex shader to create a displacement map.
I moving from a Shader working in XNA to Torque
Original:
For the moment, I'm trying this:
But I don't know how to get the worldViewOnly matrix.
I know that this matrix is declared in Torque3D but I don't know how I can get it in my shader and use it.
Do I need to use VC_EYE_POS float3?
Thanks!
I would like to you the normal of each vertex in a vertex shader to create a displacement map.
I moving from a Shader working in XNA to Torque
Original:
PositionDisplacement PullIn_VertexShader(PositionNormal input, uniform float4x4 modelview : register(VC_WORLD_PROJ))
{
PositionDisplacement output;
output.Position = mul(modelview, input.Position);
float3 normalWV = mul(input.Normal, WorldView);
normalWV.y = -normalWV.y;
float amount = dot(normalWV, float3(0,0,1)) * DistortionScale;
output.Displacement = float2(.5,.5) + float2(amount * normalWV.xy);
return output;
}For the moment, I'm trying this:
VertexIn_PT main( VertexIn_PNT IN, uniform float4x4 modelview : register(VC_WORLD_PROJ),uniform float4x4 worldViewOnly :register(?????) )
{
VertexIn_PT OUT;
OUT.pos = mul(modelview,IN.pos);
float3 normalWV = mul(IN.normal, worldViewOnly);
normalWV.y = -normalWV.y;
float amount = dot(normalWV, float3(0,0,1)) * DistortionScale;
OUT.uv0 = float2(.5,.5) + float2(amount * normalWV.xy);
return OUT;
}But I don't know how to get the worldViewOnly matrix.
I know that this matrix is declared in Torque3D but I don't know how I can get it in my shader and use it.
Do I need to use VC_EYE_POS float3?
Thanks!
About the author
Recent Threads
#2
In fact, the distorsion map I got is really a mess. I check again the the sample shader I'm trying to convert and everything is ok with worldview.
DistortionScale = 0.0003f;
So for uv0 I should have result near 0.5,0.5. Is there a way to debug such thing? any tool like render monkey or the one of nvidia may help me?
I fixed an issue in X axis as I need to got the opposite:
normalWV.x = -normalWV.x;
Here are sample:
Left image: Map from shader with distorsion = 1,
Middle image: Stealth effect applied
Right:Stealth effect with a texture distorsion map instead of map from shader.

I hope some one will catch the issue.
With distorsion =0.0003 like in the original shader, I have a full transparent model. That mean my Vertex shader is sending 0.5 0.5 to uv0 everyone time.
Map Explanation:
A distortion map is a 2D vector field stored in a texture. In this implementation, the red channel represents displacement along the x-axis, and the green channel represents displacement along the y-axis. HLSL represents texture channels as floating-point values in the range [0, 1], but displacement can take place in either the positive or negative direction along an axis. Therefore, a color channel value of 0.5 is understood to mean a vector component of 0. With this in mind, a pixel color value of 0.5 red and 0.5 green (a yellow-brown color) will result in no displacement.
02/01/2010 (3:38 am)
Thanks for the tips. Sadly, I can get the result I expect.In fact, the distorsion map I got is really a mess. I check again the the sample shader I'm trying to convert and everything is ok with worldview.
DistortionScale = 0.0003f;
So for uv0 I should have result near 0.5,0.5. Is there a way to debug such thing? any tool like render monkey or the one of nvidia may help me?
I fixed an issue in X axis as I need to got the opposite:
normalWV.x = -normalWV.x;
Here are sample:
Left image: Map from shader with distorsion = 1,
Middle image: Stealth effect applied
Right:Stealth effect with a texture distorsion map instead of map from shader.

I hope some one will catch the issue.
With distorsion =0.0003 like in the original shader, I have a full transparent model. That mean my Vertex shader is sending 0.5 0.5 to uv0 everyone time.
Map Explanation:
A distortion map is a 2D vector field stored in a texture. In this implementation, the red channel represents displacement along the x-axis, and the green channel represents displacement along the y-axis. HLSL represents texture channels as floating-point values in the range [0, 1], but displacement can take place in either the positive or negative direction along an axis. Therefore, a color channel value of 0.5 is understood to mean a vector component of 0. With this in mind, a pixel color value of 0.5 red and 0.5 green (a yellow-brown color) will result in no displacement.
#3
In fact, what make the model look bads in stealth mode is that the arms are seen trought the back, that the leg are seen under the coat etc... You have no issue if you are using a diffuse map as it will covered behind pixel:(
How can I manage this?
I have the same type of issue, if I use a transparency material.
Thanks,
02/02/2010 (3:26 pm)
Ok I got what's wrong but I don't know yet how to solve it.In fact, what make the model look bads in stealth mode is that the arms are seen trought the back, that the leg are seen under the coat etc... You have no issue if you are using a diffuse map as it will covered behind pixel:(
How can I manage this?
I have the same type of issue, if I use a transparency material.
Thanks,
#4
The important thing is to understand,that you render to a screen aligned quad.
There are four vertexes:
top-left (-1,1)
top-right (1,1)
bottom-left (-1,-1)
bottom-right (1,-1)
texcoords are:
top-left (0,0)
top-right (1,0)
bottom-left (0,1)
bottom-right (1,1)
Texel coordinates represent the pixel centers,vertex coordinates are the edges of the quad,so there is a half-pixel offset.
The post effect system applies a half-pixel correction,stored in rtparams.xy -
the value is (1/(2*screen_width),1/(2*screen_height))
rtparams.zw represent the RT scale - in your case it is 1.
So what you need to check is your uv0 texcoords.
02/02/2010 (4:24 pm)
It looks like a texcoord trouble.The important thing is to understand,that you render to a screen aligned quad.
There are four vertexes:
top-left (-1,1)
top-right (1,1)
bottom-left (-1,-1)
bottom-right (1,-1)
texcoords are:
top-left (0,0)
top-right (1,0)
bottom-left (0,1)
bottom-right (1,1)
Texel coordinates represent the pixel centers,vertex coordinates are the edges of the quad,so there is a half-pixel offset.
The post effect system applies a half-pixel correction,stored in rtparams.xy -
the value is (1/(2*screen_width),1/(2*screen_height))
rtparams.zw represent the RT scale - in your case it is 1.
So what you need to check is your uv0 texcoords.
#5
Thanks for the clarification of post effects.
I think I managed it correctly:
1/ for vertex shader postFxV, wich will apply the rtparams you are mentionning if my undertanding is ok.
2/ for pixel, it manage to change the displacement map from [0,1] to [-.5, .5] so it can be add to IN.uv0.xy
During PostFx, I looked at my displacement map and it seems that the root cause of it. When I don't apply the postfx, the map seems fine, but if I look in the buffer before processing, it seems that the model is treated as transparent. I will look in to that.
For information the pixel shader:
02/04/2010 (4:06 am)
Hi,Thanks for the clarification of post effects.
I think I managed it correctly:
1/ for vertex shader postFxV, wich will apply the rtparams you are mentionning if my undertanding is ok.
2/ for pixel, it manage to change the displacement map from [0,1] to [-.5, .5] so it can be add to IN.uv0.xy
During PostFx, I looked at my displacement map and it seems that the root cause of it. When I don't apply the postfx, the map seems fine, but if I look in the buffer before processing, it seems that the model is treated as transparent. I will look in to that.
For information the pixel shader:#include "postFx.hlsl"
#include "shadergen:/autogenConditioners.h"
const float ZeroOffset = 0.5f / 255.0f;
float4 main( PFXVertToPix IN,
uniform sampler2D selectionBuffer :register(S0),
uniform sampler2D backBuffer : register(S1),
uniform float2 targetSize : register(C0) ) : COLOR0
{
float4 DistorsionMap=tex2D( selectionBuffer,IN.uv0);
// Look up the displacement
float2 displacement = DistorsionMap.rg;
float4 finalColor = 0;
// We need to constrain the area potentially subjected to the gaussian blur to the
// distorted parts of the scene texture. Therefore, we can sample for the color
// we used to clear the distortion map (black). We used 0 to avoid any potential
// rounding errors.
if ((displacement.x == 0) && (displacement.y == 0))
{
finalColor = tex2D(backBuffer, IN.uv0);
}
else
{
// Convert from [0,1] to [-.5, .5)
// .5 is excluded by adjustment for zero
displacement -= .5 + ZeroOffset;
// Look up the displaced color, without multisampling
finalColor = tex2D(backBuffer, IN.uv0.xy + displacement);
}
return finalColor;
}
#6
I tried to look at it but I have no clue why I have this effect.
Thanks,
02/07/2010 (2:57 pm)
Ivan, can you drive where to look to analyse this effect? my rendermngr act as if my mesh had a translucent mat and it's not the case.I tried to look at it but I have no clue why I have this effect.
Thanks,
#7
It sounds like the application passes specific texture coordinates for a distortion.
I think you should prepare your texcoords to sample a fullscreen texture.
You'll have to simulate a perspective division.
For example if you have transformed IN.pos.xy in your vertex shader,then texture coordinates must be done this way:
float U = (IN.pos.x/IN.pos.w + 1)/2 + rtparams.x;
float V = (IN.pos.y/IN.pos.w - 1)/2 + rtparams.y;
float2 FStexc = float2(U,V);
Then if:
float2 Ntexc = tex2D(distortion,IN.uv0);
float4 color = tex2D(scenemap , FStexc + Ntexc);
And you return the color.
Of course this is a rough idea,I am not familiar with the real approach,so this may not work out of the box.
02/07/2010 (4:36 pm)
There is no easy solution to this.It sounds like the application passes specific texture coordinates for a distortion.
I think you should prepare your texcoords to sample a fullscreen texture.
You'll have to simulate a perspective division.
For example if you have transformed IN.pos.xy in your vertex shader,then texture coordinates must be done this way:
float U = (IN.pos.x/IN.pos.w + 1)/2 + rtparams.x;
float V = (IN.pos.y/IN.pos.w - 1)/2 + rtparams.y;
float2 FStexc = float2(U,V);
Then if:
float2 Ntexc = tex2D(distortion,IN.uv0);
float4 color = tex2D(scenemap , FStexc + Ntexc);
And you return the color.
Of course this is a rough idea,I am not familiar with the real approach,so this may not work out of the box.
#8
Inside the UV are managed this way: OUT.uv0 = viewportCoordToRenderTarget( IN.uv, rtParams0 );
As seen in this thread www.torquepowered.com/community/forums/viewthread/110439, the issue is linked to prepass mngr. I need to pass trought it to avoid the "translucent" effect.
I need now to find a way to get the background without my mesh and pass in prepass mangr ... which seems not compatible :(
02/08/2010 (3:33 am)
For the vertex shader, I'm using stock postFxV.hlslInside the UV are managed this way: OUT.uv0 = viewportCoordToRenderTarget( IN.uv, rtParams0 );
As seen in this thread www.torquepowered.com/community/forums/viewthread/110439, the issue is linked to prepass mngr. I need to pass trought it to avoid the "translucent" effect.
I need now to find a way to get the background without my mesh and pass in prepass mangr ... which seems not compatible :(
Torque Owner Ivan Mandzhukov
Liman3D
worldViewOnly is object to view, I think you need object to world (objTrans)..
uniform float4x4 modelview; uniform float4x4 worldViewOnly; VertexIn_PT main( VertexIn_PNT IN) { VertexIn_PT OUT; OUT.pos = mul(modelview,IN.pos); float3 normalWV = mul(worldViewOnly,IN.normal); normalWV.y = -normalWV.y; float amount = dot(normalWV, float3(0,0,1)) * DistortionScale; OUT.uv0 = float2(0.5,0.5) + float2(amount * normalWV.xy); return OUT; }