# [HLSL] How Does Simple Lighting Work?

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

## Recommended Posts

I was going to add this as a reply to another post but they seem to have a different problem. I am having problems getting my head around how the lighting works in HLSL fullstop. When using lights in the program it is simple. Set position, direction and colors and use it .. but in the HLSL fx file it seems there is a lot more involved. I took a look at both the BasicHLSL and DHPOWARE light demos but neither really helped to clear up the whys and hows of the excess of commands. Before I post up the code I am currently using the main question I am asking is .. Is there a SIMPLE HLSL book out there that I haven't stumbled across yet that someone can point out? edit: Just found this book 2 Books At Amazon that might be what I need. Anyone have them and can confirm they are at least partially useful ? Thanks. I've tried google but nothing as simple appears and my Shader books are currently too advanced for me and also doesn't show anything simple in HLSL language for me to try out. Okay, onto my source code for those that want to see it. Here's the fx file I have set up using the BasicHLSL as a guide.
// Matrices
float4x4 world;						// world matrix
float4x4 worldviewprojection;		// everything

// Lighting
float3 LightDir;					// Light's direction in world space
float4 LightDiffuse;				// Light's diffuse color
float4 LightAmbient;				// Light's ambient color

// Materials
float4 MaterialAmbientColor;		// Material's ambient color
float4 MaterialDiffuseColor;		// Material's diffuse color

// Textures
texture t0;
sampler t0Sampler =
sampler_state { Texture = <t0>; MipFilter = LINEAR; MinFilter = LINEAR; MagFilter = LINEAR; };

// Structs
struct VS_OUTPUT
{
float4 Position   : POSITION;   // vertex position
float4 Diffuse    : COLOR0;     // vertex diffuse color
float2 TextureUV  : TEXCOORD0;  // vertex texture coords
};
struct PS_OUTPUT
{
float4 RGBColor : COLOR0;  // Pixel color
};

VS_OUTPUT VSMesh( float4 vPos : POSITION, float3 vNormal : NORMAL, float2 vTexCoord0 : TEXCOORD0)
{
VS_OUTPUT Output;
float3 vNormalWorldSpace;

// Transform the position from object space to homogeneous projection space
Output.Position = mul(vPos, worldviewprojection);
// Transform the normal from object space to world space
vNormalWorldSpace = normalize(mul(vNormal, (float3x3)world)); // normal (world space)
// Compute simple directional lighting equation
float3 vTotalLightDiffuse = float3(0,0,0);
vTotalLightDiffuse += LightDiffuse * max(0,dot(vNormalWorldSpace, LightDir));
Output.Diffuse.rgb = MaterialDiffuseColor * vTotalLightDiffuse +
MaterialAmbientColor * LightAmbient;
Output.Diffuse.a = 1.0f;
Output.TextureUV = vTexCoord0;
return Output;
}
PS_OUTPUT PSMesh( VS_OUTPUT In)
{
PS_OUTPUT Output;
Output.RGBColor = tex2D(t0Sampler, In.TextureUV) * In.Diffuse;
return Output;
}

// Techniques
{
pass p0
{
}
}


And this is my Mesh Drawing Routine:
	bool bUseEffect = true;
