Normals and TBN Matrices

Started by
0 comments, last by Toastmastern 5 years, 9 months ago

Hello everyone,

I've been during the past few days trying to fix sunlight on my sphere which have some bugs in it. For starters I'm using this code: https://github.com/Illation/ETEngine/blob/master/source/Engine/Shaders/PlanetPatch.glsl to calculate my normals instead of using a normal map.

I'm then using this guide: http://www.thetenthplanet.de/archives/1180
To get my TBN Matrix. I have 2 main issues I'm working to solve when reworking this code. First I get seams in the normal map along the equator and from pole to pole. The normal also seems to move when I move my camera. 

Here is a video showing what I mean, the color is the normal calculated with the TBN matrix and as the camera moves it moves along with it. Nothing is multiplied by the view matrix or anything.

Here is my code Vertex Shader:
 


	output.normal = mul(finalPos, worldMatrix);
	output.viewVector = (mul(cameraPos.xyz, worldMatrix) - mul(finalPos, worldMatrix));

	mapCoords = normalize(finalPos);
	output.mapCoord = float2((0.5f + (atan2(mapCoords.z, mapCoords.x) / (2 * 3.14159265f))), (0.5f - (asin(mapCoords.y) / 3.14159265f)));

	output.position = mul(float4(finalPos, 1.0f), worldMatrix);
	output.position = mul(output.position, viewMatrix);
	output.position = mul(output.position, projectionMatrix);

	return output;

and also what might be more important, the pixel shader:
 


float3x3 GetTBNMatrix(float3 normalVector, float3 posVector, float2 uv)
{
	float3 dp1, dp2, dp2perp, dp1perp, T, B;
	float2 duv1, duv2;
	float invMax;

	dp1 = ddx(posVector);
	dp2 = ddy(posVector);
	duv1 = ddx(uv);
	duv2 = ddx(uv);

	dp2perp = cross(dp2, normalVector);
	dp1perp = cross(normalVector, dp1);

	// * -1 due to being LH coordinate system
	T = (dp2perp * duv1.x + dp1perp * duv2.x) * -1;
	B = (dp2perp * duv1.y + dp1perp * duv2.y) * -1;

	invMax = rsqrt(max(dot(T, T), dot(B, B)));

    return float3x3(T * invMax, B * invMax, normalVector);
}

float GetHeight(float2 uv)
{
	return shaderTexture.SampleLevel(sampleType, uv, 0).r * (21.229f + 8.2f);
}

float3 CalculateNormal(float3 normalVector, float3 viewVector, float2 uv)
{
	float textureWidth, textureHeight, hL, hR, hD, hU;
	float3 texOffset, N;
	float3x3 TBN;

	shaderTexture.GetDimensions(textureWidth, textureHeight);

	texOffset = float3((1.0f / textureWidth), (1.0f / textureHeight), 0.0f);

	hL = GetHeight(uv - texOffset.xz);
	hR = GetHeight(uv + texOffset.xz);
	hD = GetHeight(uv + texOffset.zy);
	hU = GetHeight(uv - texOffset.zy);

	N = normalize(float3((hL - hR), (hU - hD), 2.0f));

	TBN = GetTBNMatrix(normalVector, -viewVector, uv);

	return mul(TBN, N);
}

float4 MarsPixelShader(PixelInputType input) : SV_TARGET
{
	float3 normal;
	float lightIntensity, color;
	float4 finalColor;

	normal = normalize(CalculateNormal(normalize(input.normal), normalize(input.viewVector), input.mapCoord));

    lightIntensity = saturate(dot(normal, normalize(-lightDirection)));

    color = saturate(diffuseColor * lightIntensity);

	return float4(normal.rgb, 1.0f);//float4(color, color, color, 1.0f);
}

Hope anyone can help shine some light on this problem for me

Best Regards and Thanks in advance

Toastmastern

This topic is closed to new replies.

Advertisement