#version 330 struct Material { vec4 ambient; vec4 diffuse; sampler2D diffuseMap; vec4 specular; sampler2D specularMap; float shininess; float reflectivity; float refractiveIndex; float opacity; bool hasTexture; bool hasSpecularMap; sampler2D normalMap; bool hasNormalMap; }; in vec3 defNormal, worldNormal; in vec2 texCoord; // These are all in tangent space in vec3 lightPos; in vec3 viewPos; in vec3 fragPos; in vec3 worldViewPos, worldFragPos; uniform vec4 lightColor; uniform Material material; uniform samplerCube skybox; out vec4 FragColor; vec4 reflection() { vec3 I = normalize(worldFragPos - worldViewPos); vec3 R = reflect(I, normalize(worldNormal)); return vec4(texture(skybox, R).rgb, 1); } vec4 refraction() { float ratio = 1.f / material.refractiveIndex; vec3 I = normalize(worldFragPos - worldViewPos); vec3 R = refract(I, normalize(worldNormal), ratio); return vec4(texture(skybox, R).rgb, 1); } void main() { vec3 normal = texture(material.normalMap, texCoord).rgb; normal = normalize(normal * 2 - 1); if (!material.hasNormalMap) normal = defNormal; vec4 ambient = material.ambient * texture(material.diffuseMap, texCoord); if (!material.hasTexture) ambient = material.ambient; ambient = mix(ambient, reflection(), material.reflectivity); ambient = mix(ambient, refraction(), 1 - material.opacity); vec3 lightDir = normalize(lightPos - fragPos); vec4 diffTex = texture(material.diffuseMap, texCoord); if (!material.hasTexture) diffTex = material.diffuse; diffTex = mix(diffTex, reflection(), material.reflectivity); diffTex = mix(diffTex, refraction(), 1 - material.opacity); vec4 diffuse = max(0, dot(lightDir, normal)) * diffTex; vec3 viewDir = normalize(viewPos - fragPos); vec3 reflectDir = reflect(-lightDir, normal); vec4 specTex = texture(material.specularMap, texCoord); if (!material.hasSpecularMap) specTex = material.specular; vec4 specular = pow(max(0, dot(viewDir, reflectDir)), material.shininess) * specTex; FragColor = (ambient + diffuse + specular) * lightColor; }