Jump to content
  • Advertisement
Sign in to follow this  
silvermace

Something's Up with my shader...

This topic is 4838 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

im baffled at why this simple shader isnt working as expected everything is pretty-much as you see it, matricies are set using CG's built in matrix-state-setters, there are no transformations at all, just the camera (gluLookAt) and un-transformed terrain, ModelView matrix is identity when code enters.. download the demo, as its really hard to explain whats happening.
struct appin 
{
	float4 position : POSITION;
	float3 normal   : NORMAL;
	float4 tangent  : TEXCOORD0;
	float2 texCoord : TEXCOORD1;
};

struct vp_out 
{
	float4 pos		        : POSITION;
	float2 tex		        : TEXCOORD0;
	float3 lightDirection   : TEXCOORD1;
	float3 normal		    : TEXCOORD2;
};

// vertex program entrypoint
vp_out vp_main( appin ain, 
		uniform float3 lightPosition,
		uniform float3 eyePosition,

		uniform float4x4 ModelViewProj,
		uniform float4x4 ModelView,
		uniform float4x4 ModelViewI,
		uniform float4x4 ModelViewIT,
		uniform float4x4 Projection ) 
{
	vp_out vout = (vp_out)0;

	// Compute the object-space light vector
	float3 lightDir = lightPosition - mul( ModelViewI, ain.position ).xyz;

	vout.lightDirection = normalize( lightDir );
	vout.normal = normalize( mul( (float3x3)ModelViewIT, normalize(ain.normal) ) );

	vout.tex = ain.texCoord;
	vout.pos = mul( ModelViewProj, ain.position );

	return vout;
}

// present the final layer of output
float4 fp_main( vp_out IN, uniform sampler2D decalMap  : TEXUNIT0 ) : COLOR
{
	// sample textures
	float4 decalTex = tex2D(decalMap, IN.tex).rgba;

	float3 L = normalize(IN.lightDirection);
	float3 N = normalize(IN.normal);

	return max( dot(N, L), 0.0 ) * decalTex;
}

Share this post


Link to post
Share on other sites
Advertisement
Your ModelView matrix can't be identity or your camera wouldn't move around.

It looks to me like your projection matrix is possibly whack, but without code I can't tell why.

Your lighting code is also wrong. You're transforming the input position by the inverse ModelView matrix, which assumes the input position is in view space to begin with. It's probably not, it's probably just in world space and you don't need the matrix multiplication at all. If you want to handle things which can start in model space, then you'll need another matrix that's just the model matrix and you will want to multiply the position by that to move the vertex into world space. Similar things apply to the normal.

The fragment shader part looks correct though :)

EDIT:

If it helps, here's how I'd write it (roughly, there might be some casts/tweaks needed)


struct appin
{
float4 position : POSITION;
float3 normal : NORMAL;
float4 tangent : TEXCOORD0;
float2 texCoord : TEXCOORD1;
};

struct vp_out
{
float4 pos : POSITION;
float2 tex : TEXCOORD0;
float3 lightDirection : TEXCOORD1;
float3 normal : TEXCOORD2;
};

// vertex program entrypoint
vp_out vp_main( appin ain,
uniform float3 lightPosition,
uniform float3 eyePosition,

uniform float4x4 ModelViewProj,
uniform float4x4 ModelView,
uniform float4x4 ModelViewI,
uniform float4x4 ModelViewIT,
uniform float4x4 ModelI,
uniform float4x4 Projection )
{
vp_out vout = (vp_out)0;

// Compute the light vector in object space
// assumes: lightPosition is in worldSpace, ain.position is in object space
// so here we move the lightPosition into object space before doing the
// subtraction
float3 lightDir = mul(ModelI, lightPosition).xyz - ain.position.xyz;

vout.lightDirection = lightDir; // I wouldn't bother with the normalize call - you normalize it in the fragment shader anyway

// you don't need to transform your input normal if you do your lighting in object space
vout.normal = ain.normal;

vout.tex = ain.texCoord;
vout.pos = mul( ModelViewProj, ain.position );

return vout;
}

// present the final layer of output
float4 fp_main( vp_out IN, uniform sampler2D decalMap : TEXUNIT0 ) : COLOR
{
// sample textures
float4 decalTex = tex2D(decalMap, IN.tex).rgba;

float3 L = normalize(IN.lightDirection);
float3 N = normalize(IN.normal);

return max( dot(N, L), 0.0 ) * decalTex;
}



-Mezz

Share this post


Link to post
Share on other sites
Quote:
Original post by Mezz
Your ModelView matrix can't be identity or your camera wouldn't move around.

It looks to me like your projection matrix is possibly whack, but without code I can't tell why.

Your lighting code is also wrong. You're transforming the input position by the inverse ModelView matrix, which assumes the input position is in view space to begin with. It's probably not, it's probably just in world space and you don't need the matrix multiplication at all. If you want to handle things which can start in model space, then you'll need another matrix that's just the model matrix and you will want to multiply the position by that to move the vertex into world space. Similar things apply to the normal.

The fragment shader part looks correct though :)

-Mezz
Thanks for your input, I appreciate it! [smile]

Basically, I didn't notice that ModelViewI, thats how despirate I've gotten in trying to fix this error, it was originally lightPosition - ModelView * ain.position, but my debugging has degraded to "trial and error"!

as you have probably deduced, changing that makes next-to-no difference.
is that the only error you could find in the vertex-shader?

if you can confirm the shader is correct, I can take that out of the equation [cool]

Thanks again,
Cheers
-Danu

FYI, I use this quick-ref card for transformations between spaces

Share this post


Link to post
Share on other sites
OK I think you should break it back to the simplest it can be.

Just transform the position to clip space.
Just pass through the texture coordinates.

Do no lighting whatsoever.

I did this and it made things look a little less screwy, I could use the WSAD keys to move around and things looked relatively 'normal'. the weirdness came when I used the mouse to mouselook and as things got nearer the edge of the screen they became stretched, I think that's your main problem, and I think it's not in your shader code but in your app somewhere which is giving the shader a slightly bogus matrix.

-Mezz

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!