Sign in to follow this  

need per pixel attenuation shader help[Solved]

This topic is 3595 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

I'm trying to get per-pixel attenuation to work and I've only been somewhat successful. I could use some help getting it working completely Here's my vert shader(mostly done by the author of OGRE)
void atten_vp(float4 position : POSITION,
			 float3 normal		: NORMAL,
			 float2 uv			: TEXCOORD0,
			 float3 tangent     : TANGENT0,
			 // outputs
			 out float4 oPosition : POSITION,
			 out float2 oUv			 : TEXCOORD0,
			 out float3 oTSLightDir	 : TEXCOORD1,
			 out float4 olVec : TEXCOORD2,
			 // parameters
			 uniform float4 lightPosition,
			 uniform float4x4 worldViewProj,
			 uniform float4x4 world,
			 uniform float4x4 worldIT
			 )
{
	// calculate output position

	oPosition = mul(worldViewProj, position);

	float4 worldloc = mul(world, position);

	olVec = lightPosition - worldloc;

	// pass the main uvs straight through unchanged
	oUv = uv;

	// calculate tangent space light vector
	// Get object space light direction
	// Non-normalised since we'll do that in the fragment program anyway
	float3 lightDir = lightPosition.xyz -  (position * lightPosition.w);

	// Calculate the binormal (NB we assume both normal and tangent are
	// already normalised)
	// NB looks like nvidia cross params are BACKWARDS to what you'd expect
	// this equates to NxT, not TxN
	float3 binormal = cross(tangent, normal);
	
	// Form a rotation matrix out of the vectors
	float3x3 rotation = float3x3(tangent, binormal, normal);
	
	// Transform the light vector according to this matrix
	oTSLightDir = mul(rotation, lightDir);
	
	
}


Notice how the out light vec is light position - the vertex world position... This code doesn't work right. When I make olVec = lightPosition - oPosition the per pixel attenuation only works when the camera is moved within the light radius of a surface. Here's my pixel shader:
void atten_fp( 
		 	  float2 uv			: TEXCOORD0,
			  float3 TSlightDir : TEXCOORD1,
			  float4 lpos : TEXCOORD2,

			  out float4 colour	: COLOR,

			  uniform float4 lightDiffuse,
			  uniform float4 lightAttenuation,
			  uniform sampler2D   normalMap : register(s0),
			  uniform samplerCUBE normalCubeMap : register(s1) )
{

	float dist = length(lpos);
	float att = saturate( (1.0f - saturate(  ( dist * dist ) / ( lightAttenuation.x * lightAttenuation.x ) ) ) );

	float att2 = att * att;	

	// retrieve normalised light vector, expand from range-compressed
	float3 lightVec = expand(texCUBE(normalCubeMap, TSlightDir).xyz);

	// get bump map vector, again expand from range-compressed
	float3 bumpVec = expand(tex2D(normalMap, uv).xyz);

	// Calculate dot product
	colour = att2 * (lightDiffuse * dot(bumpVec, lightVec));
}



I'm not really good at graphics programming but I think my lights should cutoff when I make olVec = lightPosition - worldloc but it looks like I'm wrong. This shader is being used in the ogre engine... Anyone know what I'm doing wrong? [Edited by - etsuja on February 9, 2008 11:37:14 PM]

Share this post


Link to post
Share on other sites
For some reaons I'm not getting the same results as I was last night when I set olVec = lightPosition - oPosition, but it wasn't working right anyway so I guess it doesn't matter that much.

Share this post


Link to post
Share on other sites
I found a solution, I was sending a mistransformed world position to my pixel shader.

Here's my final point light attenuation shaders

VS:

void atten_vp(float4 position : POSITION,
float4 normal : NORMAL,
float2 uv : TEXCOORD0,
float3 tangent : TANGENT0,
// outputs
out float4 oPosition : POSITION,
out float2 oUv : TEXCOORD0,
out float3 oTSLightDir : TEXCOORD1,
out float4 oworldPos : TEXCOORD2,
// parameters
uniform float4 lightPosition,
uniform float4x4 worldViewProj,
uniform float4x4 world,
uniform float4x4 worldIT
)
{
// calculate output position

oPosition = mul(worldViewProj, position);

oworldPos = position;

oworldPos.w = 1.0f;

// pass the main uvs straight through unchanged
oUv = uv;

// calculate tangent space light vector
// Get object space light direction
// Non-normalised since we'll do that in the fragment program anyway
float3 lightDir = lightPosition.xyz - (position * lightPosition.w);

// Calculate the binormal (NB we assume both normal and tangent are
// already normalised)
// NB looks like nvidia cross params are BACKWARDS to what you'd expect
// this equates to NxT, not TxN
float3 binormal = cross(tangent, normal);

// Form a rotation matrix out of the vectors
float3x3 rotation = float3x3(tangent, binormal, normal);

// Transform the light vector according to this matrix
oTSLightDir = mul(rotation, lightDir);


}




PS:

void atten_fp(
float2 uv : TEXCOORD0,
float3 TSlightDir : TEXCOORD1,
float3 wpos : TEXCOORD2,

out float4 colour : COLOR0,

uniform float4 lightDiffuse,
uniform float4 lightAttenuation,
uniform float4 lightPos,
uniform sampler2D normalMap : register(s0),
uniform samplerCUBE normalCubeMap : register(s1) )
{
float dist = distance(lightPos, wpos );
float att = saturate( 1.0f - saturate( ( dist * dist ) / ( lightAttenuation.x * lightAttenuation.x ) ) );

float att2 = att * att;

// retrieve normalised light vector, expand from range-compressed
float3 lightVec = expand(texCUBE(normalCubeMap, TSlightDir).xyz);

// get bump map vector, again expand from range-compressed
float3 bumpVec = expand(tex2D(normalMap, uv).xyz);

// Calculate dot product
colour = lightDiffuse * att2 * dot(lightVec, bumpVec);


}


Share this post


Link to post
Share on other sites

This topic is 3595 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this