Sign in to follow this  
NickGravelyn

Diffuse Shader With No Ambient Light

Recommended Posts

My diffuse shader is giving me some headaches right now. I have an ambient color set so that if the light is not hitting a polygon, it will still have some color as opposed to just black. Yet here is my result: I can't figure out why I'm not seeing the unlit part of the torus. Any ideas? Here's the shader and then the code for setting some variables in the shader.
float4x4 matWVP : WORLDVIEWPROJECTION;
float4x4 matWorld : WORLD;
float4 lightSource;
float4 ambientColor;
float ambientIntensity;
float4 diffuseColor;
float diffuseIntensity;

struct VS_INPUT 
{
   float4 Position : POSITION;
   float3 Normal : NORMAL;
};

struct VS_OUTPUT 
{
   float4 Position : POSITION;
   float3 Light : TEXCOORD1;
   float3 Normal : TEXCOORD2;
};

struct VS_OUTPUT2
{
   float4 Position : POSITION;
};

VS_OUTPUT DiffuseVertexShader(VS_INPUT Input)
{
   VS_OUTPUT Output;

   Output.Position = mul(Input.Position, matWVP);
   Output.Light = normalize(lightSource - mul(Input.Position, matWorld));
   Output.Normal = normalize(mul(Input.Normal, matWorld));
   
   return(Output);
}

float4 DiffusePixelShader(float3 Light : TEXCOORD1, float3 Normal : TEXCOORD2) : COLOR0
{
	float4 dc = diffuseIntensity * diffuseColor * dot(Normal, Light);
	float4 ac = ambientIntensity * ambientColor;
    return (ac + dc);
}

VS_OUTPUT2 AmbientVertexShader(VS_INPUT Input)
{
   VS_OUTPUT2 Output;

   Output.Position = mul(Input.Position, matWVP);
   
   return(Output);
}

float4 AmbientPixelShader() : COLOR0
{
	return ambientColor;
}

technique DiffuseLighting
{
   pass Pass_0
   {
      VertexShader = compile vs_2_0 DiffuseVertexShader();
      PixelShader = compile ps_2_0 DiffusePixelShader();
   }
}

technique AmbientLighting
{
	pass Pass_0
	{
		VertexShader = compile vs_2_0 AmbientVertexShader();
		PixelShader = compile ps_2_0 AmbientPixelShader();
	}
}

D3DXVECTOR4 ambientColor(0.2f, 0.2f, 0.2f, 1.0f);
float ambientIntensity = 0.2f;
D3DXVECTOR4 diffuseColor(0.6f, 0.6f, 0.6f, 1.0f);
float diffuseIntensity = 1.0f;

Share this post


Link to post
Share on other sites
You should clamp the result of the dot product at the zero border. If you don’t do this it can go negative and “steal” the ambient light.

float4 DiffusePixelShader(float3 Light : TEXCOORD1, float3 Normal : TEXCOORD2) : COLOR0
{
float4 dc = diffuseIntensity * diffuseColor * max(0, dot(Normal, Light));
float4 ac = ambientIntensity * ambientColor;
return (ac + dc);
}


Instead of the max you can use a saturate to clamp to the range [0,1].

Share this post


Link to post
Share on other sites
Also, instead of using a low intensity and a dark grey colour, use white for colour. Also for your light. It's easier to just play with the intensity, instead of factoring it into the light, too.

You currently have a white light with 0.04 intensity, which is very low, and won't be very distinguishable from black.

Share this post


Link to post
Share on other sites

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