From: Luke Lau Date: Thu, 8 Nov 2018 02:57:01 +0000 (+0000) Subject: Reflection X-Git-Tag: cs7gv3-a3~22 X-Git-Url: https://git.lukelau.me/?p=opengl.git;a=commitdiff_plain;h=8abaf8f77191e1c660def0832d8036a8b4639ba8 Reflection --- diff --git a/.gitignore b/.gitignore index bc1c2f2..de0f0b8 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ bin *.log _minted-report .vim +*.blend1 diff --git a/main.cpp b/main.cpp index 613d679..4dd4e60 100644 --- a/main.cpp +++ b/main.cpp @@ -23,7 +23,7 @@ using namespace std; GLuint lightVao; -Program *textureProg, *plainProg; +Program *textureProg, *plainProg, *reflectProg; Skybox *skybox; glm::vec3 camPos = glm::vec3(0.0f, 0.0f, 0.0f); @@ -31,8 +31,8 @@ glm::vec3 camFront = glm::vec3(0.0f, 0.0f, 1.0f); glm::vec3 camUp = glm::vec3(0.0f, 1.0f, 0.0f); float yaw = 1.57, pitch = 0; bool doScale, doRotate, doTranslate; -Model *chest; -glm::vec3 lightPos(0); +Model *chest, *mirrorCube; +glm::vec3 lightPos(3); const int WIDTH = 800, HEIGHT = 600; const float ASPECT = (float)WIDTH / (float)HEIGHT; @@ -88,8 +88,6 @@ void display() { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); float d = (float)glutGet(GLUT_ELAPSED_TIME) * 0.001f; - skybox->draw(projMat(), viewMat()); - glm::vec4 lightColor(1, 1, 1, 1); drawLight(d, lightPos, lightColor); @@ -98,10 +96,10 @@ void display() { setProjectionAndViewUniforms(textureProg->progId); setLightColorAndPos(textureProg->progId, lightPos, lightColor); - Model::Node *top = chest->find("top"); - top->model = glm::translate(glm::mat4(1), glm::vec3(0, 1, -1)); - top->model = glm::rotate(top->model, sin(d / 2.5f) * 0.5f, glm::vec3(1, 0, 0)); - top->model = glm::translate(top->model, glm::vec3(0, -1, 1)); + /* Model::Node *top = chest->find("top"); */ + /* top->model = glm::translate(glm::mat4(1), glm::vec3(0, 1, -1)); */ + /* top->model = glm::rotate(top->model, sin(d / 2.5f) * 0.5f, glm::vec3(1, 0, 0)); */ + /* top->model = glm::translate(top->model, glm::vec3(0, -1, 1)); */ /* Model::Node *jewels = chest->find("jewels"); */ /* jewels->model = glm::scale(glm::mat4(1), glm::vec3((sin(d) + 1.2f) / 2.f)); */ @@ -114,8 +112,11 @@ void display() { /* Model::Node *key = chest->find("key"); */ /* key->model = glm::translate(glm::mat4(1), glm::vec3(0, 0, sin(d))); */ - /* chest->getRoot()->model = glm::translate(glm::mat4(1), lightPos); */ - chest->draw(); + /* chest->draw(); */ + + mirrorCube->draw(); + + skybox->draw(projMat(), viewMat()); glutSwapBuffers(); } @@ -136,29 +137,11 @@ void setupLightBuffers(GLuint progId) { glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, 0); } -void validateProgram(GLuint progId) { - glValidateProgram(progId); - - GLint success; - glGetProgramiv(progId, GL_VALIDATE_STATUS, &success); - if (!success) { - GLchar log[1024]; - glGetProgramInfoLog(progId, sizeof(log), NULL, log); - fprintf(stderr, "error: %s\n", log); - exit(1); - } -} - void init() { plainProg = new Program("plainvertex.glsl", "plainfrag.glsl"); glUseProgram(plainProg->progId); setupLightBuffers(plainProg->progId); - validateProgram(plainProg->progId); - - textureProg = new Program("texturevertex.glsl", "texturefrag.glsl"); - glUseProgram(textureProg->progId); - - chest = new Model("models/chest.dae", *textureProg); + plainProg->validate(); std::vector faces = { "models/skybox/right.jpg", @@ -170,6 +153,11 @@ void init() { }; skybox = new Skybox(faces); + textureProg = new Program("texturevertex.glsl", "texturefrag.glsl"); + /* chest = new Model("models/chest.dae", *textureProg, *skybox); */ + + mirrorCube = new Model("models/mirrorCube.dae", *textureProg, *skybox); + glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); } diff --git a/material.cpp b/material.cpp index 0e655a1..49af1d4 100644 --- a/material.cpp +++ b/material.cpp @@ -7,17 +7,20 @@ Material::Material(const aiMaterial &ai, GLuint progId): progId(progId) { ai.GetTexture(aiTextureType_DIFFUSE, 0, &path); diffuseMap = new Texture(std::string(path.C_Str())); } + if (ai.GetTextureCount(aiTextureType_SPECULAR) > 0) { aiString path; ai.GetTexture(aiTextureType_SPECULAR, 0, &path); specularMap = new Texture(std::string(path.C_Str())); } + if (ai.GetTextureCount(aiTextureType_NORMALS) > 0) { aiString path; ai.GetTexture(aiTextureType_NORMALS, 0, &path); normalMap = new Texture(std::string(path.C_Str())); } ai.Get(AI_MATKEY_SHININESS, shininess); + ai.Get(AI_MATKEY_REFLECTIVITY, reflectivity); ai.Get(AI_MATKEY_COLOR_AMBIENT, ambient); ai.Get(AI_MATKEY_COLOR_DIFFUSE, diffuse); ai.Get(AI_MATKEY_COLOR_SPECULAR, specular); @@ -36,23 +39,20 @@ void Material::bind() const { glUniform4f(glGetUniformLocation(progId, "material.diffuse"), diffuse.r, diffuse.g, diffuse.b, diffuse.a); glUniform4f(glGetUniformLocation(progId, "material.specular"), specular.r, specular.g, specular.b, specular.a); glUniform1f(glGetUniformLocation(progId, "material.shininess"), shininess); + glUniform1f(glGetUniformLocation(progId, "material.reflectivity"), reflectivity); glUniform1i(glGetUniformLocation(progId, "material.hasTexture"), diffuseMap != nullptr); glUniform1i(glGetUniformLocation(progId, "material.hasSpecularMap"), specularMap != nullptr); glUniform1i(glGetUniformLocation(progId, "material.hasNormalMap"), normalMap != nullptr); - if (diffuseMap) { - glUniform1i(glGetUniformLocation(progId, "material.diffuseMap"), 0); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, diffuseMap->texId); - } - if (specularMap) { - glUniform1i(glGetUniformLocation(progId, "material.specularMap"), 1); - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, specularMap->texId); - } - if (normalMap) { - glUniform1i(glGetUniformLocation(progId, "material.normalMap"), 2); + glUniform1i(glGetUniformLocation(progId, "material.diffuseMap"), 2); glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, normalMap->texId); - } + if (diffuseMap) glBindTexture(GL_TEXTURE_2D, diffuseMap->texId); + + glUniform1i(glGetUniformLocation(progId, "material.specularMap"), 3); + glActiveTexture(GL_TEXTURE3); + if (specularMap) glBindTexture(GL_TEXTURE_2D, specularMap->texId); + + glUniform1i(glGetUniformLocation(progId, "material.normalMap"), 4); + glActiveTexture(GL_TEXTURE4); + if (normalMap) glBindTexture(GL_TEXTURE_2D, normalMap->texId); } diff --git a/material.hpp b/material.hpp index 06cd2d0..0fb6f5d 100644 --- a/material.hpp +++ b/material.hpp @@ -13,7 +13,7 @@ class Material { private: GLuint progId; aiColor4D ambient, diffuse, specular; - ai_real shininess; + ai_real shininess, reflectivity; struct Texture { Texture(const std::string &file); diff --git a/model.cpp b/model.cpp index 524b913..c9ecdc1 100644 --- a/model.cpp +++ b/model.cpp @@ -1,4 +1,5 @@ #include "model.hpp" +#include "error.hpp" #include #include #include @@ -25,8 +26,8 @@ Model::Mesh::Mesh(const aiMesh *aiMesh, GLuint progId) { aiVector3D b = aiMesh->mBitangents[i]; bitangents.push_back(glm::vec3(b.x, b.y, b.z)); } else { - tangents.push_back(glm::vec3(0)); - bitangents.push_back(glm::vec3(0)); + std::cerr << "Missing tangents: make sure blender has UV maps" << std::endl; + exit(1); } // check for texture coord set 0 if (aiMesh->HasTextureCoords(0)) { @@ -59,13 +60,13 @@ Model::Mesh::Mesh(const aiMesh *aiMesh, GLuint progId) { GLuint vertexVbo = vbos[0], normalVbo = vbos[1], texCoordVbo = vbos[2], indicesVbo = vbos[3]; GLuint tangentVbo = vbos[4], bitangentVbo = vbos[5]; - GLuint posLoc = glGetAttribLocation(progId, "vPosition"); + GLuint posLoc = glGetAttribLocation(progId, "pos"); glBindBuffer(GL_ARRAY_BUFFER, vertexVbo); glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), &vertices[0], GL_STATIC_DRAW); glEnableVertexAttribArray(posLoc); glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, 0); - GLuint normalLoc = glGetAttribLocation(progId, "vNormal"); + GLuint normalLoc = glGetAttribLocation(progId, "unscaledNormal"); glBindBuffer(GL_ARRAY_BUFFER, normalVbo); glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(glm::vec3), &normals[0], GL_STATIC_DRAW); glEnableVertexAttribArray(normalLoc); @@ -91,7 +92,7 @@ Model::Mesh::Mesh(const aiMesh *aiMesh, GLuint progId) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesVbo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint), &indices[0], GL_STATIC_DRAW); -}; +} Model::Node::Node(const aiNode &node, GLuint progId): ai(node), progId(progId) { for (int i = 0; i < node.mNumMeshes; i++) { @@ -113,6 +114,7 @@ glm::mat4 aiMatrixToMat4(aiMatrix4x4 from) { void Model::Node::draw( const std::vector &meshes, const std::vector &materials, + const Skybox skybox, glm::mat4 parentTrans = glm::mat4(1)) const { GLuint modelLoc = glGetUniformLocation(progId, "model"); @@ -125,14 +127,20 @@ void Model::Node::draw( const std::vector &meshes, Material material = materials[mesh.materialIndex]; material.bind(); + glUniform1i(glGetUniformLocation(progId, "skybox"), 5); + glActiveTexture(GL_TEXTURE5); + glBindTexture(GL_TEXTURE_CUBE_MAP, skybox.getTexture()); + glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(m)); glDrawElements(GL_TRIANGLES, mesh.numIndices, GL_UNSIGNED_INT, 0); } - for (Node *child: children) child->draw(meshes, materials, m); + for (Node *child: children) child->draw(meshes, materials, skybox, m); } -Model::Model(const std::string &path, Program p): program(p) { +Model::Model(const std::string &path, Program p, Skybox s): program(p), skybox(s) { + glUseProgram(p.progId); + const aiScene *scene = importer.ReadFile(path, aiProcess_Triangulate | aiProcess_CalcTangentSpace | aiProcess_GenNormals); if (!scene) { @@ -155,7 +163,8 @@ Model::Model(const std::string &path, Program p): program(p) { void Model::draw() const { glUseProgram(program.progId); - root->draw(meshes, materials); + root->draw(meshes, materials, skybox); + program.validate(); } Model::Node* Model::find(const std::string &name) { diff --git a/model.hpp b/model.hpp index de8e27f..e0c8a2d 100644 --- a/model.hpp +++ b/model.hpp @@ -9,6 +9,7 @@ #include #include "material.hpp" #include "program.hpp" +#include "skybox.hpp" class Model { @@ -19,13 +20,13 @@ class Model { }; public: - Model(const std::string &path, Program p); + Model(const std::string &path, Program p, Skybox s); void draw() const; class Node { public: Node(const aiNode &aiNode, GLuint progId); - void draw(const std::vector &meshes, const std::vector &materials, glm::mat4 parentModel) const; + void draw(const std::vector &meshes, const std::vector &materials, const Skybox s, glm::mat4 parentModel) const; const std::vector &getChildren() const { return children; } Node* findNode(const aiNode &aiNode); glm::mat4 model = glm::mat4(1); @@ -42,6 +43,7 @@ class Model { private: const Program program; + const Skybox skybox; std::vector meshes; Node *root; diff --git a/models/mirrorCube.blend b/models/mirrorCube.blend new file mode 100644 index 0000000..77d1d4e Binary files /dev/null and b/models/mirrorCube.blend differ diff --git a/models/mirrorCube.dae b/models/mirrorCube.dae new file mode 100644 index 0000000..d84bd4b --- /dev/null +++ b/models/mirrorCube.dae @@ -0,0 +1,235 @@ + + + + + Blender User + Blender 2.79.0 commit date:2018-03-22, commit time:14:10, hash:f4dc9f9 + + 2018-11-08T02:49:10 + 2018-11-08T02:49:10 + + Z_UP + + + + + + + 49.13434 + 1.777778 + 0.1 + 100 + + + + + + 0 + 0 + 0 + + + + + + + + + 1 1 1 + 1 + 0 + 0.00111109 + + + + + 0 + 0 + 8192 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + 1 + 29.99998 + 75 + 0.15 + 1 + 0 + 1 + 2 + 1.000799 + 30.002 + 1 + 3 + 0.04999995 + 2880 + 3 + 1 + 0 + 0 + 2 + 1 + 1 + 1 + 0 + 1 + 0.1 + 0.1 + 1 + 0.000999987 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 2 + 1 + 1 + 1 + 1 + 0 + + + + + + + brickwall_normal.jpg + + + + + + + + brickwall_normal_jpg + + + + + brickwall_normal_jpg-surface + + + + + + 0 0 0 1 + + + 0 0 0 1 + + + 0.64 0.005287599 0.4252137 1 + + + 0.5 0.5 0.5 1 + + + 50 + + + 1 1 1 1 + + + 1 + + + 1 + + + + + + + + + + + + + + + + + + + + + + + 1 1 -1 1 -1 -1 -1 -0.9999998 -1 -0.9999997 1 -1 1 0.9999995 1 0.9999994 -1.000001 1 -1 -0.9999997 1 -1 1 1 + + + + + + + + + + 0 0 -1 0 0 1 1 0 -2.38419e-7 0 -1 -4.76837e-7 -1 2.38419e-7 -1.49012e-7 2.68221e-7 1 2.38419e-7 0 0 -1 0 0 1 1 -5.96046e-7 3.27825e-7 -4.76837e-7 -1 0 -1 2.38419e-7 -1.19209e-7 2.08616e-7 1 0 + + + + + + + + + + 0 0 1 1 0 1 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 1 1 0 1 1 0 0 1 0 0 0 0 1 0 1 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 0 0 1 0 1 1 1 0 1 1 0 1 + + + + + + + + + + + + + + +

