Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /////////////////////////////////////////////////////
- ////////////////////VERTEX SHADER////////////////////
- /////////////////////////////////////////////////////
- #version 330
- layout(location = 0) in vec3 inPosition;
- layout(location = 1) in vec3 inNormal;
- layout(location = 2) in vec2 inTexCoord;
- layout(location = 3) in vec3 inTangent;
- layout(location = 4) in vec3 inBitangent;
- out vec2 texCoord;
- out vec3 camDir;
- out vec3 lightDir;
- out float attenuation;
- uniform mat4 viewMatrix;
- uniform mat4 modelMatrix;
- uniform mat4 projectionMatrix;
- uniform mat3 normalMatrix;
- uniform vec3 camPosIn;
- uniform vec3 lightPosIn;
- void main()
- {
- vec3 N = normalize(normalMatrix * inNormal);
- vec3 T = normalize(normalMatrix * inTangent);
- T = normalize(T - (dot(N, T) * N));
- vec3 B = normalize(normalMatrix * inBitangent);
- if (dot(cross(N, T), B) < 0.0)
- T = T * -1.0;
- mat3 TBNMatrix = transpose(mat3(T, B, N));
- vec3 position = vec3((viewMatrix * modelMatrix) * vec4(inPosition, 1.0)); //Vector is a position so W = 1.0. If it were a direction w = 0.0.
- camDir = TBNMatrix * (normalize(camPosIn - position));
- lightDir = TBNMatrix * (normalize(lightPosIn - position));
- texCoord = inTexCoord;
- float radius = 50.0;
- float dist = length(vec3((viewMatrix * modelMatrix) * vec4(lightPosIn, 1.0)) - position);
- attenuation = 1.0 / (1.0 + ((2.0 / radius) * dist) + ((1.0 / (radius * radius)) * (dist * dist)));
- gl_Position = (projectionMatrix * (viewMatrix * modelMatrix)) * vec4(inPosition, 1.0);
- }
- ///////////////////////////////////////////////////////
- ////////////////////FRAGMENT SHADER////////////////////
- ///////////////////////////////////////////////////////
- #version 330
- precision mediump float;
- in vec2 texCoord;
- in vec3 camDir;
- in vec3 lightDir;
- in float attenuation;
- layout (location = 0) out vec4 FragColour;
- uniform sampler2D textureMap;
- uniform sampler2D normalMap;
- uniform sampler2D AOMap;
- uniform sampler2D specMap;
- uniform sampler2D roughMap;
- uniform vec3 lightColour;
- const float PI = 3.14159;
- /////////////////////////////////////////////////
- //////////Normal Distribution Functions//////////
- /////////////////////////////////////////////////
- float D_Beckmann(float NH2, float tan2Alpha, float roughness2) //Beckmann = exp(-tan^2(alpha) / m^2) / PI * m^2 * cos^4(alpha)
- {
- float denom = PI * roughness2 * (pow(NH2, 2.0));
- return exp(tan2Alpha / roughness2) / denom;
- }
- float D_TrowbridgeReitz(float NH2, float roughness2) //Trowbridge-Reitz = m^2 / (1 - m^2) * cos^2(alpha) - 1
- {
- float denom = NH2 * roughness2 + (1.0 - NH2);
- return roughness2 / (PI * pow(denom, 2.0));
- }
- ///////////////////////////////////////////////////
- //////////Geometric Attenuation Functions//////////
- ///////////////////////////////////////////////////
- float G_CookTorrance(float NH2, float NdotV, float NdotL, float VdotH) //Cook-Torrance = min(1, ((N.H)^2 * (N.V)) / (V.H), ((N.H)^2 * (N.L)) / (V.H))
- {
- float g1 = (NH2 * NdotV) / VdotH;
- float g2 = (NH2 * NdotL) / VdotH;
- return min(1.0, min(g1, g2));
- }
- float G_GGXSmith(float roughness2, float NdotV, float NdotL)
- {
- float g1 = (NdotL * 2.0) / (NdotL + sqrt(roughness2 + (1.0 - roughness2) * pow(NdotL, 2.0)));
- float g2 = (NdotV * 2.0) / (NdotV + sqrt(roughness2 + (1.0 - roughness2) * pow(NdotV, 2.0)));
- return g1 * g2;
- }
- float G_BeckmannSmith(float NdotV, float NdotL, float roughness)
- {
- float g1 = NdotV / roughness * sqrt(1.0 - (pow(NdotV, 2.0)));
- float g2 = NdotL / roughness * sqrt(1.0 - (pow(NdotL, 2.0)));
- if (g1 >= 1.6)
- g1 = ((3.535 * g1) + pow((2.181 * g1), 2.0)) / 1.0 + (2.276 * g1) + pow((2.577 * g1), 2.0);
- else
- g1 = 1.0;
- if (g2 >= 1.6)
- g2 = ((3.535 * g2) + pow((2.181 * g2), 2.0)) / 1.0 + (2.276 * g2) + pow((2.577 * g2), 2.0);
- else
- g2 = 1.0;
- return g1 * g2;
- }
- float G_Neumann(float NdotL, float NdotV)
- {
- return (NdotL * NdotV) / max(NdotL, NdotV);
- }
- float G_Kelemen(float NdotL, float NdotV, float VdotH)
- {
- return (NdotL * NdotV) / pow(VdotH, 2.0);
- }
- /////////////////////////////////////
- //////////Fresnel Functions//////////
- /////////////////////////////////////
- float F_Shlick(float NdotL, float Kr) //Shlick Approximation = Kr + (1 - Kr) * (1 - (N.V))^5
- {
- return Kr + (1.0 - Kr) * pow((1.0 - NdotL), 5.0);
- }
- float F_CookTorrance(float VdotH, float Kr)
- {
- float n = (1.0 + sqrt(Kr)) / (1.0 - sqrt(Kr));
- float g = sqrt(pow(n, 2.0) + pow(VdotH, 2.0) - 1.0);
- return 0.5 * pow((g - VdotH) / (g + VdotH), 2.0) * (1.0 + pow(((g + VdotH) * VdotH - 1.0) / ((g - VdotH) * VdotH + 1.0), 2.0));
- }
- /////////////////////////////////
- //////////Main Function//////////
- /////////////////////////////////
- void main() //Cook-Torrance = (F/PI) * (D*G)/((N.L)*(N.V))
- {
- float mirror = 0.0;
- float air = 1.0;
- float bubble = 1.1;
- float ice = 1.31;
- float water = 1.33;
- float glass = 1.5;
- float standard = 2.0;
- float steel = 2.5;
- vec3 albedo = texture(textureMap, texCoord).rgb;
- vec3 normals = normalize(texture(normalMap, texCoord).rgb * 2.0 - 1.0);
- float roughness = texture(roughMap, texCoord).r;
- float spec = texture(specMap, texCoord).r;
- float AO = texture(AOMap, texCoord).r;
- float NdotV = max(dot(normals, camDir), 0.0);
- vec3 diffuse = vec3(0.0);
- vec3 CookTorrance = vec3(0.0);
- vec3 ambientColour = vec3(0.0);
- vec3 test = vec3(0.0);
- for (int i = 0; i < 1; i++)
- {
- vec3 halfAngle = normalize(camDir + lightDir);
- float NdotL = max(dot(normals, lightDir), 0.0);
- float NdotH = max(dot(normals, halfAngle), 0.0);
- float VdotH = max(dot(camDir, halfAngle), 0.0);
- float NH2 = pow(NdotH, 2.0);
- float tan2Alpha = (NH2 - 1.0) / NH2;
- float roughness2 = pow(clamp(roughness, 0.01, 0.99), 2.0);
- float Kr = pow((1.0 - standard) / (1.0 + standard), 2.0);
- float F = F_Shlick(NdotV, Kr);
- float D = D_TrowbridgeReitz(NH2, roughness2);
- float G = G_GGXSmith(roughness2, NdotV, NdotL);
- vec3 specular = spec * (lightColour * ((F * G * D) / ((PI * NdotV))));
- vec3 lambertian = (1.0 - roughness) * (lightColour * NdotL);
- test += lightColour * D;
- diffuse += lambertian * attenuation;
- CookTorrance += specular * attenuation;
- ambientColour += lightColour * attenuation;
- }
- float mipMapLevel = roughness * 12.0;
- vec3 ambience = (0.01 * ambientColour) * AO;
- vec3 final = albedo * (ambience + diffuse + CookTorrance);
- final = pow(final, vec3(1.0 / 2.2));
- FragColour = vec4(final, 1.0);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement