Sign in to follow this  

Light - Dot function

This topic is 1189 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 want to add lightning to my application.

I tried to do it in this way, but only ambient lightning is working:

float4 PS_INS (PS_INS_INPUT input) : SV_Target{

	float4 diffuse = txDiffuse.Sample( samLinear, input.Tex ) * input.Light_S + KolorL;

	float4 PosD = (0, 1, 0, 0);

	float4 LighD = (0.5f, 0.5f, 0.5f, 0.5f);
	float4 LighA = (0.2f, 0.2f, 0.2f, 0.2f);
	float4 FK;

	FK = diffuse * LighA;
	FK += saturate(dot(PosD, input.Nor) * LighD * diffuse);

	return FK;

}

I tried found what is wrong and I found that dot function doesn't work correct.

	float4 diffuse = txDiffuse.Sample( samLinear, input.Tex ) * input.Light_S + KolorL;

	float4 PosD = (0, 1, 0, 0);
	float4 PosW = (0, 1, 0, 0);

	float4 LighD = (0.5f, 0.5f, 0.5f, 0.5f);
	float4 LighA = (0.2f, 0.2f, 0.2f, 0.2f);
	float4 FK;

	FK = diffuse * LighA;
	FK += dot(PosD, PosW) * LighD * diffuse; //LighD * diffuse is not added
	FK += 1 * LighD * diffuse; //LighD * diffuse is added

Dot function should return something like this: Ax*Bx+Ay*By+Az*Bz, so dot (PosD, PosW) should return 1 (0*0+1*1+0*0+0*0).

Why doesn't dot return 1?

Edited by Kamil9132

Share this post


Link to post
Share on other sites

Just an idea : incorrect variable initialization syntax?

 

try

 

float4 PosD = float4(0, 1, 0, 0);

float4 PosW = float4(0, 1, 0, 0);

 

or float4 PosD = {0,1,0,0};

 

Cheers!

Share this post


Link to post
Share on other sites

Thanks, float4 PosD = float4(0, 1, 0, 0); resolved problem with dot funtion.

But i still have problem with this lightning.

struct PS_INS_INPUT{

	float4 Pos : SV_POSITION;
	float4 Nor : NORMAL;
	float2 Tex : TEXCOORD0;
	float Light_S : LIGHT_S;

};

struct VS_INS_INPUT{

	float4 Pos : POSITION;
	float4 Nor : NORMAL;
	float2 Tex : TEXCOORD0;

	matrix instancePos : INSTANCEPOS;
	float Light_S : LIGHT_S;

};

PS_INS_INPUT VS_INS (VS_INS_INPUT input){
   
	PS_INS_INPUT output = (PS_INS_INPUT)0;
	output.Pos = mul (input.Pos, input.instancePos);
    output.Pos = mul (output.Pos, View);
    output.Pos = mul (output.Pos, Projection);
    output.Tex = input.Tex;
	output.Light_S = input.Light_S;
	output.Nor = mul (input.Nor, input.instancePos);

    return output;
}

float4 PS_INS (PS_INS_INPUT input) : SV_Target{

	float4 diffuse = txDiffuse.Sample( samLinear, input.Tex ) * input.Light_S + KolorL;

	float3 PosD = float3 (0.25f, 0.5f, -1.0f);

	float3 LighD = float3 (0.5f, 0.5f, 0.5f);
	float3 LighA = float3 (0.2f, 0.2f, 0.2f);
	float3 FK;

	float3 NR = float3 (input.Nor.x, input.Nor.y, input.Nor.z);

	FK = diffuse * LighA;
	FK += saturate(dot(PosD, NR) * LighD * diffuse);

	return float4 (FK, diffuse.a);

}

Without FK += saturate(dot(PosD, NR) * LighD * diffuse);

http://i.imgur.com/RyX6FyK.jpg

 

With FK += saturate(dot(PosD, NR) * LighD * diffuse);

http://i.imgur.com/FPALXy6.jpg

 

Why do I get someting like second photo? 

Share this post


Link to post
Share on other sites

Well if the PosD is the lighing direction vector you can see directly that it is not normalized and for this reason it will produce lighting effect stronger than you intend. Output values over 1.0 will be clamped to 1.0 (ie. white).

 

