Jump to content

Phong and tangent space.

Kamjam66xx

Hello i really need help getting my lighting into tangent space to work with my shadows and all that. its straight up phong, not blinn-phong. im really confused, because my code does not reflect any tutorial since ive been trying to take the hard route. im completely for what to do. can anyone help?

 

here are my shaders. you can ignore the messy parts. my phong lighting is neatly packed into functions. you can ignore the if statement at the end too. please help!

 

Vertex Shader

#version 330

layout (location = 0) in vec3 pos;
layout (location = 1) in vec2 tex;
layout (location = 2) in vec3 norm;
layout (location = 3) in vec3 tang;
layout (location = 4) in vec3 bitang;

out vec2 TexCoord;
out vec3 normal;
out vec3 FragPos; 
out vec4 DirectionalLightSpacePos;
out vec3 nTangent;
out vec3 nBitangent

uniform mat4 model;
uniform mat4 projection;
uniform mat4 view;
uniform mat4 directionalLightTransform;

void main()
{
	gl_Position = projection * view * model * vec4(pos, 1.0f);
	DirectionalLightSpacePos = directionalLightTransform * model * vec4(pos, 1.0);
	
	TexCoord = tex;

	FragPos = (model * vec4(pos, 1.0f)).xyz;

	normal = norm;
	nTangent = tang;
	nBitangent = bitang;
	// normal = mat3(transpose(inverse(model))) * norm;	
}

 

 

Fragment Shader

 

#version 330

in vec2 TexCoord;
in vec3 normal;
in vec3 FragPos;
in vec4 DirectionalLightSpacePos;
in vec3 nTangent;
in vec3 nBitangent;

out vec4 colour;

const int MAX_POINT_LIGHTS = 3;
const int MAX_SPOT_LIGHTS = 3;

struct Light
{
	vec3 colour;
	float ambientIntensity;
	float diffuseIntensity;
};

struct DirectionalLight 
{
	Light base;
	vec3 direction;
};

struct PointLight
{
	Light base;
	
	vec3 position;
	float constant;
	float linear;
	float exponent;
};

struct SpotLight
{
	PointLight base;
	vec3 direction;
	float edge;
};

struct OmniShadowMap
{
	samplerCube shadowMap;
	float farPlane;
};

struct Material
{
	float specularIntensity;
	float specularPower;
};

uniform int pointLightCount;
uniform int spotLightCount;

uniform DirectionalLight directionalLight;
uniform PointLight pointLights[MAX_POINT_LIGHTS];
uniform SpotLight spotLights[MAX_SPOT_LIGHTS];

uniform OmniShadowMap omniShadowMaps[MAX_POINT_LIGHTS + MAX_SPOT_LIGHTS];


// KEEP TEXTURE LAYOUTS EXPLICIT 
layout (binding = 1) uniform sampler2D theTextureDiffuse;
layout (binding = 4) uniform sampler2D theTextureSpecular;
layout (binding = 5) uniform sampler2D theTextureNormal;
layout (binding = 2) uniform sampler2D directionalShadowMap;
layout (binding = 6) uniform samplerCube skyBoxTexture;

uniform Material material;

uniform vec3 eyePosition;

vec3 gridSamplingDisk[20] = vec3[]
(
   vec3(1, 1,  1), vec3( 1, -1,  1), vec3(-1, -1,  1), vec3(-1, 1,  1), 
   vec3(1, 1, -1), vec3( 1, -1, -1), vec3(-1, -1, -1), vec3(-1, 1, -1),
   vec3(1, 1,  0), vec3( 1, -1,  0), vec3(-1, -1,  0), vec3(-1, 1,  0),
   vec3(1, 0,  1), vec3(-1,  0,  1), vec3( 1,  0, -1), vec3(-1, 0, -1),
   vec3(0, 1,  1), vec3( 0, -1,  1), vec3( 0, -1, -1), vec3( 0, 1, -1)
);

vec4 AmbientColourG = vec4(0.0f, 0.0f, 0.0f, 0.0f);
vec4 SpecularColourG = vec4(0.0f, 0.0f, 0.0f, 0.0f);
vec4 DiffuseColourG = vec4(0.0f, 0.0f, 0.0f, 0.0f);

