Light - Dot function

Started by
5 comments, last by Kamil9132 9 years, 7 months ago

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?

Advertisement

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!

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?

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!

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

Game Engine's WIP Videos - http://www.youtube.com/sicgames88
SIC Games @ GitHub - https://github.com/SICGames?tab=repositories
Simple D2D1 Font Wrapper for D3D11 - https://github.com/SICGames/D2DFontX

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;

Thank you for help.

This topic is closed to new replies.

Advertisement