diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index 618785ca66..46fc2dfc36 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -28,6 +28,7 @@ static const float DPI = 30.47f; static const float INCHES_TO_METERS = 1.0f / 39.3701f; +static float OPAQUE_ALPHA_THRESHOLD = 0.99f; QString const Web3DOverlay::TYPE = "web3d"; @@ -106,7 +107,11 @@ void Web3DOverlay::render(RenderArgs* args) { batch.setModelTransform(transform); auto geometryCache = DependencyManager::get(); - geometryCache->bindSimpleSRGBTexturedUnlitNoTexAlphaProgram(batch); + if (color.a < OPAQUE_ALPHA_THRESHOLD) { + geometryCache->bindTransparentWebBrowserProgram(batch); + } else { + geometryCache->bindOpaqueWebBrowserProgram(batch); + } geometryCache->renderQuad(batch, halfSize * -1.0f, halfSize, vec2(0), vec2(1), color); batch.setResourceTexture(0, args->_whiteTexture); // restore default white color after me } diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp index 9221fec140..4a42df561e 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp @@ -35,6 +35,7 @@ static const uint32_t MAX_CONCURRENT_WEB_VIEWS = 100; static uint64_t MAX_NO_RENDER_INTERVAL = 30 * USECS_PER_SECOND; static int MAX_WINDOW_SIZE = 4096; +static float OPAQUE_ALPHA_THRESHOLD = 0.99f; EntityItemPointer RenderableWebEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { EntityItemPointer entity{ new RenderableWebEntityItem(entityID) }; @@ -144,7 +145,7 @@ void RenderableWebEntityItem::render(RenderArgs* args) { glm::vec2 windowSize = getWindowSize(); // The offscreen surface is idempotent for resizes (bails early - // if it's a no-op), so it's safe to just call resize every frame + // if it's a no-op), so it's safe to just call resize every frame // without worrying about excessive overhead. _webSurface->resize(QSize(windowSize.x, windowSize.y)); @@ -164,9 +165,14 @@ void RenderableWebEntityItem::render(RenderArgs* args) { } float fadeRatio = _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f; + batch._glColor4f(1.0f, 1.0f, 1.0f, fadeRatio); - DependencyManager::get()->bindSimpleSRGBTexturedUnlitNoTexAlphaProgram(batch); + if (fadeRatio < OPAQUE_ALPHA_THRESHOLD) { + DependencyManager::get()->bindTransparentWebBrowserProgram(batch); + } else { + DependencyManager::get()->bindOpaqueWebBrowserProgram(batch); + } DependencyManager::get()->renderQuad(batch, topLeft, bottomRight, texMin, texMax, glm::vec4(1.0f, 1.0f, 1.0f, fadeRatio)); } @@ -291,3 +297,9 @@ void RenderableWebEntityItem::update(const quint64& now) { destroyWebSurface(); } } + + +bool RenderableWebEntityItem::isTransparent() { + float fadeRatio = _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f; + return fadeRatio < OPAQUE_ALPHA_THRESHOLD; +} diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.h b/libraries/entities-renderer/src/RenderableWebEntityItem.h index 7bfd40864b..03234ce690 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.h +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.h @@ -44,6 +44,8 @@ public: SIMPLE_RENDERABLE(); + virtual bool isTransparent() override; + private: bool buildWebSurface(EntityTreeRenderer* renderer); void destroyWebSurface(); diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 01cec78eae..a3a9303156 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -35,7 +35,8 @@ #include "simple_vert.h" #include "simple_textured_frag.h" #include "simple_textured_unlit_frag.h" -#include "simple_srgb_textured_unlit_no_tex_alpha_frag.h" +#include "simple_opaque_web_browser_frag.h" +#include "simple_transparent_web_browser_frag.h" #include "glowLine_vert.h" #include "glowLine_geom.h" #include "glowLine_frag.h" @@ -1763,25 +1764,55 @@ inline bool operator==(const SimpleProgramKey& a, const SimpleProgramKey& b) { return a.getRaw() == b.getRaw(); } -void GeometryCache::bindSimpleSRGBTexturedUnlitNoTexAlphaProgram(gpu::Batch& batch) { - batch.setPipeline(getSimpleSRGBTexturedUnlitNoTexAlphaPipeline()); +void GeometryCache::bindOpaqueWebBrowserProgram(gpu::Batch& batch) { + batch.setPipeline(getOpaqueWebBrowserProgram()); // Set a default normal map batch.setResourceTexture(render::ShapePipeline::Slot::MAP::NORMAL_FITTING, - DependencyManager::get()->getNormalFittingTexture()); + DependencyManager::get()->getNormalFittingTexture()); } -gpu::PipelinePointer GeometryCache::getSimpleSRGBTexturedUnlitNoTexAlphaPipeline() { - // Compile the shaders, once +gpu::PipelinePointer GeometryCache::getOpaqueWebBrowserProgram() { static std::once_flag once; std::call_once(once, [&]() { auto VS = gpu::Shader::createVertex(std::string(simple_vert)); - auto PS = gpu::Shader::createPixel(std::string(simple_srgb_textured_unlit_no_tex_alpha_frag)); + auto PS = gpu::Shader::createPixel(std::string(simple_opaque_web_browser_frag)); - _simpleSRGBTexturedUnlitNoTexAlphaShader = gpu::Shader::createProgram(VS, PS); + _simpleOpaqueWebBrowserShader = gpu::Shader::createProgram(VS, PS); gpu::Shader::BindingSet slotBindings; slotBindings.insert(gpu::Shader::Binding(std::string("normalFittingMap"), render::ShapePipeline::Slot::MAP::NORMAL_FITTING)); - gpu::Shader::makeProgram(*_simpleSRGBTexturedUnlitNoTexAlphaShader, slotBindings); + gpu::Shader::makeProgram(*_simpleOpaqueWebBrowserShader, slotBindings); + auto state = std::make_shared(); + state->setCullMode(gpu::State::CULL_NONE); + state->setDepthTest(true, true, gpu::LESS_EQUAL); + state->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); + + _simpleOpaqueWebBrowserPipeline = gpu::Pipeline::create(_simpleOpaqueWebBrowserShader, state); + }); + + return _simpleOpaqueWebBrowserPipeline; +} + +void GeometryCache::bindTransparentWebBrowserProgram(gpu::Batch& batch) { + batch.setPipeline(getTransparentWebBrowserProgram()); + // Set a default normal map + batch.setResourceTexture(render::ShapePipeline::Slot::MAP::NORMAL_FITTING, + DependencyManager::get()->getNormalFittingTexture()); +} + +gpu::PipelinePointer GeometryCache::getTransparentWebBrowserProgram() { + static std::once_flag once; + std::call_once(once, [&]() { + auto VS = gpu::Shader::createVertex(std::string(simple_vert)); + auto PS = gpu::Shader::createPixel(std::string(simple_transparent_web_browser_frag)); + + _simpleTransparentWebBrowserShader = gpu::Shader::createProgram(VS, PS); + + gpu::Shader::BindingSet slotBindings; + slotBindings.insert(gpu::Shader::Binding(std::string("normalFittingMap"), render::ShapePipeline::Slot::MAP::NORMAL_FITTING)); + gpu::Shader::makeProgram(*_simpleTransparentWebBrowserShader, slotBindings); auto state = std::make_shared(); state->setCullMode(gpu::State::CULL_NONE); state->setDepthTest(true, true, gpu::LESS_EQUAL); @@ -1789,10 +1820,10 @@ gpu::PipelinePointer GeometryCache::getSimpleSRGBTexturedUnlitNoTexAlphaPipeline 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); - _simpleSRGBTexturedUnlitNoTexAlphaPipeline = gpu::Pipeline::create(_simpleSRGBTexturedUnlitNoTexAlphaShader, state); + _simpleTransparentWebBrowserPipeline = gpu::Pipeline::create(_simpleTransparentWebBrowserShader, state); }); - return _simpleSRGBTexturedUnlitNoTexAlphaPipeline; + return _simpleTransparentWebBrowserPipeline; } void GeometryCache::bindSimpleProgram(gpu::Batch& batch, bool textured, bool transparent, bool culled, bool unlit, bool depthBiased) { diff --git a/libraries/render-utils/src/GeometryCache.h b/libraries/render-utils/src/GeometryCache.h index 9099daf7c0..244683759d 100644 --- a/libraries/render-utils/src/GeometryCache.h +++ b/libraries/render-utils/src/GeometryCache.h @@ -149,8 +149,7 @@ public: int allocateID() { return _nextID++; } static const int UNKNOWN_ID; - - + // Bind the pipeline and get the state to render static geometry void bindSimpleProgram(gpu::Batch& batch, bool textured = false, bool transparent = false, bool culled = true, bool unlit = false, bool depthBias = false); @@ -158,8 +157,11 @@ public: gpu::PipelinePointer getSimplePipeline(bool textured = false, bool transparent = false, bool culled = true, bool unlit = false, bool depthBias = false); - void bindSimpleSRGBTexturedUnlitNoTexAlphaProgram(gpu::Batch& batch); - gpu::PipelinePointer getSimpleSRGBTexturedUnlitNoTexAlphaPipeline(); + void bindOpaqueWebBrowserProgram(gpu::Batch& batch); + gpu::PipelinePointer getOpaqueWebBrowserProgram(); + + void bindTransparentWebBrowserProgram(gpu::Batch& batch); + gpu::PipelinePointer getTransparentWebBrowserProgram(); render::ShapePipelinePointer getOpaqueShapePipeline() { return GeometryCache::_simpleOpaquePipeline; } render::ShapePipelinePointer getTransparentShapePipeline() { return GeometryCache::_simpleTransparentPipeline; } @@ -423,9 +425,11 @@ private: gpu::PipelinePointer _glowLinePipeline; QHash _simplePrograms; - gpu::ShaderPointer _simpleSRGBTexturedUnlitNoTexAlphaShader; - gpu::PipelinePointer _simpleSRGBTexturedUnlitNoTexAlphaPipeline; + gpu::ShaderPointer _simpleOpaqueWebBrowserShader; + gpu::PipelinePointer _simpleOpaqueWebBrowserPipeline; + gpu::ShaderPointer _simpleTransparentWebBrowserShader; + gpu::PipelinePointer _simpleTransparentWebBrowserPipeline; }; #endif // hifi_GeometryCache_h diff --git a/libraries/render-utils/src/simple_opaque_web_browser.slf b/libraries/render-utils/src/simple_opaque_web_browser.slf new file mode 100644 index 0000000000..2921d6aea0 --- /dev/null +++ b/libraries/render-utils/src/simple_opaque_web_browser.slf @@ -0,0 +1,30 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// simple_opaque_web_browser.frag +// fragment shader +// +// Created by Anthony Thibault on 7/25/16. +// Copyright 2016 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 +// + +<@include gpu/Color.slh@> +<@include DeferredBufferWrite.slh@> + +// the albedo texture +uniform sampler2D originalTexture; + +// the interpolated normal +in vec3 _normal; +in vec4 _color; +in vec2 _texCoord0; + +void main(void) { + vec4 texel = texture(originalTexture, _texCoord0.st); + texel = colorToLinearRGBA(texel); + packDeferredFragmentUnlit(normalize(_normal), 1.0, _color.rgb * texel.rgb); +} diff --git a/libraries/render-utils/src/simple_srgb_textured_unlit_no_tex_alpha.slf b/libraries/render-utils/src/simple_transparent_web_browser.slf similarity index 58% rename from libraries/render-utils/src/simple_srgb_textured_unlit_no_tex_alpha.slf rename to libraries/render-utils/src/simple_transparent_web_browser.slf index 38b7e1002c..b7606985e6 100644 --- a/libraries/render-utils/src/simple_srgb_textured_unlit_no_tex_alpha.slf +++ b/libraries/render-utils/src/simple_transparent_web_browser.slf @@ -2,7 +2,7 @@ <$VERSION_HEADER$> // Generated on <$_SCRIBE_DATE$> // -// simple_srgb_texture_unlit_no_tex_alpha.frag +// simple_transparent_web_browser.frag // fragment shader // // Created by Anthony Thibault on 7/25/16. @@ -26,19 +26,11 @@ in vec2 _texCoord0; void main(void) { vec4 texel = texture(originalTexture, _texCoord0.st); texel = colorToLinearRGBA(texel); - - const float ALPHA_THRESHOLD = 0.999; - if (_color.a < ALPHA_THRESHOLD) { - packDeferredFragmentTranslucent( - normalize(_normal), - _color.a, - _color.rgb * texel.rgb, - DEFAULT_FRESNEL, - DEFAULT_ROUGHNESS); - } else { - packDeferredFragmentUnlit( - normalize(_normal), - 1.0, - _color.rgb * texel.rgb); - } + packDeferredFragmentTranslucent( + normalize(_normal), + _color.a, + _color.rgb * texel.rgb, + DEFAULT_FRESNEL, + DEFAULT_ROUGHNESS); } +