int effectID = 1;
if (bUseEffect)
{
gEffect[effectID]->SetTextureValue("t0",gTexture[0]->Retrieve());
gEffect[effectID]->Retrieve()->SetValue("LightDir",&(gDirectX->Light().Direction),sizeof(D3DVECTOR));
gEffect[effectID]->Retrieve()->SetValue("LightDiffuse",&(gDirectX->Light().Diffuse),sizeof(D3DCOLORVALUE));
gEffect[effectID]->Retrieve()->SetValue("LightAmbient",&(gDirectX->Light().Ambient),sizeof(D3DCOLORVALUE));
gEffect[effectID]->Retrieve()->SetValue("MaterialDiffuse",&(gDirectX->Material().Diffuse),sizeof(D3DCOLORVALUE));
gEffect[effectID]->Retrieve()->SetValue("MaterialAmbient",&(gDirectX->Material().Ambient),sizeof(D3DCOLORVALUE));
}
else
{
gTexture[0]->Use(0,TRUE);
gDirectX->EnableLight(0,TRUE);
gDirectX->UseMaterial(TRUE);
}
gDirectX->PositionObject(D3DXVECTOR3(2.0f,-2.0f,5.0f));
if (bUseEffect)
{
gEffect[effectID]->SetMatrixValue("world",&(gDirectX->World()));
gEffect[effectID]->SetMatrixValue("worldviewprojection",&(gDirectX->WorldViewProjection()));
passes = gEffect[effectID]->Begin();
for (int i = 0; i < passes; i++)
{
gEffect[effectID]->BeginPass(i);
gTeapot->DrawSubset(0);
gEffect[effectID]->EndPass();
}
gEffect[effectID]->End();
}
else
{
gTeapot->DrawSubset(0);
}
gDirectX->PositionObject(D3DXVECTOR3(-2.0f,-2.0f,5.0f));
if (bUseEffect)
{
gEffect[effectID]->SetMatrixValue("world",&(gDirectX->World()));
gEffect[effectID]->SetMatrixValue("worldviewprojection",&(gDirectX->WorldViewProjection()));
passes = gEffect[effectID]->Begin();
for (int i = 0; i < passes; i++)
{
gEffect[effectID]->BeginPass(i);
gCube->DrawSubset(0);
gEffect[effectID]->EndPass();
}
gEffect[effectID]->End();
}
else
{
gCube->DrawSubset(0);
}
gDirectX->PositionObject(D3DXVECTOR3(2.0f,2.0f,5.0f));
if (bUseEffect)
{
gEffect[effectID]->SetMatrixValue("world",&(gDirectX->World()));
gEffect[effectID]->SetMatrixValue("worldviewprojection",&(gDirectX->WorldViewProjection()));
passes = gEffect[effectID]->Begin();
for (int i = 0; i < passes; i++)
{
gEffect[effectID]->BeginPass(i);
gSphere->DrawSubset(0);
gEffect[effectID]->EndPass();
}
gEffect[effectID]->End();
}
else
{
gSphere->DrawSubset(0);
}
gDirectX->PositionObject(D3DXVECTOR3(-2.0f,2.0f,5.0f));
if (bUseEffect)
{
gEffect[effectID]->SetMatrixValue("world",&(gDirectX->World()));
gEffect[effectID]->SetMatrixValue("worldviewprojection",&(gDirectX->WorldViewProjection()));
passes = gEffect[effectID]->Begin();
for (int i = 0; i < passes; i++)
{
gEffect[effectID]->BeginPass(i);
gTorus->DrawSubset(0);
gEffect[effectID]->EndPass();
}
gEffect[effectID]->End();
}
else
{
gTorus->DrawSubset(0);
}


The positioning of the objects while using the effect file is perfect but they are being drawn black which seems to signify a sign of the lighting not working properly. All the global effect file values are being set to values the program uses to draw when not using the effect file so I can't see what is wrong unless the fx file itself is wrong or that I need to set more lighting values but no other lighting values are actually being used in the fx file. I'll have to investigate further but this is about the simplest lighting fx file I could find and if I can't get this working then I'll never get anything more complex working let alone understood. Thanks for any replies and for reading this loooong post.

##### Share on other sites
I'd recommend taking a PIX capture and stepping through the shader to see how your computations and parameters are coming out.

##### Share on other sites
Hmm, well just tried PIX and not sure why its not working but it seems the following lines are at fault:

Heres the source code being used
		gEffect[effectID]->Retrieve()->SetValue("LightDir",&(gDirectX->Light().Direction),sizeof(D3DVECTOR));		gEffect[effectID]->Retrieve()->SetValue("LightDiffuse",&(gDirectX->Light().Diffuse),sizeof(D3DVECTOR));		gEffect[effectID]->Retrieve()->SetValue("LightAmbient",&(gDirectX->Light().Ambient),sizeof(D3DCOLORVALUE));		gEffect[effectID]->Retrieve()->SetValue("MaterialDiffuse",&(gDirectX->Material().Diffuse),sizeof(D3DCOLORVALUE));		gEffect[effectID]->Retrieve()->SetValue("MaterialAmbient",&(gDirectX->Material().Ambient),sizeof(D3DCOLORVALUE));

