#version 430 core uniform sampler2D colorTexture; uniform sampler2D rust; uniform sampler2D scratches; uniform sampler2D shipNormalSampler; uniform sampler2D rustNormalSampler; uniform vec3 sunPos; uniform vec3 sunColor; uniform float sunLightExp; uniform vec3 cameraPos; uniform float time; uniform vec3 reflectorPos; uniform vec3 reflectorDir; uniform vec3 reflectorColor; uniform float reflectorAngle; uniform float reflectorLightExp; vec3 normalizedVertexNormal; vec3 scratchesColor; in vec3 vertexPosWld; in vec2 vertexTexCoordOut; in vec3 viewDirTS; in vec3 sunLightDirTS; in vec3 reflectorLightDirTS; in vec3 vertexLocPos; out vec4 outColor; vec4 calcPointLight(vec3 fragColor, vec3 lightPos, vec3 lightDirTS, vec3 lightColor, float lightExp) { float lightDistance = length(vertexPosWld - lightPos); vec3 newLightColor = lightColor / pow(lightDistance, 2); float intensity = dot(normalizedVertexNormal, -lightDirTS); intensity = max(intensity, 0.0); vec3 reflectDir = reflect(lightDirTS, normalizedVertexNormal); float glossPow = 8; float specular = pow(max(dot(viewDirTS, reflectDir), 0.0), glossPow); float diffuse = intensity; vec3 resultColor = newLightColor * (fragColor * diffuse + specular ); return vec4(1 - exp(-resultColor * lightExp), 1.0); } vec4 calcSpotLight(vec3 fragColor, vec3 lightPos, vec3 lightDirTS, vec3 lightColor, float lightExp) { vec3 reflectorLightDir = normalize(vertexPosWld - lightPos); float angleCos = dot(reflectorLightDir, reflectorDir); float reflectorOutAngle = reflectorAngle + radians(10); float epsilon = cos(reflectorAngle) - cos(reflectorOutAngle); vec4 res = vec4(0, 0, 0, 1); if (angleCos > cos(reflectorOutAngle)) { float intensity = clamp((angleCos - cos(reflectorOutAngle)) / epsilon, 0.0, 1.0); res = calcPointLight(fragColor, lightPos, lightDirTS, lightColor, lightExp * intensity); } return res; } vec3 calcShipColor() { vec3 shipColor = texture2D(colorTexture, vertexTexCoordOut).rgb; vec3 rustColor = texture2D(rust, vertexTexCoordOut).rgb; vec3 textureColor = mix(rustColor, shipColor, scratchesColor.r); if (sin(vertexLocPos.y * vertexLocPos.x * vertexLocPos.z) > 0) { textureColor = vec3(1, 0, 0); } return textureColor; } vec3 calcShipNormal() { vec3 shipNormal = texture2D(shipNormalSampler, vertexTexCoordOut).xyz; shipNormal = 2 * shipNormal - 1;//since sampler has values from [0, 1], but we want [-1, 1] vec3 rustNormal = texture2D(rustNormalSampler, vertexTexCoordOut).xyz; rustNormal = 2 * rustNormal - 1;//since sampler has values from [0, 1], but we want [-1, 1] //normalize to avoid potential precision problems in sampler texture return normalize(mix(rustNormal, shipNormal, scratchesColor.r)); } void main() { scratchesColor = texture2D(scratches, vertexTexCoordOut).rgb; vec3 textureColor = calcShipColor(); normalizedVertexNormal = calcShipNormal(); //Debug //normalizedVertexNormal = vec3(0, 0, 1); outColor = calcPointLight(textureColor, sunPos, sunLightDirTS, sunColor, sunLightExp); outColor += calcSpotLight(textureColor, reflectorPos, reflectorLightDirTS, reflectorColor, reflectorLightExp); //Debug //outColor = vec4(textureColor, 1); }