Skip to main content
gamedev.net
🔒 Locked

Easy HLSL problem

Started by FoxHunter2 Aug 9, 2007 at 12:43 PM 4 replies 1k views
Original Post
FoxHunter2
FoxHunter2
Hi, I have a strange problem with my HLSL fog shader. Here it is:
float4x4 matWVP : WorldViewProjection;
float3 cameraPos;
float fogNear : FOGNEAR = 0;
float fogFar : FORGAR = 20;
float4 fogColor : FOGCOLOR = float4(1, 1, 1, 1);
sampler Texture;

//------------------------------------
struct VS_INPUT {
    float4 Position	: POSITION;
    float2 TexCoord : TEXCOORD0;
};

struct VS_OUTPUT {
    float4 Position : POSITION;
    float2 TexCoord : TEXCOORD0;
};

//------------------------------------
VS_OUTPUT VS_Simple(VS_INPUT input) 
{
    VS_OUTPUT output;
    output.Position = mul(input.Position, matWVP);
    output.TexCoord = input.TexCoord;
    
    return output;
}

float4 PS_Fog(VS_OUTPUT input) : COLOR
{
	float4 color = tex2D(Texture, input.TexCoord);
	
	float d = length(input.Position - cameraPos);
	float l = saturate((d - fogNear) / (fogFar - fogNear));
	
	return lerp(color, fogColor, l);
}

//-----------------------------------
technique textured
{
    pass p0 
    {		
		VertexShader = compile vs_1_1 VS_Simple();
		PixelShader = compile ps_2_0 PS_Fog();
    }
}
The compiler complains here:
struct VS_OUTPUT {
    float4 Position : POSITION;
"Invalid input semantic: POSITION" Now I understand that you can't directly pass a POSITION to the pixel shader, so if I change this to use a TEXCOORD1 instead, I get this: "Vertex shader must minimally write all four components of POSITION" What's going on here? The new_material.fx in NVidia's FX Composer uses the same semantics and their's compiles fine. regards
Zipster
Zipster
You need to pass the position through POSITION at the very least, and if you actually want to use that position as an input in the pixel shader then you also need to pass it through as a texcoord. It's a bit strange, and one of my major pet peeves of HLSL...
FoxHunter2
FoxHunter2
Quote:
Original post by Zipster
You need to pass the position through POSITION at the very least


I don't understand exactly, can you give me a sample here?
I'm a bit puzzled because the FX Composer examples work the same way.
ViLiO
ViLiO
To further clarify, the vertex shader needs to output a POSITION, but you can't access that POSITION in the pixel shader. So, if you want to get at that POSITION in the pixel shader, you need to output it twice from the vertex shader. Once as the vertex shader output's POSITION and again using a TEXCOORDn and then access the TEXCOORDn in the pixel shader.

Regards,
ViLiO
Richard 'ViLiO' Thomasv.net | Twitter | YouTube
glaeken
glaeken
EDIT: ViLiO beat me to it.

Your vertex output struct should look like this:

struct VS_Out{    float4 posH       : POSITION;    floar4 posW : TEXCOORD0;};


posH is what you have to set.

posW is what you want to set to pass to the pixel shader.

You can't access posH in the pixel shader, so you have to set a second position (posW) to use in the pixel shader.
FoxHunter2
FoxHunter2
That's some weird stuff, thanks guys :)

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.