vec3 Normal = vec3(0.0f, 0.0f, 0.0f);

vec4 CalcLightByDirection(Light light, vec3 direction, float shadowFactor)
{
	vec4 ambientColour = vec4(light.colour, 1.0f) * light.ambientIntensity;
	
	float diffuseFactor = max(dot(normalize(Normal), normalize(direction)), 0.0f);
	vec4 diffuseColour = vec4(light.colour * light.diffuseIntensity * diffuseFactor, 1.0f);
	
	vec4 specularColour = vec4(0, 0, 0, 0);
	
	if(diffuseFactor > 0.0f)
	{
		vec3 fragToEye = normalize(eyePosition - FragPos);
		vec3 reflectedVertex = normalize(reflect(direction, normalize(Normal)));
		
		float specularFactor = dot(fragToEye, reflectedVertex);
		if(specularFactor > 0.0f)
		{
			specularFactor = pow(specularFactor, material.specularPower);
			specularColour = vec4(light.colour * material.specularIntensity * specularFactor, 1.0f);
		}
	}

	SpecularColourG += specularColour;
	AmbientColourG += ambientColour;
	DiffuseColourG += diffuseColour;

	return vec4(1.0 - shadowFactor);	// * (diffuseColour + specularColour));
}

vec4 CalcPointLightByDirection(Light light, vec3 direction, float shadowFactor)
{
	vec4 ambientColour = vec4(light.colour, 1.0f) * light.ambientIntensity;

	
	float diffuseFactor = max(dot(normalize(Normal), normalize(direction)), 0.0f);
	vec4 diffuseColour = vec4(light.colour * light.diffuseIntensity * diffuseFactor + diffuseFactor * 0.2, 1.0f);
	
	vec4 specularColour = vec4(0, 0, 0, 0);
	
	if(diffuseFactor > 0.0f)
	{
		vec3 fragToEye = normalize(eyePosition - FragPos);
		vec3 reflectedVertex = normalize(reflect(direction, normalize(Normal)));
		
		float specularFactor = dot(fragToEye, reflectedVertex);
		if(specularFactor > 0.0f)
		{
			specularFactor = pow(specularFactor, material.specularPower);
			specularColour = vec4(light.colour * material.specularIntensity * specularFactor, 1.0f);
		}
	}

	SpecularColourG += specularColour;
	AmbientColourG += ambientColour; 
	DiffuseColourG += diffuseColour;
	
	// 	return ambientColour + (1.0 - shadowFactor) * (diffuseColour + specularColour));
	return vec4(1.0 - shadowFactor);
}

float CalcPointShadowFactor(PointLight light, int shadowIndex)
{
	vec3 fragToLight = FragPos - light.position;
	float currentDepth = length(fragToLight);
	
	float shadow = 0.0;
	float bias   = 0.015;
	int samples  = 20;
	float viewDistance = length(eyePosition - FragPos);
	float diskRadius = (1.0 + (viewDistance / omniShadowMaps[shadowIndex].farPlane)) / 85.0;
	for(int i = 0; i < samples; ++i)
	{
		float closestDepth = texture(omniShadowMaps[shadowIndex].shadowMap, fragToLight + gridSamplingDisk[i] * diskRadius).r;
		closestDepth *= omniShadowMaps[shadowIndex].farPlane;
		if(currentDepth - bias > closestDepth)
			shadow += 1.0;
	}
	shadow /= float(samples);  
	
	return shadow;
}

float CalcShadowFactor(vec4 DirectionalLightSpacePos)
{
	vec3 projCoords = DirectionalLightSpacePos.xyz / DirectionalLightSpacePos.w;
	projCoords = projCoords * 0.5 + 0.5;
	
	float closestDepth = texture(directionalShadowMap, projCoords.xy).r;
	float currentDepth = projCoords.z;
	
	vec3 normal = normalize(Normal);
	vec3 lightDir = normalize(directionalLight.direction);
	float bias = max(0.05 * (1.0 - dot(normal, lightDir)), 0.0005);
	
	float shadow = 0.0;
	vec2 texelSize = 1.0 / textureSize(directionalShadowMap, 0);
	for(int x = -1; x <= 1; ++x)
	{
		for(int y = -1; y <= 1; ++y)
		{
			float pcfDepth = texture(directionalShadowMap, projCoords.xy + vec2(x,y) * texelSize).r;
			shadow += currentDepth - bias > pcfDepth ? 1.0 : 0.0;
		}
	}
	
	shadow /= 9.0;
	if(projCoords.z > 1.0)
	{
		shadow = 0.0;
	}
	
	return shadow;
}

