Can you guys check my directional lighting is correct?

Started by
6 comments, last by eu5 2 years, 9 months ago

Hi. I'm studying for lighting.

This is directional light I made.

There is no effect like a shadow.. just used the lighting.

I used diffuse and specular.

I don't know why the top of cube is shining sometimes.

even doesn't change the cube normal or view direction.

The white line of light is the direction of light.

The light is acting like the Sun.

So the position of the light doesn't affect to anything. but rotation can affect.

Advertisement

you need to provide code of your shader, my guess is that you rotate it wrong way

@_WeirdCat_ Thank you for your feedback!

This is my vertex shader code.

VS_OUTPUT main(VS_INPUT input)
{
	VS_OUTPUT output;
	
	output.Pos      = mul(float4(input.Pos, 1), WorldViewProjection);
	output.WPos     = mul(float4(input.Pos, 1), World);
	output.Color    = input.Color;
	output.Normal   = mul(input.Normal, (float3x3) World);
	output.TexCoord = input.TexCoord;
	
	return output;
}

And this is the pixel shader code.

float4 main(PS_INPUT input) : SV_TARGET
{
	//float3 SampleColor = objTexture.Sample(objSamplerState, input.TexCoord).rgb;
	
	float3 WorldCamPos = mul(CameraPosition, (float3x3) World);
	float3 ViewDir = normalize(input.WPos.xyz - WorldCamPos);
	float3 WorldLightDir = mul(LightDir.xyz, (float3x3) World);
	WorldLightDir = normalize(WorldLightDir);
	
	float3 WorldNormal = mul(input.Normal, (float3x3) World);
	WorldNormal = normalize(WorldNormal);
	
	// Get Diffuse
	float Diffuse = max(dot(-WorldLightDir, WorldNormal), 0);
	float3 PhongD = Diffuse * (LightColor.rgb * input.Color);
	
	// Get Specular
	float3 PhongS = float3(0.f, 0.f, 0.f);
	if (Diffuse > 0.f)
	{
		float3 ReflectionVec = normalize(reflect(LightDir.xyz, WorldNormal));
		float Specular = max(dot(ReflectionVec, -ViewDir), 0);
		Specular = pow(Specular, 60.f);
		PhongS = Specular * (LightColor.rgb * float3(0.7f, 0.7f, 0.7f));
	}
	
	// Get Ambient (temp)
	// Not used currently.
	float3 PhongA = 0.1f * (LightColor.rgb * input.Color);
	
	float3 FinalColor = PhongD + PhongS;
	
	return float4(FinalColor, 1.f);
}

But if the rotation way is the problem, aren't you need a cpp code?

@eu5 And this is the way how I rotate object.

void GameObject::Rotate(const XMVECTOR& rotation)
{
	m_RotationVector += rotation;
	XMStoreFloat3(&m_F3Rotation, m_RotationVector);
	UpdateMatrix();
}

void RenderableGameObject::UpdateMatrix()
{
	// S->R->T
	XMMATRIX ScalingMatrix = XMMatrixScaling(m_F3ScalingSize.x, m_F3ScalingSize.y, m_F3ScalingSize.z);
	XMMATRIX RotationMatrix = XMMatrixRotationRollPitchYaw(m_F3Rotation.x, m_F3Rotation.y, m_F3Rotation.z);
	XMMATRIX TranslationMatrix = XMMatrixTranslation(m_F3Pos.x, m_F3Pos.y, m_F3Pos.z);

	//m_WorldMatrix = matScaling * matRotation * matTranslation;
	m_WorldMatrix = ScalingMatrix * RotationMatrix * TranslationMatrix;

	// Update direction vectors
	UpdateDirectionVectors();
}

void GameObject::UpdateDirectionVectors()
{
	XMMATRIX matRotation = XMMatrixRotationRollPitchYaw(m_F3Rotation.x, m_F3Rotation.y, 0.f);
	
	m_ForwardVector  = XMVector3Transform(UnitVector::FORWARD, matRotation); // FORWARD: (0.f,0.f,1.f,0.f)
	m_BackwardVector = XMVector3Transform(UnitVector::BACKWARD, matRotation);
	m_LeftVector	 = XMVector3Transform(UnitVector::LEFT, matRotation);
	m_RightVector	 = XMVector3Transform(UnitVector::RIGHT, matRotation);
}

This isn't correct for a world-space normal:

output.Normal   = mul(input.Normal, (float3x3) World);

As long as you have no skew or scale in your World matrix, it will “work,” but as soon as you have skew or scale, you will want to use the inverse of the transpose of the upper-left three-by-three of the World matrix, to properly get flattening on squash and such. Otherwise the scale scales “in the wrong direction.”

float3 WorldLightDir = mul(LightDir.xyz, (float3x3) World);

Is your light really expressed in object coordinates? I would expect, because you do lighting in world space, that the light direction will already be in world space.

And even if you DO use object-local coordinates, you should not need to transform this for every pixel shader invocation, given that LightDir seems to be a constant. But very likely, you should just take out this transformation – or multiply it by some light-specific transform matrix. (Typically, this is done in software, before the shader is configured, if you have a light entity with a world transform.)

float3 WorldNormal = mul(input.Normal, (float3x3) World);

You already transformed the normal into world space, before interpolation. Re-transforming it will generate hard-to-predict outcomes.


enum Bool { True, False, FileNotFound };

As.mentioned above you only rotate normals, i just pass object rotation matrix to the shader itself.

Delete.these lines

float3 WorldLightDir = mul(LightDir.xyz, (float3x3) World); WorldLightDir = normalize(WorldLightDir); float3 WorldNormal = mul(input.Normal, (float3x3) World); WorldNormal = normalize(WorldNormal); // Get Diffuse

float3 WorldCamPos = mul(CameraPosition, (float3x3) World); float3 ViewDir = normalize(input.WPos.xyz - WorldCamPos); float3 WorldLightDir = mul(LightDir.xyz, (float3x3) World); WorldLightDir = normalize(WorldLightDir);

I must mention that LightDir is not defined in your code and like above hplus said its already in worldspace same for.camera position it should be in worldspace too, so no need to multiply it by world matrix

Instead worldlightdir is = normalize(LightPos - input.WPos )

ViewDir = normalize(Input.WPos-CamPos )

Just.define camerapos and lightpos already in worldspace ( this means just set.their positions do not multiply anything by any matrix)

@hplus0603 @_WeirdCat_

Thank you guys! It works!

The transformation of the normal in pixel shader was my mistake. It was just for the testing. I forgot the comment.

And I don't understand why the camera and light is already in world space.

Because their positions are set with the same way like cubes, tile.

I'm gonna think about it more.

--------------------------------------------

Okey. I got it.

I think I was confused.

The position of the camera and the direction of the light already transformed in cpp.

I was a fool…

This topic is closed to new replies.

Advertisement