diff --git a/data/shaders/objectref_pass2.frag b/data/shaders/objectref_pass2.frag index 3fd35d295..e2049a971 100644 --- a/data/shaders/objectref_pass2.frag +++ b/data/shaders/objectref_pass2.frag @@ -10,11 +10,11 @@ in vec2 uv; void main(void) { vec4 color = texture2D(Albedo, uv); - if (color.a < 0.5) discard; + if (color.a < 0.5) discard; vec2 tc = gl_FragCoord.xy / screen; vec3 DiffuseComponent = texture2D(DiffuseMap, tc).xyz; vec3 SpecularComponent = texture2D(SpecularMap, tc).xyz; - float ao = texture2D(SSAO, tc).x; - vec3 LightFactor = ao * ambient + DiffuseComponent + SpecularComponent * (1. - color.a); + float ao = texture2D(SSAO, tc).x; + vec3 LightFactor = ao * ambient + DiffuseComponent + SpecularComponent; gl_FragColor = vec4(color.xyz * LightFactor, 1.); } diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index 1530556fe..c9a22ed15 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -302,6 +302,7 @@ namespace MeshShader GLuint ObjectRefPass1Shader::Program; GLuint ObjectRefPass1Shader::attrib_position; GLuint ObjectRefPass1Shader::attrib_normal; + GLuint ObjectRefPass1Shader::attrib_texcoord; GLuint ObjectRefPass1Shader::uniform_MVP; GLuint ObjectRefPass1Shader::uniform_TIMV; GLuint ObjectRefPass1Shader::uniform_tex; @@ -312,6 +313,7 @@ namespace MeshShader Program = LoadProgram(file_manager->getAsset("shaders/objectref_pass1.vert").c_str(), file_manager->getAsset("shaders/objectref_pass1.frag").c_str()); attrib_position = glGetAttribLocation(Program, "Position"); attrib_normal = glGetAttribLocation(Program, "Normal"); + attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); uniform_TIMV = glGetUniformLocation(Program, "TransposeInverseModelView"); uniform_tex = glGetUniformLocation(Program, "tex"); @@ -769,4 +771,4 @@ namespace FullScreenShader uniform_ipvmat = glGetUniformLocation(Program, "ipvmat"); vao = createVAO(Program); } -} \ No newline at end of file +} diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 37b7e7952..4dfd6313d 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -41,7 +41,7 @@ class ObjectRefPass1Shader { public: static GLuint Program; - static GLuint attrib_position, attrib_normal; + static GLuint attrib_position, attrib_normal, attrib_texcoord; static GLuint uniform_MVP, uniform_TIMV, uniform_tex; static void init(); diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index c6160843e..9ccf3f0ec 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -198,6 +198,45 @@ void STKMesh::drawFirstPass(const GLMesh &mesh) irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getMainSetup(), false, false); } +void STKMesh::drawObjectRefPass1(const GLMesh &mesh) +{ + irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH), false, false); + + glStencilFunc(GL_ALWAYS, 0, ~0); + glEnable(GL_DEPTH_TEST); + glDisable(GL_ALPHA_TEST); + glDepthMask(GL_TRUE); + glDisable(GL_BLEND); + GLenum ptype = mesh.PrimitiveType; + GLenum itype = mesh.IndexType; + size_t count = mesh.IndexCount; + + ModelViewProjectionMatrix = irr_driver->getVideoDriver()->getTransform(video::ETS_PROJECTION); + ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); + ModelViewProjectionMatrix *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); + TransposeInverseModelView = irr_driver->getVideoDriver()->getTransform(video::ETS_VIEW); + TransposeInverseModelView *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); + TransposeInverseModelView.makeInverse(); + TransposeInverseModelView = TransposeInverseModelView.getTransposed(); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mesh.textures[0]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glUseProgram(MeshShader::ObjectRefPass1Shader::Program); + MeshShader::ObjectRefPass1Shader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, 0); + + glBindVertexArray(mesh.vao_first_pass); + glDrawElements(ptype, count, itype, 0); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glStencilFunc(GL_ALWAYS, 1, ~0); + irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getMainSetup(), false, false); +} + void STKMesh::drawNormalPass(const GLMesh &mesh) { irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH), false, false); @@ -339,6 +378,41 @@ void STKMesh::drawSplatting(const GLMesh &mesh) irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); } +void STKMesh::drawObjectRefPass2(const GLMesh &mesh) +{ + irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); + + glEnable(GL_DEPTH_TEST); + glDisable(GL_ALPHA_TEST); + glDepthMask(GL_FALSE); + glDisable(GL_BLEND); + GLenum ptype = mesh.PrimitiveType; + GLenum itype = mesh.IndexType; + size_t count = mesh.IndexCount; + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mesh.textures[0]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_TMP1))->getOpenGLTextureName()); + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_TMP2))->getOpenGLTextureName()); + glActiveTexture(GL_TEXTURE3); + glBindTexture(GL_TEXTURE_2D, static_cast(irr_driver->getRTT(RTT_SSAO))->getOpenGLTextureName()); + + glUseProgram(MeshShader::ObjectRefPass2Shader::Program); + MeshShader::ObjectRefPass2Shader::setUniforms(ModelViewProjectionMatrix, 0, 1, 2, 3); + + glBindVertexArray(mesh.vao_second_pass); + glDrawElements(ptype, count, itype, 0); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + irr_driver->getVideoDriver()->setRenderTarget(irr_driver->getRTT(RTT_COLOR), false, false); +} void STKMesh::drawSecondPass(const GLMesh &mesh) { @@ -404,6 +478,8 @@ void STKMesh::draw(const GLMesh &mesh, video::E_MATERIAL_TYPE type) case 0: if (type == irr_driver->getShader(ES_NORMAL_MAP)) drawNormalPass(mesh); + else if (type == irr_driver->getShader(ES_OBJECTPASS_REF)) + drawObjectRefPass1(mesh); else drawFirstPass(mesh); break; @@ -412,6 +488,8 @@ void STKMesh::draw(const GLMesh &mesh, video::E_MATERIAL_TYPE type) drawSphereMap(mesh); else if (type == irr_driver->getShader(ES_SPLATTING)) drawSplatting(mesh); + else if (type == irr_driver->getShader(ES_OBJECTPASS_REF)) + drawObjectRefPass2(mesh); else drawSecondPass(mesh); break; @@ -437,6 +515,8 @@ static bool isObject(video::E_MATERIAL_TYPE type) { if (type == irr_driver->getShader(ES_OBJECTPASS)) return true; + if (type == irr_driver->getShader(ES_OBJECTPASS_REF)) + return true; if (type == irr_driver->getShader(ES_NORMAL_MAP)) return true; if (type == irr_driver->getShader(ES_SPHERE_MAP)) @@ -455,6 +535,11 @@ static void initvaostate(GLMesh &mesh, video::E_MATERIAL_TYPE type) mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::NormalMapShader::attrib_position, MeshShader::NormalMapShader::attrib_texcoord, -1, -1, MeshShader::NormalMapShader::attrib_tangent, MeshShader::NormalMapShader::attrib_bitangent, mesh.Stride); } + else if (type == irr_driver->getShader(ES_OBJECTPASS_REF)) + { + mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, + MeshShader::ObjectPass1Shader::attrib_position, MeshShader::ObjectRefPass1Shader::attrib_texcoord, -1, MeshShader::ObjectPass1Shader::attrib_normal, -1, -1, mesh.Stride); + } else { mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, @@ -471,6 +556,12 @@ static void initvaostate(GLMesh &mesh, video::E_MATERIAL_TYPE type) mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::SplattingShader::attrib_position, MeshShader::SplattingShader::attrib_texcoord, MeshShader::SplattingShader::attrib_second_texcoord, -1, -1, -1, mesh.Stride); } + else if (type == irr_driver->getShader(ES_OBJECTPASS_REF)) + { + mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, + MeshShader::ObjectRefPass2Shader::attrib_position, MeshShader::ObjectRefPass2Shader::attrib_texcoord, -1, -1, -1, -1, mesh.Stride); + + } else { mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, diff --git a/src/graphics/stkmesh.hpp b/src/graphics/stkmesh.hpp index bfdad00af..959fff563 100644 --- a/src/graphics/stkmesh.hpp +++ b/src/graphics/stkmesh.hpp @@ -31,11 +31,13 @@ protected: // Pass 1 shader (ie shaders that outputs normals and depth) void drawFirstPass(const GLMesh &mesh); void drawNormalPass(const GLMesh &mesh); + void drawObjectRefPass1(const GLMesh &mesh); // Pass 2 shader (ie shaders that outputs final color) void drawSphereMap(const GLMesh &mesh); void drawSplatting(const GLMesh &mesh); void drawSecondPass(const GLMesh &mesh); + void drawObjectRefPass2(const GLMesh &mesh); // Pass 3 shader (glow) void drawGlow(const GLMesh &mesh, float r, float g, float b);