0 0 0 2 0 1 3 0 2 7 1 3 5 1 4 4 1 5 4 2 6 1 2 7 0 2 8 5 3 9 2 3 10 1 3 11 2 4 12 7 4 13 3 4 14 0 5 15 7 5 16 4 5 17 0 6 18 1 6 19 2 6 20 7 7 21 6 7 22 5 7 23 4 8 24 5 8 25 1 8 26 5 9 27 6 9 28 2 9 29 2 10 30 6 10 31 7 10 32 0 11 33 3 11 34 7 11 35

+
+
+
+
+ + + + + 0.6859207 -0.3240135 0.6515582 7.481132 0.7276763 0.3054208 -0.6141704 -6.50764 0 0.8953956 0.4452714 5.343665 0 0 0 1 + + + + -0.2908646 -0.7711008 0.5663932 4.076245 0.9551712 -0.1998834 0.2183912 1.005454 -0.05518906 0.6045247 0.7946723 5.903862 0 0 0 1 + + + + 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/program.cpp b/program.cpp index b1f2ede..d6adf06 100644 --- a/program.cpp +++ b/program.cpp @@ -48,3 +48,17 @@ Program::Program(const string vertexShader, const string fragmentShader) { exit(1); } } + +void Program::validate() const { + glValidateProgram(progId); + + GLint success; + glGetProgramiv(progId, GL_VALIDATE_STATUS, &success); + if (!success) { + GLchar log[1024]; + glGetProgramInfoLog(progId, sizeof(log), NULL, log); + fprintf(stderr, "error: %s\n", log); + exit(1); + } +} + diff --git a/program.hpp b/program.hpp index 0436338..3fa8879 100644 --- a/program.hpp +++ b/program.hpp @@ -5,6 +5,7 @@ class Program { public: Program(const std::string vert, const std::string frag); + void validate() const; GLuint progId; }; #endif diff --git a/reflectfrag.glsl b/reflectfrag.glsl new file mode 100644 index 0000000..9506153 --- /dev/null +++ b/reflectfrag.glsl @@ -0,0 +1,15 @@ +#version 330 + +in vec3 fragPos; +in vec3 normal; + +uniform vec3 viewPos; +uniform samplerCube skybox; + +out vec4 fragColor; + +void main() { + vec3 I = normalize(fragPos - viewPos); + vec3 R = reflect(I, normalize(normal)); + fragColor = vec4(texture(skybox, R).rgb, 1); +} diff --git a/reflectvert.glsl b/reflectvert.glsl new file mode 100644 index 0000000..43a4d3d --- /dev/null +++ b/reflectvert.glsl @@ -0,0 +1,15 @@ +#version 330 + +in vec3 pos; +in vec3 unscaledNormal; + +out vec3 fragPos; +out vec3 normal; + +uniform mat4 model, view, projection; + +void main() { + normal = mat3(inverse(transpose(model))) * unscaledNormal; + fragPos = vec3(model * vec4(pos, 1)); + gl_Position = projection * view * vec4(fragPos, 1); +} diff --git a/skybox.cpp b/skybox.cpp index bd097cb..79ce9d0 100644 --- a/skybox.cpp +++ b/skybox.cpp @@ -1,13 +1,12 @@ #include "shapes.hpp" #include "skybox.hpp" #include "image.hpp" -#include #include Skybox::Skybox(const std::vector faces): program("skyboxvert.glsl", "skyboxfrag.glsl") { - glUseProgram(program.progId); glGenTextures(1, &texId); glBindTexture(GL_TEXTURE_CUBE_MAP, texId); + glDepthFunc(GL_LEQUAL); int width, height, numChans; for (int i = 0; i < faces.size(); i++) { @@ -30,6 +29,9 @@ Skybox::Skybox(const std::vector faces): program("skyboxvert.glsl", auto vertices = cube(); + //reverse so facing inside out + std::reverse(vertices.begin(), vertices.end()); + glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), &vertices[0], GL_STATIC_DRAW); @@ -37,26 +39,11 @@ Skybox::Skybox(const std::vector faces): program("skyboxvert.glsl", glEnableVertexAttribArray(posLoc); glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, 0); } -void validatePrograms(GLuint progId) { - glValidateProgram(progId); - - GLint success; - glGetProgramiv(progId, GL_VALIDATE_STATUS, &success); - if (!success) { - GLchar log[1024]; - glGetProgramInfoLog(progId, sizeof(log), NULL, log); - fprintf(stderr, "error: %s\n", log); - exit(1); - } -} void Skybox::draw(glm::mat4 proj, glm::mat4 view) const { glUseProgram(program.progId); - glDepthMask(GL_FALSE); - glDisable(GL_CULL_FACE); glBindVertexArray(vao); - validatePrograms(program.progId); GLuint projLoc = glGetUniformLocation(program.progId, "projection"); glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(proj)); @@ -65,8 +52,11 @@ void Skybox::draw(glm::mat4 proj, glm::mat4 view) const { view = glm::mat4(glm::mat3(view)); glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view)); + glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_CUBE_MAP, texId); glDrawArrays(GL_TRIANGLES, 0, 36); - glEnable(GL_CULL_FACE); - glDepthMask(GL_TRUE); +} + +GLuint Skybox::getTexture() const { + return texId; } diff --git a/skybox.hpp b/skybox.hpp index f1ac4ee..759ce7a 100644 --- a/skybox.hpp +++ b/skybox.hpp @@ -1,3 +1,6 @@ +#ifndef SKYBOX_HPP +#define SKYBOX_HPP + #include #include #include @@ -7,7 +10,10 @@ class Skybox { public: Skybox(const std::vector faces); void draw(glm::mat4 proj, glm::mat4 view) const; + GLuint getTexture() const; private: GLuint texId, vao; const Program program; }; + +#endif diff --git a/skyboxvert.glsl b/skyboxvert.glsl index f1ba729..4946c73 100644 --- a/skyboxvert.glsl +++ b/skyboxvert.glsl @@ -8,5 +8,6 @@ uniform mat4 view; void main() { texCoords = pos; - gl_Position = projection * view * vec4(pos, 1); + vec4 fragPos = projection * view * vec4(pos, 1); + gl_Position = fragPos.xyww; } diff --git a/texturefrag.glsl b/texturefrag.glsl index 94bda7f..2a3de55 100644 --- a/texturefrag.glsl +++ b/texturefrag.glsl @@ -8,6 +8,8 @@ struct Material { sampler2D specularMap; float shininess; + float reflectivity; + bool hasTexture; bool hasSpecularMap; @@ -15,7 +17,7 @@ struct Material { bool hasNormalMap; }; -in vec3 defNormal; +in vec3 defNormal, worldNormal; in vec2 texCoord; // These are all in tangent space @@ -23,47 +25,50 @@ 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; -void main() { +vec4 reflection(vec3 normal) { + vec3 I = normalize(worldFragPos - worldViewPos); + vec3 R = reflect(I, normalize(normal)); + 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; - } vec3 lightDir = normalize(lightPos - fragPos); - vec4 diffTex; - if (material.hasTexture) - diffTex = texture(material.diffuseMap, texCoord); - else - diffTex = vec4(1); + vec4 diffTex = texture(material.diffuseMap, texCoord); + if (!material.hasTexture) + diffTex = material.diffuse; + + diffTex = mix(diffTex, reflection(worldNormal), material.reflectivity); vec4 ambient = material.ambient * diffTex; - vec4 diffuse = max(0, dot(lightDir, normal)) * material.diffuse * diffTex; + vec4 diffuse = max(0, dot(lightDir, normal)) * diffTex; vec3 viewDir = normalize(viewPos - fragPos); vec3 reflectDir = reflect(-lightDir, normal); - vec4 specTex; - if (material.hasSpecularMap) - specTex = texture(material.specularMap, texCoord); - else - specTex = vec4(1); + vec4 specTex = texture(material.specularMap, texCoord); + if (!material.hasSpecularMap) + specTex = material.specular; - vec4 specular = pow(max(0, dot(viewDir, reflectDir)), material.shininess) * material.specular * specTex; + vec4 specular = pow(max(0, dot(viewDir, reflectDir)), material.shininess) * specTex; - vec4 lighting = (ambient + diffuse + specular) * lightColor; + FragColor = (ambient + diffuse + specular) * lightColor; - FragColor = lighting; } diff --git a/texturevertex.glsl b/texturevertex.glsl index 684b9b9..06535cf 100644 --- a/texturevertex.glsl +++ b/texturevertex.glsl @@ -1,7 +1,7 @@ #version 330 -in vec3 vPosition; +in vec3 pos; in vec4 vColor; -in vec3 vNormal; +in vec3 unscaledNormal; in vec3 tangent; in vec3 bitangent; in vec2 vTexCoord; @@ -10,31 +10,37 @@ uniform mat4 model; uniform mat4 view; uniform mat4 projection; -out vec3 defNormal; +out vec3 defNormal, worldNormal; out vec2 texCoord; uniform vec3 vLightPos; uniform vec3 vViewPos; -out vec3 lightPos; -out vec3 viewPos; -out vec3 fragPos; +out vec3 lightPos, viewPos, fragPos; +out vec3 worldViewPos, worldFragPos; void main() { - vec4 pos = model * vec4(vPosition, 1.f); + vec4 worldPos = model * vec4(pos, 1.f); texCoord = vTexCoord; //tangent space stuff vec3 T = normalize(vec3(model * vec4(tangent, 0.0))); vec3 B = normalize(vec3(model * vec4(bitangent, 0.0))); - vec3 N = normalize(vec3(model * vec4(vNormal, 0.0))); + vec3 N = normalize(vec3(model * vec4(unscaledNormal, 0.0))); // convert TBN to world->tangent space mat3 TBN = transpose(mat3(T, B, N)); lightPos = TBN * vLightPos; viewPos = TBN * vViewPos; - fragPos = TBN * vec3(pos); - defNormal = TBN * mat3(transpose(inverse(model))) * vNormal; + fragPos = TBN * vec3(worldPos); - gl_Position = projection * view * pos; + worldViewPos = vViewPos; + worldFragPos = vec3(worldPos); + + vec3 normal = mat3(transpose(inverse(model))) * unscaledNormal; + + defNormal = TBN * normal; + worldNormal = normal; + + gl_Position = projection * view * worldPos; }