From 646c0dc48f8f147e7e79c2fdee5dd554d007c2bd Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 19 Sep 2014 15:31:46 -0700 Subject: [PATCH] Working on translucent model bits. --- interface/resources/shaders/model.frag | 5 +- .../resources/shaders/model_normal_map.frag | 5 +- .../shaders/model_normal_specular_map.frag | 5 +- .../resources/shaders/model_specular_map.frag | 5 +- .../resources/shaders/model_translucent.frag | 20 +++++++ interface/src/renderer/Model.cpp | 54 ++++++++++++++++--- interface/src/renderer/Model.h | 11 ++-- 7 files changed, 91 insertions(+), 14 deletions(-) create mode 100644 interface/resources/shaders/model_translucent.frag diff --git a/interface/resources/shaders/model.frag b/interface/resources/shaders/model.frag index 58a5d24463..82bc70ec46 100644 --- a/interface/resources/shaders/model.frag +++ b/interface/resources/shaders/model.frag @@ -14,13 +14,16 @@ // the diffuse texture uniform sampler2D diffuseMap; +// the alpha threshold +uniform float alphaThreshold; + // the interpolated normal varying vec4 normal; void main(void) { // set the diffuse, normal, specular data vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st); - gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, 0.5))); + gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, alphaThreshold))); gl_FragData[1] = normalize(normal) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0); gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb, gl_FrontMaterial.shininess / 128.0); } diff --git a/interface/resources/shaders/model_normal_map.frag b/interface/resources/shaders/model_normal_map.frag index 28c65f20b4..f5a1047b2b 100644 --- a/interface/resources/shaders/model_normal_map.frag +++ b/interface/resources/shaders/model_normal_map.frag @@ -17,6 +17,9 @@ uniform sampler2D diffuseMap; // the normal map texture uniform sampler2D normalMap; +// the alpha threshold +uniform float alphaThreshold; + // the interpolated normal varying vec4 interpolatedNormal; @@ -34,7 +37,7 @@ void main(void) { // set the diffuse, normal, specular data vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st); - gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, 0.5))); + gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, alphaThreshold))); gl_FragData[1] = viewNormal + vec4(0.5, 0.5, 0.5, 1.0); gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb, gl_FrontMaterial.shininess / 128.0); } diff --git a/interface/resources/shaders/model_normal_specular_map.frag b/interface/resources/shaders/model_normal_specular_map.frag index 3d4f795111..08321c0017 100644 --- a/interface/resources/shaders/model_normal_specular_map.frag +++ b/interface/resources/shaders/model_normal_specular_map.frag @@ -20,6 +20,9 @@ uniform sampler2D normalMap; // the specular map texture uniform sampler2D specularMap; +// the alpha threshold +uniform float alphaThreshold; + // the interpolated normal varying vec4 interpolatedNormal; @@ -37,7 +40,7 @@ void main(void) { // set the diffuse, normal, specular data vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st); - gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, 0.5))); + gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, alphaThreshold))); gl_FragData[1] = viewNormal + vec4(0.5, 0.5, 0.5, 1.0); gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb * texture2D(specularMap, gl_TexCoord[0].st).rgb, gl_FrontMaterial.shininess / 128.0); diff --git a/interface/resources/shaders/model_specular_map.frag b/interface/resources/shaders/model_specular_map.frag index 0c021d333c..bcf658dc15 100644 --- a/interface/resources/shaders/model_specular_map.frag +++ b/interface/resources/shaders/model_specular_map.frag @@ -17,13 +17,16 @@ uniform sampler2D diffuseMap; // the specular texture uniform sampler2D specularMap; +// the alpha threshold +uniform float alphaThreshold; + // the interpolated normal varying vec4 normal; void main(void) { // set the diffuse, normal, specular data vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st); - gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, 0.5))); + gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, alphaThreshold))); gl_FragData[1] = normalize(normal) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0); gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb * texture2D(specularMap, gl_TexCoord[0].st).rgb, gl_FrontMaterial.shininess / 128.0); diff --git a/interface/resources/shaders/model_translucent.frag b/interface/resources/shaders/model_translucent.frag new file mode 100644 index 0000000000..dbb640d3b1 --- /dev/null +++ b/interface/resources/shaders/model_translucent.frag @@ -0,0 +1,20 @@ +#version 120 + +// +// model_translucent.frag +// fragment shader +// +// Created by Andrzej Kapolka on 9/19/14. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +// the diffuse texture +uniform sampler2D diffuseMap; + +void main(void) { + // set the diffuse data + gl_FragData[0] = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].st); +} diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 56ab0c8219..3411097b49 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -58,6 +58,7 @@ ProgramObject Model::_program; ProgramObject Model::_normalMapProgram; ProgramObject Model::_specularMapProgram; ProgramObject Model::_normalSpecularMapProgram; +ProgramObject Model::_translucentProgram; ProgramObject Model::_shadowProgram; @@ -65,6 +66,7 @@ ProgramObject Model::_skinProgram; ProgramObject Model::_skinNormalMapProgram; ProgramObject Model::_skinSpecularMapProgram; ProgramObject Model::_skinNormalSpecularMapProgram; +ProgramObject Model::_skinTranslucentProgram; ProgramObject Model::_skinShadowProgram; @@ -72,12 +74,14 @@ Model::Locations Model::_locations; Model::Locations Model::_normalMapLocations; Model::Locations Model::_specularMapLocations; Model::Locations Model::_normalSpecularMapLocations; +Model::Locations Model::_translucentLocations; Model::SkinLocations Model::_skinLocations; Model::SkinLocations Model::_skinNormalMapLocations; Model::SkinLocations Model::_skinSpecularMapLocations; Model::SkinLocations Model::_skinNormalSpecularMapLocations; Model::SkinLocations Model::_skinShadowLocations; +Model::SkinLocations Model::_skinTranslucentLocations; void Model::setScale(const glm::vec3& scale) { setScaleInternal(scale); @@ -112,6 +116,7 @@ void Model::setOffset(const glm::vec3& offset) { void Model::initProgram(ProgramObject& program, Model::Locations& locations, int specularTextureUnit) { program.bind(); locations.tangent = program.attributeLocation("tangent"); + locations.alphaThreshold = program.uniformLocation("alphaThreshold"); program.setUniformValue("diffuseMap", 0); program.setUniformValue("normalMap", 1); program.setUniformValue("specularMap", specularTextureUnit); @@ -192,6 +197,14 @@ void Model::init() { initProgram(_normalSpecularMapProgram, _normalSpecularMapLocations, 2); + _translucentProgram.addShaderFromSourceFile(QGLShader::Vertex, + Application::resourcesPath() + "shaders/model.vert"); + _translucentProgram.addShaderFromSourceFile(QGLShader::Fragment, + Application::resourcesPath() + "shaders/model_translucent.frag"); + _translucentProgram.link(); + + initProgram(_translucentProgram, _translucentLocations); + _shadowProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/model_shadow.vert"); _shadowProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + "shaders/model_shadow.frag"); @@ -234,6 +247,14 @@ void Model::init() { _skinShadowProgram.link(); initSkinProgram(_skinShadowProgram, _skinShadowLocations); + + _skinTranslucentProgram.addShaderFromSourceFile(QGLShader::Vertex, + Application::resourcesPath() + "shaders/skin_model.vert"); + _skinTranslucentProgram.addShaderFromSourceFile(QGLShader::Fragment, + Application::resourcesPath() + "shaders/model_translucent.frag"); + _skinTranslucentProgram.link(); + + initSkinProgram(_skinTranslucentProgram, _skinTranslucentLocations); } } @@ -410,21 +431,31 @@ bool Model::render(float alpha, RenderMode mode) { renderMeshes(mode, false); // render translucent meshes afterwards - - renderMeshes(mode, true); + if (mode == DEFAULT_RENDER_MODE) { + Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(false, true, true); + renderMeshes(mode, true, 0.75f); + } glDisable(GL_ALPHA_TEST); + glEnable(GL_BLEND); + glDepthMask(false); + glDepthFunc(GL_LEQUAL); + //glEnable(GL_POLYGON_OFFSET_FILL); + //glPolygonOffset(-1.0f, -1.0f); Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true); + renderMeshes(mode, true, 0.0f); + + //glDisable(GL_POLYGON_OFFSET_FILL); + glDepthMask(true); + glDepthFunc(GL_LESS); glDisable(GL_CULL_FACE); if (mode == SHADOW_RENDER_MODE) { glCullFace(GL_BACK); } - glEnable(GL_BLEND); - // deactivate vertex arrays after drawing glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); @@ -1161,7 +1192,7 @@ void Model::deleteGeometry() { _blendedBlendshapeCoefficients.clear(); } -void Model::renderMeshes(RenderMode mode, bool translucent) { +void Model::renderMeshes(RenderMode mode, bool translucent, float alphaThreshold) { updateVisibleJointStates(); const FBXGeometry& geometry = _geometry->getFBXGeometry(); const QVector& networkMeshes = _geometry->getMeshes(); @@ -1193,6 +1224,12 @@ void Model::renderMeshes(RenderMode mode, bool translucent) { program = &_shadowProgram; skinProgram = &_skinShadowProgram; skinLocations = &_skinShadowLocations; + + } else if (translucent && alphaThreshold == 0.0f) { + program = &_translucentProgram; + locations = &_translucentLocations; + skinProgram = &_skinTranslucentProgram; + skinLocations = &_skinTranslucentLocations; } else if (!mesh.tangents.isEmpty()) { if (mesh.hasSpecularTexture()) { @@ -1242,6 +1279,8 @@ void Model::renderMeshes(RenderMode mode, bool translucent) { program->bind(); } + activeProgram->setUniformValue(activeLocations->alphaThreshold, alphaThreshold); + if (mesh.blendshapes.isEmpty()) { if (!(mesh.tangents.isEmpty() || mode == SHADOW_RENDER_MODE)) { activeProgram->setAttributeBuffer(activeLocations->tangent, GL_FLOAT, vertexCount * 2 * sizeof(glm::vec3), 3); @@ -1277,7 +1316,7 @@ void Model::renderMeshes(RenderMode mode, bool translucent) { for (int j = 0; j < networkMesh.parts.size(); j++) { const NetworkMeshPart& networkPart = networkMesh.parts.at(j); const FBXMeshPart& part = mesh.parts.at(j); - if (networkPart.isTranslucent() != translucent) { + if ((networkPart.isTranslucent() || part.opacity != 1.0f) != translucent) { offset += (part.quadIndices.size() + part.triangleIndices.size()) * sizeof(int); continue; } @@ -1286,7 +1325,8 @@ void Model::renderMeshes(RenderMode mode, bool translucent) { glBindTexture(GL_TEXTURE_2D, 0); } else { - glm::vec4 diffuse = glm::vec4(part.diffuseColor, Application::getInstance()->getGlowEffect()->getIntensity()); + glm::vec4 diffuse = glm::vec4(part.diffuseColor, (translucent && alphaThreshold == 0.0f) ? + part.opacity : Application::getInstance()->getGlowEffect()->getIntensity()); glm::vec4 specular = glm::vec4(part.specularColor, 1.0f); glMaterialfv(GL_FRONT, GL_AMBIENT, (const float*)&diffuse); glMaterialfv(GL_FRONT, GL_DIFFUSE, (const float*)&diffuse); diff --git a/interface/src/renderer/Model.h b/interface/src/renderer/Model.h index fbf0167844..89c47e229d 100644 --- a/interface/src/renderer/Model.h +++ b/interface/src/renderer/Model.h @@ -242,7 +242,7 @@ private: void applyNextGeometry(); void deleteGeometry(); - void renderMeshes(RenderMode mode, bool translucent); + void renderMeshes(RenderMode mode, bool translucent, float alphaThreshold = 0.5f); QVector createJointStates(const FBXGeometry& geometry); void initJointTransforms(); @@ -276,6 +276,7 @@ private: static ProgramObject _normalMapProgram; static ProgramObject _specularMapProgram; static ProgramObject _normalSpecularMapProgram; + static ProgramObject _translucentProgram; static ProgramObject _shadowProgram; @@ -283,6 +284,7 @@ private: static ProgramObject _skinNormalMapProgram; static ProgramObject _skinSpecularMapProgram; static ProgramObject _skinNormalSpecularMapProgram; + static ProgramObject _skinTranslucentProgram; static ProgramObject _skinShadowProgram; @@ -292,12 +294,14 @@ private: class Locations { public: int tangent; + int alphaThreshold; }; static Locations _locations; static Locations _normalMapLocations; static Locations _specularMapLocations; static Locations _normalSpecularMapLocations; + static Locations _translucentLocations; static void initProgram(ProgramObject& program, Locations& locations, int specularTextureUnit = 1); @@ -311,9 +315,10 @@ private: static SkinLocations _skinLocations; static SkinLocations _skinNormalMapLocations; static SkinLocations _skinSpecularMapLocations; - static SkinLocations _skinNormalSpecularMapLocations; + static SkinLocations _skinNormalSpecularMapLocations; static SkinLocations _skinShadowLocations; - + static SkinLocations _skinTranslucentLocations; + static void initSkinProgram(ProgramObject& program, SkinLocations& locations, int specularTextureUnit = 1); };