Jump to content

  • Log In with Google      Sign In   
  • Create Account

World Position


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
3 replies to this topic

#1 Archaik   Members   -  Reputation: 115

Like
0Likes
Like

Posted 01 August 2014 - 09:52 AM

Hi,
I wanted to control a property in pixel shader based on world position passed from vertex shader and got stuck there. For the sake of simplicity, let's say I want to draw stripes on the object, when the view changes they'd stay where they were on the object (as if planar mapped to the object), when the object moves, they'd stay on their original coords, moving across its surface.

Now, here's what I tried:

float4x4 WorldITXf : WorldInverseTranspose;
float4x4 WorldViewProjXf : WorldViewProjection;
float4x4 WorldXf : World;
float4x4 ViewIXf : ViewInverse;

void mainVS(inout float4 Position : POSITION,
            out float3 WorldPos : TEXCOORD0)
{
    Position = mul(Position, WorldViewProjXf);
    WorldPos = mul(Position, WorldXf).xyz;
}

float4 mainPS(in float3 WorldPos : TEXCOORD0) : COLOR {
    float strokeS = frac(WorldPos.x / 5);
    return (strokeS > 0.5) ? float4(1,1,1,1) : float4(0,0,0,0);
}

technique Default {
    pass p0 {
        VertexShader = compile vs_3_0 mainVS();
        PixelShader = compile ps_3_0 mainPS();
    }
}

I'd expect WorldPos to contain absolute world coords so the pixel shader value on the same world x-coord would always be the same. However, when I rotate the view, these values change, leading me to believe I got something wrong in the vertex shader. I'm completely new to shaders, tried searching for a solution both in literature and online, yet it seems this is the right way to do it. I would be very grateful if anyone could point me in the right direction.



Sponsor:

#2 Programmer101   Members   -  Reputation: 198

Like
0Likes
Like

Posted 01 August 2014 - 10:01 AM

It looks like you multiplied Position by the world/view/projection and then again by the world matrix to get WorldPos. If you switch the order of statements in your vertex shader, that should help:

void mainVS(inout float4 Position : POSITION,
            out float3 WorldPos : TEXCOORD0)
{
    WorldPos = mul(Position, WorldXf).xyz;
    Position = mul(Position, WorldViewProjXf);
}


#3 Samith   Members   -  Reputation: 2273

Like
1Likes
Like

Posted 01 August 2014 - 10:21 AM

Ack, making Position an inout parameter of mainVS made your code hard to read!

 

Programmer101's answer above is correct, but I would like to mention a relatively minor quibble. I would rewrite that function to look more like this:

void mainVS(in float4 InputPosition : POSITION,
            out float4 OutputPosition : POSITION,
            out float3 OutputWorldPos : TEXCOORD0)
{
    OutputPosition = mul(InputPosition, WorldViewProjXf);
    OutputWorldPos = mul(InputPosition, WorldXf).xyz;
}
 

Now your function doesn't have any weird ordering dependencies. You can do those two lines in either order and it will still work. Generally I think modifying a function's parameters is bad form, and can make understanding code and finding bugs harder.



#4 Archaik   Members   -  Reputation: 115

Like
0Likes
Like

Posted 02 August 2014 - 11:34 AM

Aargh, stupid me, didn't even notice that I'm changing it, always mentally skipped that line. Thanks a lot, you've saved me a lot of head-banging.






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS