Sign in to follow this  
p0is0n

[SOLVED] fx lighting (lighting terrain by a direction to the light source)

Recommended Posts

Hi, I'm trying to light my terrain, but I must be doing something wrong as the light direction I give to the fx dosent work, the light ends up in the center of the screen. If anyone can see any problems in the code below please let me know. The light direction is the direction to the sun.
/*------------------------------------------------------------------------------------------------------
TerrainBlendMap.fx
Uses a blend map to blend 3 textures together across the terrain
Lights the terrain using a direction to the sun and the vertex normals
------------------------------------------------------------------------------------------------------*/

//Defines the matrix passed in (the view matrix multiplied by the projection matrix)
uniform extern float4x4 gViewTimesProj;
//The light vector
uniform extern float3 gDirectionToSun;
//Texture 0
uniform extern texture gTex0;
//Texture 1
uniform extern texture gTex1;
//Texture 2
uniform extern texture gTex2;
//Blend Texture
uniform extern texture gTexBlend;
//The texture scale
uniform extern float gTexScale;

/*------------------------------------------------------------------------------------------------------
Sets the texture sampler states
------------------------------------------------------------------------------------------------------*/
sampler Tex0Sampler = sampler_state
{
	Texture = <gTex0>;
	MinFilter = LINEAR;
	MagFilter = LINEAR;
	MipFilter = LINEAR;
	AddressU  = WRAP;
    AddressV  = WRAP;
};
sampler Tex1Sampler = sampler_state
{
	Texture = <gTex1>;
	MinFilter = LINEAR;
	MagFilter = LINEAR;
	MipFilter = LINEAR;
	AddressU  = WRAP;
    AddressV  = WRAP;
};
sampler Tex2Sampler = sampler_state
{
	Texture = <gTex2>;
	MinFilter = LINEAR;
	MagFilter = LINEAR;
	MipFilter = LINEAR;
	AddressU  = WRAP;
    AddressV  = WRAP;
};
sampler BlendMapSampler = sampler_state
{
	Texture = <gTexBlend>;
	MinFilter = LINEAR;
	MagFilter = LINEAR;
	MipFilter = LINEAR;
	AddressU  = WRAP;
    AddressV  = WRAP;
};

/*------------------------------------------------------------------------------------------------------
Define vertex shader output structure
Output position, tiled tex coord, non tiled tex coord, the shade for that part
------------------------------------------------------------------------------------------------------*/
struct OutputVS
{
    float4 pos				: POSITION0;
    float2 tiledTexCoord    : TEXCOORD0;
    float2 nonTiledTexCoord : TEXCOORD1;
    float  shade			: TEXCOORD2;
};

/*------------------------------------------------------------------------------------------------------
Defines the vertex shader program
------------------------------------------------------------------------------------------------------*/
OutputVS TerrainVS(float3 pos : POSITION0, float3 normal : NORMAL0, float2 tex0: TEXCOORD0)
{
    //Zero out the output
	OutputVS outVS = (OutputVS)0;
	
	//Calculates the grayscale ambient and diffuse lighting
	outVS.shade = saturate(max(0.0f, dot(normal, gDirectionToSun)) + 0.3f);
	
	//Transform the co-ordinates to homogeneous clip space
	outVS.pos = mul(float4(pos, 1.0f), gViewTimesProj);
	
	//Pass texture coordinates to be interpolated in rasterization
	outVS.tiledTexCoord = tex0 * gTexScale;	//Scale tex-coord to tile
	outVS.nonTiledTexCoord = tex0;	//Blend map is not tiles
	 
	//Return the output
    return outVS;
}

/*------------------------------------------------------------------------------------------------------
Defines the pixel shader program
------------------------------------------------------------------------------------------------------*/ 
float4 TerrainPS(float2 tiledTexCoord : TEXCOORD0, float2 nonTiledTexCoord : TEXCOORD1, float shade : TEXCOORD2) : COLOR
{
	//Layer maps are tiled
	float3 col0 = tex2D(Tex0Sampler, tiledTexCoord).rgb;
	float3 col1 = tex2D(Tex1Sampler, tiledTexCoord).rgb;
	float3 col2 = tex2D(Tex2Sampler, tiledTexCoord).rgb;
	
	//Blendmap is not tiled
	float3 blend = tex2D(BlendMapSampler, nonTiledTexCoord).rgb;
	
	//Get the inverse of all the blends and convert it into between 0 and 1
	float inverse = 1.0f / (blend.r + blend.g + blend.b);
	
	//Scale the colours by each texture layer by its weight in the blend map
	col0 *= blend.r * inverse;
	col1 *= blend.g * inverse;
	col2 *= blend.b * inverse;
	
	//Add the colours from the textures together, and multiply it by the shade
	float3 finalColour = (col0 + col1 + col2) * shade;
	
	return float4(finalColour, 1.0f);
}

technique TerrainBlendMapTech
{
    pass P0
    {
        //Specify the vertex and pixel shader associated with this pass
        vertexShader = compile vs_2_0 TerrainVS();
        pixelShader  = compile ps_2_0 TerrainPS();
    }
}


Thanks in advance for any help. [Edited by - p0is0n on March 24, 2008 6:56:57 PM]

Share this post


Link to post
Share on other sites
Quote:
saturate(max(0.0f, dot(normal, gDirectionToSun)) + 0.3f);

Just a guess, but any normals within 45 degrees of the sun direction will result in shade = 1. That's not much variation.

Do you add 0.3f for a reason?

Share this post


Link to post
Share on other sites
I dont see any obvious problems in the FX file itself. Are you sure the light direction is correct? Try hardcoding it just to see what happens. Does that work as expected? If so try checking the application code. Also what exactly do you mean by the light ends up in the center of the screen? It is a directional light and has no position, only a direction. I hope I can help.

Share this post


Link to post
Share on other sites
Quote:

Just a guess, but any normals within 45 degrees of the sun direction will result in shade = 1. That's not much variation.

Do you add 0.3f for a reason?


No that was in there by accident from earlier testing, thanks for letting me know it was still there.

@Roboticus
Thanks for the input, I hardcoded the light direction and nothing changed so I can cross that off my list. A couple of times when I ran my program the light seemed as though it was in the center of the terrain going in one direction leaving half the terrain completely blank. However I am unable to replicate this so it may have just been one of those random things.

Seeing as there is nothing in the fx file that looks wrong, and I certianly cant find anything I'm gonna have to go back over my other code. If anything is wrong I'm guessing it's gonna be my normal calculations.

Thanks for the advice.

EDIT : It was my normal calculations that were wrong, thanks for the input though.

[Edited by - p0is0n on March 24, 2008 6:26:06 PM]

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