From d8545bc7a3bbfd319ef11212d580bbed4d990d67 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Wed, 10 Aug 2016 13:49:35 -0700 Subject: [PATCH] fix procedural transparency --- .../src/RenderableShapeEntityItem.cpp | 5 ----- .../procedural/src/procedural/Procedural.cpp | 21 +++++++++++++++---- .../procedural/src/procedural/Procedural.h | 10 ++++++--- .../src/procedural/ProceduralSkybox.cpp | 3 ++- 4 files changed, 26 insertions(+), 13 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp index 73c4d99b5e..e14def114d 100644 --- a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp @@ -91,11 +91,6 @@ void RenderableShapeEntityItem::render(RenderArgs* args) { _procedural.reset(new Procedural(getUserData())); _procedural->_vertexSource = simple_vert; _procedural->_fragmentSource = simple_frag; - _procedural->_state->setCullMode(gpu::State::CULL_NONE); - _procedural->_state->setDepthTest(true, true, gpu::LESS_EQUAL); - _procedural->_state->setBlendFunction(true, - gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, - gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); } gpu::Batch& batch = *args->_batch; diff --git a/libraries/procedural/src/procedural/Procedural.cpp b/libraries/procedural/src/procedural/Procedural.cpp index cd9edb6621..79a90ef72d 100644 --- a/libraries/procedural/src/procedural/Procedural.cpp +++ b/libraries/procedural/src/procedural/Procedural.cpp @@ -63,7 +63,19 @@ QJsonValue Procedural::getProceduralData(const QString& proceduralJson) { return doc.object()[PROCEDURAL_USER_DATA_KEY]; } -Procedural::Procedural() : _state { std::make_shared() } { +Procedural::Procedural() { + _opaqueState->setCullMode(gpu::State::CULL_NONE); + _opaqueState->setDepthTest(true, true, gpu::LESS_EQUAL); + _opaqueState->setBlendFunction(false, + gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, + gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); + + _transparentState->setCullMode(gpu::State::CULL_NONE); + _transparentState->setDepthTest(true, true, gpu::LESS_EQUAL); + _transparentState->setBlendFunction(true, + gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, + gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); + _proceduralDataDirty = false; } @@ -230,7 +242,7 @@ void Procedural::prepare(gpu::Batch& batch, const glm::vec3& position, const glm _shaderSource = _networkShader->_source; } - if (!_pipeline || _shaderDirty) { + if (!_opaquePipeline || !_transparentPipeline || _shaderDirty) { if (!_vertexShader) { _vertexShader = gpu::Shader::createVertex(_vertexSource); } @@ -268,7 +280,8 @@ void Procedural::prepare(gpu::Batch& batch, const glm::vec3& position, const glm slotBindings.insert(gpu::Shader::Binding(std::string("iChannel3"), 3)); gpu::Shader::makeProgram(*_shader, slotBindings); - _pipeline = gpu::Pipeline::create(_shader, _state); + _opaquePipeline = gpu::Pipeline::create(_shader, _opaqueState); + _transparentPipeline = gpu::Pipeline::create(_shader, _transparentState); for (size_t i = 0; i < NUM_STANDARD_UNIFORMS; ++i) { const std::string& name = STANDARD_UNIFORM_NAMES[i]; _standardUniformSlots[i] = _shader->getUniforms().findLocation(name); @@ -277,7 +290,7 @@ void Procedural::prepare(gpu::Batch& batch, const glm::vec3& position, const glm _frameCount = 0; } - batch.setPipeline(_pipeline); + batch.setPipeline(isFading() ? _transparentPipeline : _opaquePipeline); if (_shaderDirty || _uniformsDirty) { setupUniforms(); diff --git a/libraries/procedural/src/procedural/Procedural.h b/libraries/procedural/src/procedural/Procedural.h index c2939e4a01..fdca85bbae 100644 --- a/libraries/procedural/src/procedural/Procedural.h +++ b/libraries/procedural/src/procedural/Procedural.h @@ -43,15 +43,17 @@ public: glm::vec4 getColor(const glm::vec4& entityColor); quint64 getFadeStartTime() { return _fadeStartTime; } - bool isFading() { return _isFading; } + bool isFading() { return _doesFade && _isFading; } void setIsFading(bool isFading) { _isFading = isFading; } + void setDoesFade(bool doesFade) { _doesFade = doesFade; } uint8_t _version { 1 }; std::string _vertexSource; std::string _fragmentSource; - gpu::StatePointer _state; + gpu::StatePointer _opaqueState { std::make_shared() }; + gpu::StatePointer _transparentState { std::make_shared() }; enum StandardUniforms { DATE, @@ -89,7 +91,8 @@ protected: UniformLambdas _uniforms; int32_t _standardUniformSlots[NUM_STANDARD_UNIFORMS]; NetworkTexturePointer _channels[MAX_PROCEDURAL_TEXTURE_CHANNELS]; - gpu::PipelinePointer _pipeline; + gpu::PipelinePointer _opaquePipeline; + gpu::PipelinePointer _transparentPipeline; gpu::ShaderPointer _vertexShader; gpu::ShaderPointer _fragmentShader; gpu::ShaderPointer _shader; @@ -113,6 +116,7 @@ private: quint64 _fadeStartTime; bool _hasStartedFade { false }; bool _isFading { false }; + bool _doesFade { true }; }; #endif diff --git a/libraries/procedural/src/procedural/ProceduralSkybox.cpp b/libraries/procedural/src/procedural/ProceduralSkybox.cpp index 9e9a26d902..843df3aa8d 100644 --- a/libraries/procedural/src/procedural/ProceduralSkybox.cpp +++ b/libraries/procedural/src/procedural/ProceduralSkybox.cpp @@ -22,7 +22,8 @@ ProceduralSkybox::ProceduralSkybox() : model::Skybox() { _procedural._vertexSource = skybox_vert; _procedural._fragmentSource = skybox_frag; // Adjust the pipeline state for background using the stencil test - _procedural._state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + _procedural.setDoesFade(false); + _procedural._opaqueState->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); } void ProceduralSkybox::clear() {