vec4 CalcDirectionalLight(vec4 DirectionalLightSpacePos)
{
	float ShadowFactor = CalcShadowFactor(DirectionalLightSpacePos);
	return CalcLightByDirection(directionalLight.base, directionalLight.direction, ShadowFactor);
}

vec4 CalcPointLight(PointLight pLight, int shadowIndex)
{
	vec3 direction = FragPos - pLight.position;
	float distance = length(direction);
	direction = normalize(direction);
	
	float shadowFactor = CalcPointShadowFactor(pLight, shadowIndex);
	
	vec4 colour = CalcPointLightByDirection(pLight.base, direction, shadowFactor);
	float attenuation = pLight.exponent * distance * distance +
						pLight.linear * distance +
						pLight.constant;
	
	return (colour / attenuation);
}

vec4 CalcSpotLight(SpotLight sLight, int shadowIndex)
{
	vec3 rayDirection = normalize(FragPos - sLight.base.position);
	float slFactor = dot(rayDirection, sLight.direction);
	
	if(slFactor > sLight.edge)
	{
		vec4 colour = CalcPointLight(sLight.base, shadowIndex);
		
		return colour * (1.0f - (1.0f - slFactor)*(1.0f/(1.0f - sLight.edge)));
		
	} else {
		return vec4(0, 0, 0, 0);
	}
}

vec4 CalcPointLights()
{
	vec4 totalColour = vec4(0, 0, 0, 0);
	for(int i = 0; i < pointLightCount; i++)
	{		
		totalColour += CalcPointLight(pointLights[i], i);
	}
	
	return totalColour;
}

vec4 CalcSpotLights()
{
	vec4 totalColour = vec4(0, 0, 0, 0);
	for(int i = 0; i < spotLightCount; i++)
	{		
		totalColour += CalcSpotLight(spotLights[i], i + pointLightCount);
	}
	
	return totalColour;
}

void main()
{
	 vec3 Normal = normalize(  mat3(nTangent, nBitangent, normal) * texture(theTextureNormal, TexCoord).rgb * 2.0f - 1.0f  );



	vec4 diffuse = texture(theTextureDiffuse, TexCoord);
	vec4 specular = texture(theTextureSpecular, TexCoord);
	//vec4 shadowFactor = CalcDirectionalLight(DirectionalLightSpacePos);
	vec4 shadowFactor = CalcPointLights();
	//shadowFactor += CalcSpotLights();

	float alpha = texture(theTextureDiffuse, TexCoord).a;

	vec4 finalColour =  diffuse * ( AmbientColourG + ( shadowFactor * DiffuseColourG ) ) * ( ( AmbientColourG + shadowFactor ) * ( DiffuseColourG + ( 1.2f * (specular * SpecularColourG) / 32.0f) ) );
	float exposure = 32.0f;

	vec3 I = normalize(FragPos - eyePosition);
	vec3 R = reflect(I, normalize(Normal));
	vec4 reflectColor = texture(skyBoxTexture, R);
	float reflectStrength = 0.50f;


	vec4 noAlpha = vec4(exposure * (finalColour * finalColour)) + (0.5f * diffuse);
	colour = vec4(noAlpha.xyz, alpha);

	vec4 reflectionFinal = reflectColor * reflectStrength * specular * shadowFactor;
    colour *= (reflectionFinal + 0.01f);
	
	
	if(gl_FragCoord.y > 0) { colour.rgb = Normal; }
	else { colour.rgb = normal.rgb; }	
	// if(gl_FragCoord.y > 0) { colour *= (reflectionFinal + 0.01f); }	
	// if(gl_FragCoord.y < 0) { colour *= (reflectionFinal + 0.01f); }


	float gamma = 0.819;
	colour.rgb = pow(colour.rgb, vec3(1.0/gamma));	
}

 

it wont compile as is. im interested in the math.

 

Link to comment
Share on other sites

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

×