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