Add PosD = normalize(PosD); after the initalization. 

 

Cheers!

Edited by kauna

Share this post


Link to post
Share on other sites

Thanks, float4 PosD = float4(0, 1, 0, 0); resolved problem with dot funtion.

But i still have problem with this lightning.

struct PS_INS_INPUT{

	float4 Pos : SV_POSITION;
	float4 Nor : NORMAL;
	float2 Tex : TEXCOORD0;
	float Light_S : LIGHT_S;

};

struct VS_INS_INPUT{

	float4 Pos : POSITION;
	float4 Nor : NORMAL;
	float2 Tex : TEXCOORD0;

	matrix instancePos : INSTANCEPOS;
	float Light_S : LIGHT_S;

};

PS_INS_INPUT VS_INS (VS_INS_INPUT input){
   
	PS_INS_INPUT output = (PS_INS_INPUT)0;
	output.Pos = mul (input.Pos, input.instancePos);
    output.Pos = mul (output.Pos, View);
    output.Pos = mul (output.Pos, Projection);
    output.Tex = input.Tex;
	output.Light_S = input.Light_S;
	output.Nor = mul (input.Nor, input.instancePos);

    return output;
}

float4 PS_INS (PS_INS_INPUT input) : SV_Target{

	float4 diffuse = txDiffuse.Sample( samLinear, input.Tex ) * input.Light_S + KolorL;

	float3 PosD = float3 (0.25f, 0.5f, -1.0f);

	float3 LighD = float3 (0.5f, 0.5f, 0.5f);
	float3 LighA = float3 (0.2f, 0.2f, 0.2f);
	float3 FK;

	float3 NR = float3 (input.Nor.x, input.Nor.y, input.Nor.z);

	FK = diffuse * LighA;
	FK += saturate(dot(PosD, NR) * LighD * diffuse);

	return float4 (FK, diffuse.a);

}

Without FK += saturate(dot(PosD, NR) * LighD * diffuse);

http://i.imgur.com/RyX6FyK.jpg

 

With FK += saturate(dot(PosD, NR) * LighD * diffuse);

http://i.imgur.com/FPALXy6.jpg

 

Why do I get someting like second photo? 

 

I'm guessing this is directional lighting being used like the sun? The reason why you're getting washed out area inside image two would because the position of the light is 1 unit above ground.

float3 PosD = float3(0.25f, 0.5f, -1.0f); //-- Light Position
float3 lightD = float3(0.5f, 0.5f, 0.5f) //-- Light Diffuse term
float3 lightA = float3(0.2f, 0.2f, 0.2f); //-- Light Ambient
float3 diffuseLight = diffuse.xyz * lightA; //-- Calculating diffuse map with the ambient color.
float intensity = saturate(dot(posD, input.normal)); //-- Clamp from 0 to 1 and get angle of light position to normal.
diffuseLight += saturate(lightD * intensity); //- Accumulate the diffuse light with the light intensity.

You could probably leave out the saturate from the diffuseLight accumulation - if it helps. I see you also changed the light position as well. Try to position it a bit heigher on Y Axis and see if there's any changes on how you like it.

 

Also the dot hlsl function returns a scalar 1 (float, int) - which could be the reason why you were having issues.

 

http://msdn.microsoft.com/en-us/library/windows/desktop/bb509594%28v=vs.85%29.aspx

Share this post


Link to post
Share on other sites

As kauna said you need to normalize light vector and normal of the surface to get reasonable result from dot product (-1, 1) and then use saturate to get value (0, 1) so you can scale your diffuse color (0 - 100%) based on light/normal orientation, on top of that ambient color should be uniform from all directions so you might want to add it instead multiply, something like:

float3 diffuseMap = txDiffuse.Sample(...);
float3 LightDir = normalize(PosD);
float3 Normal = normalize(In.Normal);
 
float3 LighD = float3 (0.5f, 0.5f, 0.5f);
float3 LighA = float3 (0.2f, 0.2f, 0.2f);
 
float NdotL = saturate(dot(Normal, LightDir));
FinalColor.rgb = (NdotL * diffuseMap * LighD) + LighA;
Edited by belfegor

Share this post


Link to post
Share on other sites

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