diff --git a/res/shaders/simple.frag b/res/shaders/simple.frag index cf17b8c..3ab4d53 100644 --- a/res/shaders/simple.frag +++ b/res/shaders/simple.frag @@ -10,6 +10,7 @@ in layout(location = 5) vec3 bitangent; layout(binding = 0) uniform sampler2D diffuseTexture; layout(binding = 1) uniform sampler2D normalTexture; layout(binding = 2) uniform sampler2D displacementTexture; +layout(binding = 3) uniform sampler2D reflectionTexture; uniform float displacementCoefficient; uniform mat4 MVP; @@ -19,6 +20,7 @@ uniform mat4 MVnormal; // material uniform float opacity; uniform float shininess; +uniform float reflexiveness; uniform vec3 diffuse_color; uniform vec3 specular_color; uniform vec3 emissive_color; @@ -28,6 +30,7 @@ uniform bool isTextured; uniform bool isVertexColored; uniform bool isNormalMapped; uniform bool isDisplacementMapped; +uniform bool isReflectionMapped; uniform bool isInverted; // lights @@ -48,6 +51,17 @@ uniform Light light[N_LIGHTS]; out vec4 color_out; +vec3 reflection(vec3 basecolor, vec3 nnormal) { + vec3 up = normalize(vec3(MVnormal * vec4(vec3(0.0, 0.0, 1.0), 1.0))); + vec3 north = normalize(vec3(MVnormal * vec4(vec3(1.0, 0.0, 0.0), 1.0))); + float u = acos(dot(reflect(normalize(vertex), nnormal), north)) / -3.141592; + float v = acos(dot(reflect(normalize(vertex), nnormal), up )) / -3.141592; + vec3 reflection = texture(reflectionTexture, vec2(u, v)).rgb; + return (reflexiveness < 0) + ? basecolor * mix(vec3(0.0), reflection, -reflexiveness) + : mix(basecolor, reflection, reflexiveness); +} + vec3 phong(vec3 basecolor) { vec3 nnormal; // normalized normal if (isNormalMapped) { @@ -117,6 +131,10 @@ vec3 phong(vec3 basecolor) { } basecolor *= (emissive_color + diffuse_component); + + if (isReflectionMapped) + basecolor = reflection(basecolor, nnormal); + return basecolor + specular_component; } @@ -126,7 +144,11 @@ void main() { if (isTextured) c *= texture(diffuseTexture, UV); if (isInverted) c.rgb = 1 - c.rgb; if (isIlluminated) c.rgb = phong(c.rgb); - else c.rgb *= diffuse_color; + else{ + c.rgb *= diffuse_color; + if (isReflectionMapped) + c.rgb = reflection(c.rgb, normalize(normal)); + } //c.rgb = diffuse_color; //c.rgb = emissive_color; //c.rgb = specular_color; diff --git a/res/shaders/simple.vert b/res/shaders/simple.vert index 8ea91c4..039fb02 100644 --- a/res/shaders/simple.vert +++ b/res/shaders/simple.vert @@ -10,6 +10,7 @@ in layout(location = 5) vec3 bitangent; layout(binding = 0) uniform sampler2D diffuseTexture; layout(binding = 1) uniform sampler2D normalTexture; layout(binding = 2) uniform sampler2D displacementTexture; +layout(binding = 3) uniform sampler2D reflectionTexture; uniform float displacementCoefficient; uniform mat4 MVP; diff --git a/src/gamelogic.cpp b/src/gamelogic.cpp index 58f086e..78431b0 100644 --- a/src/gamelogic.cpp +++ b/src/gamelogic.cpp @@ -72,6 +72,8 @@ PNGImage t_cobble_diff = loadPNGFile("../res/textures/cobble_diff.png"); PNGImage t_cobble_normal = loadPNGFile("../res/textures/cobble_normal.png"); PNGImage t_plain_diff = loadPNGFile("../res/textures/plain_diff.png"); PNGImage t_plain_normal = loadPNGFile("../res/textures/plain_normal.png", true); +PNGImage t_reflection = loadPNGFile("../res/textures/reflection_field.png"); +PNGImage t_reflection2 = loadPNGFile("../res/textures/reflection_blurry.png"); PNGImage t_perlin = makePerlinNoisePNG(256, 256, 0.05/16); @@ -363,6 +365,7 @@ void renderNode(SceneNode* node, Gloom::Shader* parent_shader = default_shader) if (node->isTextured) glBindTextureUnit(0, node->diffuseTextureID); if (node->isNormalMapped) glBindTextureUnit(1, node->normalTextureID); if (node->isDisplacementMapped) glBindTextureUnit(2, node->displacementTextureID); + if (node->isReflectionMapped) glBindTextureUnit(3, node->reflectionTextureID); glBindVertexArray(node->vertexArrayObjectID); glDrawElements(GL_TRIANGLES, node->VAOIndexCount, GL_UNSIGNED_INT, nullptr); } diff --git a/src/sceneGraph.hpp b/src/sceneGraph.hpp index 4c90eb8..769cb00 100644 --- a/src/sceneGraph.hpp +++ b/src/sceneGraph.hpp @@ -57,6 +57,7 @@ struct SceneNode { isTextured = false; isNormalMapped = false; isDisplacementMapped = false; + isReflectionMapped = false; } if (diffuse) { @@ -79,8 +80,16 @@ struct SceneNode { displacementTextureID = cache[displacement]; isDisplacementMapped = true; } + + if (reflection) { + if (cache.find(reflection) == cache.end()) + cache[reflection] = generateTexture(*reflection); + reflectionTextureID = cache[reflection]; + isReflectionMapped = true; + } } void setMaterial(const Material& mat, bool recursive=false) { + reflexiveness = mat.reflexiveness; if (!mat.ignore_diffuse) diffuse_color = mat.diffuse_color; if (!mat.ignore_emissive) emissive_color = mat.emissive_color; if (!mat.ignore_specular) specular_color = mat.specular_color; @@ -121,6 +130,7 @@ struct SceneNode { // textures and materials float opacity = 1.0; float shininess = 1.0; // specular power + float reflexiveness = 0.0; // 0 is no reflection, 1 is a mirror. Negative value will have it multiply with base instead vec3 diffuse_color = vec3(1.0); vec3 emissive_color = vec3(0.5); vec3 specular_color = vec3(0.2); @@ -129,12 +139,14 @@ struct SceneNode { uint normalTextureID; uint displacementTextureID; float displacementCoefficient = 0.1; // in units + uint reflectionTextureID; // shader flags bool isTextured = false; bool isVertexColored = false; bool isNormalMapped = false; bool isDisplacementMapped = false; + bool isReflectionMapped = false; bool isIlluminated = true; bool isInverted = false;