And Heres the PIX output in question
1208	ID3DXEffect::SetValue(0x0047A834, 0x0012F640, 12) -- result: S_OK	2141702400			1209	ID3DXEffect::SetValue(0x0047A824, 0x0012F674, 12) -- result: D3DERR_INVALIDCALL	2141746560			1210	ID3DXEffect::SetValue(0x0047A814, 0x0012F704, 16) -- result: S_OK	2141790976			1211	ID3DXEffect::SetValue(0x0047A800, 0x0012F750, 16) -- result: D3DERR_INVALIDCALL	2141833088			1212	ID3DXEffect::SetValue(0x0047A7EC, 0x0012F7AC, 16) -- result: D3DERR_INVALIDCALL	2141877248

After some tweaking of the effect file as follows:

// Lightingfloat3 LightDir;		// Light's direction in world spacefloat3 LightDiffuse;		// Light's diffuse color (was float4)float3 LightAmbient;		// Light's ambient color (was float4)// Materialsfloat4 MaterialAmbientColor;	// Material's ambient colorfloat4 MaterialDiffuseColor;	// Material's diffuse color

The PIX output is as follows:
1208	ID3DXEffect::SetValue(0x0047A834, 0x0012F640, 12) -- result: S_OK	1820396672			1209	ID3DXEffect::SetValue(0x0047A824, 0x0012F674, 12) -- result: S_OK	1820440832			1210	ID3DXEffect::SetValue(0x0047A814, 0x0012F704, 16) -- result: S_OK	1820491392			1211	ID3DXEffect::SetValue(0x0047A800, 0x0012F750, 16) -- result: D3DERR_INVALIDCALL	1820534144			1212	ID3DXEffect::SetValue(0x0047A7EC, 0x0012F7AC, 16) -- result: D3DERR_INVALIDCALL	1820578816

Looks like its just the material at fault now so will have to check that out.

##### Share on other sites
Quote:
 Original post by superpigI'd recommend taking a PIX capture and stepping through the shader to see how your computations and parameters are coming out.

Thanks for that suggestion. I could never figure out how to get anything useful out of it before. Very useful tool.

##### Share on other sites
I have Introduction to 3D Game Programming with DirectX 9.0c: A Shader Approach and can definitely recommend it. It's a pretty good book.

##### Share on other sites
Quote:
 Original post by glaekenI have Introduction to 3D Game Programming with DirectX 9.0c: A Shader Approach and can definitely recommend it. It's a pretty good book.

Thanks, my book collection is getting pretty large so didn't want to buy another book if it wasn't really worth it. Anyway, book ordered so will have to read through it and see if I can make sense of my problem.

##### Share on other sites
*Slaps head a few times at the simplicity of the bug*

//The following code:gEffect[effectID]->Retrieve()->SetValue("MaterialDiffuse",&(gDirectX->Material().Diffuse),sizeof(D3DCOLORVALUE));gEffect[effectID]->Retrieve()->SetValue("MaterialAmbient",&(gDirectX->Material().Ambient),sizeof(D3DCOLORVALUE));//should have beengEffect[effectID]->Retrieve()->SetValue("MaterialDiffuseColor",&(gDirectX->Material().Diffuse),sizeof(D3DCOLORVALUE));gEffect[effectID]->Retrieve()->SetValue("MaterialAmbientColor",&(gDirectX->Material().Ambient),sizeof(D3DCOLORVALUE));

I only noticed this after I received the book I mentioned in the earlier post and found I was doing the same way of setting as they were but with unexpected results. Added an extra line in to grab a Handle and saw that the result in PIX was NULL which then drew me to the cause of the problem. Source and Effect files had different values. I must have changed the Effect file after copying the value to my source file. *shakes head*

It's not perfectly working due to other code not being set in place in the effect file but I can see a slight light glow off of the material instead of pure black. Something to do with not setting the Inverse value which the book says has to be set to make lighting work.

Anyway, thanks for the suggestions and ideas that were posted and must confirm that at first browse through the book it seems pretty useful to have around.

1. 1
2. 2
3. 3
4. 4
frob
15
5. 5

• 14
• 12
• 20
• 12
• 13
• ### Forum Statistics

• Total Topics
632152
• Total Posts
3004470

×