2
\$\begingroup\$

I'm trying to get world position from my vertex shader to my pixel shader so that I can disable the shader once a preset X coordinate has been passed (no shading once I'm over X).

Getting the screen position is not a problem so far but despite my best efforts to look after it and implement examples the calculations just don't return the preferred world positions I'm looking for.

Update: So got it to somewhat work, after compiling the shaders the output changes to such:Could anyone explain this?

Could anyone explain why this happens?

I should mention that I'm really new to HLSL, been only scripting so far.
Edit:Added matrices.

world = Matrix.Identity;
view = Matrix.CreateScale(new Vector3(1, 0.75f, 0)) * Matrix.CreateTranslation(-playerpos.X, -playerpos.Y, 1); 
projection = Matrix.CreateOrthographicOffCenter(0, view.Width, view.Height, 0, 0, 1);
Matrix halfPixelOffset = Matrix.CreateTranslation(-0.5f, -0.5f, 0);
projection = halfPixelOffset * projection; <\code>

texture lightMask; sampler mainSampler : register(s0); sampler lightSampler = sampler_state{Texture = lightMask;}; float4x4 World; float4x4 View; float4x4 Projection; struct vs2ps { float4 Pos : POSITION0; float4 TexCd : TEXCOORD0; float3 PosW : TEXCOORD1; }; vs2ps VS(float4 Pos : POSITION0,float4 TexCd : TEXCOORD0) { vs2ps Out; Out.Pos = mul(Pos, World*View*Projection); Out.TexCd = TexCd; Out.PosW = mul(Pos, World); return Out; } float4 PixelShaderFunction(vs2ps input) : COLOR0 { float2 texCoord = input.TexCd; float4 screenPosition = (input.PosW,1.0f); float4 lightColor = tex2D(lightSampler, texCoord); float4 mainColor = tex2D(mainSampler, texCoord); if(screenPosition.x < 3500) { return (mainColor * lightColor); } else return mainColor; }
\$\endgroup\$
  • 1
    \$\begingroup\$ You should do this using a scissor test instead. \$\endgroup\$ – Maximus Minimus Dec 7 '14 at 15:25
  • \$\begingroup\$ Could you elaborate on that please? I'm not really familiar with the method. \$\endgroup\$ – Razeal Dec 7 '14 at 15:38
1
\$\begingroup\$

World position is vertex position multiplied by world matrix, not view matrix. So it should be like this in the vertex shader:

output.WorldPos = mul(input.Pos,World);

Unless you want View position to work with. I haven't checked the code for bugs if you want to use that.

\$\endgroup\$
  • \$\begingroup\$ Actually forgot to revert the edit on that. The point is that I've already tried with the world matrix, oddly it only returns 0 as value. \$\endgroup\$ – Razeal Dec 3 '14 at 21:11
  • \$\begingroup\$ What value is the vertex position (one of them) and what is the World matrix before and in the vertex shader? Could you add this to your question? The shader seems right to me so far. :) \$\endgroup\$ – János Turánszki Dec 3 '14 at 21:19
  • \$\begingroup\$ Do you mean how they're calculated before they are added as parameters? As for the results in the shader, unfortunately I can't say exact numbers in the shaders while debugging. But considering you said that the shader code seems okay I'm suspecting that I calculated the world matrix incorrectly. (Altho I'm not sure then why the screenpositions come back correctly) Thanks for the quick answers by the way. :) \$\endgroup\$ – Razeal Dec 3 '14 at 21:53
0
\$\begingroup\$

Okay so, finally achieved my goal.

view = Matrix.CreateScale(new Vector3(1, 0.75f, 1)) * Matrix.CreateTranslation(-playerpos.X, -playerpos.Y, 1);
world = Matrix.Invert(view);
projection = Matrix.CreateOrthographicOffCenter(0, view.Width, view.Height, 0, -1, 1);
Matrix halfPixelOffset = Matrix.CreateTranslation(-0.5f, -0.5f, 0);
projection = halfPixelOffset * projection;



texture lightMask;
sampler mainSampler : register(s0);
sampler lightSampler = sampler_state{Texture = lightMask;};
float4x4 World;
float4x4 View;
float4x4 Projection;

struct vs2ps
{
    float4 Pos : POSITION0;
    float4 TexCd : TEXCOORD0;
    float3 PosW : TEXCOORD1;
};

vs2ps VS(float4 Pos : POSITION0,float4 TexCd : TEXCOORD0)
{
    vs2ps Out;
float4 worldPosition = mul(Pos, World);
float4 viewPosition = mul(worldPosition, View);
    Out.Pos = mul(viewPosition, Projection);
    Out.TexCd = TexCd;
    Out.PosW = mul(Pos,World);
    return Out;
    }

float4 PixelShaderFunction(vs2ps input) : COLOR0
{   float2 texCoord = input.TexCd;
    float2 screenPosition = input.PosW;
    float4 lightColor = tex2D(lightSampler, texCoord);
    float4 mainColor = tex2D(mainSampler, texCoord);
    if(screenPosition.x < 3500)
    {
         return (mainColor * lightColor);
    }
         else return mainColor;
}

Like this the visual output doesn't change and I get the correct coordinates back.

Thanks to those who tried helping tho, they actually set me on the right path.

I'll leave this here for future reference in case anyone's struggling with the same.

\$\endgroup\$
0
\$\begingroup\$

This question already has been answered. See the second link here:

https://stackoverflow.com/questions/12794428/calculating-world-space-coordinates-in-the-pixel-shader

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.