diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index 8f2149f02d..ff5177ed3a 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -26,7 +26,8 @@ Base3DOverlay::Base3DOverlay() : _isSolid(DEFAULT_IS_SOLID), _isDashedLine(DEFAULT_IS_DASHED_LINE), _ignoreRayIntersection(false), - _drawInFront(false) + _drawInFront(false), + _isAA(true) { } @@ -37,7 +38,8 @@ Base3DOverlay::Base3DOverlay(const Base3DOverlay* base3DOverlay) : _isSolid(base3DOverlay->_isSolid), _isDashedLine(base3DOverlay->_isDashedLine), _ignoreRayIntersection(base3DOverlay->_ignoreRayIntersection), - _drawInFront(base3DOverlay->_drawInFront) + _drawInFront(base3DOverlay->_drawInFront), + _isAA(base3DOverlay->_isAA) { setTransform(base3DOverlay->getTransform()); } @@ -175,6 +177,13 @@ void Base3DOverlay::setProperties(const QVariantMap& originalProperties) { needRenderItemUpdate = true; } + auto isAA = properties["isAA"]; + if (isAA.isValid()) { + bool value = isAA.toBool(); + setIsAA(value); + needRenderItemUpdate = true; + } + // Communicate changes to the renderItem if needed if (needRenderItemUpdate) { auto itemID = getRenderItemID(); @@ -224,6 +233,9 @@ QVariant Base3DOverlay::getProperty(const QString& property) { if (property == "parentJointIndex") { return getParentJointIndex(); } + if (property == "isAA") { + return _isAA; + } return Overlay::getProperty(property); } diff --git a/interface/src/ui/overlays/Base3DOverlay.h b/interface/src/ui/overlays/Base3DOverlay.h index 487d4eff70..18936df504 100644 --- a/interface/src/ui/overlays/Base3DOverlay.h +++ b/interface/src/ui/overlays/Base3DOverlay.h @@ -36,13 +36,14 @@ public: bool getIgnoreRayIntersection() const { return _ignoreRayIntersection; } bool getDrawInFront() const { return _drawInFront; } - virtual bool isAA() const { return true; } + virtual bool isAA() const { return _isAA; } void setLineWidth(float lineWidth) { _lineWidth = lineWidth; } void setIsSolid(bool isSolid) { _isSolid = isSolid; } void setIsDashedLine(bool isDashedLine) { _isDashedLine = isDashedLine; } void setIgnoreRayIntersection(bool value) { _ignoreRayIntersection = value; } void setDrawInFront(bool value) { _drawInFront = value; } + void setIsAA(bool value) { _isAA = value; } virtual AABox getBounds() const override = 0; @@ -66,6 +67,7 @@ protected: bool _isDashedLine; bool _ignoreRayIntersection; bool _drawInFront; + bool _isAA; }; #endif // hifi_Base3DOverlay_h diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index bf708c738d..f33ef24c0d 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -249,9 +249,9 @@ void Web3DOverlay::render(RenderArgs* args) { batch.setModelTransform(transform); auto geometryCache = DependencyManager::get(); if (color.a < OPAQUE_ALPHA_THRESHOLD) { - geometryCache->bindTransparentWebBrowserProgram(batch); + geometryCache->bindTransparentWebBrowserProgram(batch, _isAA); } else { - geometryCache->bindOpaqueWebBrowserProgram(batch); + geometryCache->bindOpaqueWebBrowserProgram(batch, _isAA); } geometryCache->renderQuad(batch, halfSize * -1.0f, halfSize, vec2(0), vec2(1), color, _geometryId); batch.setResourceTexture(0, args->_whiteTexture); // restore default white color after me diff --git a/interface/src/ui/overlays/Web3DOverlay.h b/interface/src/ui/overlays/Web3DOverlay.h index 72b923496c..2b9686919d 100644 --- a/interface/src/ui/overlays/Web3DOverlay.h +++ b/interface/src/ui/overlays/Web3DOverlay.h @@ -29,8 +29,6 @@ public: Web3DOverlay(const Web3DOverlay* Web3DOverlay); virtual ~Web3DOverlay(); - virtual bool isAA() const { return false; } - QString pickURL(); void loadSourceURL(); virtual void render(RenderArgs* args) override; diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp index e8353a1595..972c23d534 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp @@ -241,10 +241,11 @@ void RenderableWebEntityItem::render(RenderArgs* args) { batch._glColor4f(1.0f, 1.0f, 1.0f, fadeRatio); + const bool IS_AA = true; if (fadeRatio < OPAQUE_ALPHA_THRESHOLD) { - DependencyManager::get()->bindTransparentWebBrowserProgram(batch); + DependencyManager::get()->bindTransparentWebBrowserProgram(batch, IS_AA); } else { - DependencyManager::get()->bindOpaqueWebBrowserProgram(batch); + DependencyManager::get()->bindOpaqueWebBrowserProgram(batch, IS_AA); } DependencyManager::get()->renderQuad(batch, topLeft, bottomRight, texMin, texMax, glm::vec4(1.0f, 1.0f, 1.0f, fadeRatio), _geometryId); } diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index a19f1844f0..c277b9be64 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -36,7 +36,9 @@ #include "simple_textured_frag.h" #include "simple_textured_unlit_frag.h" #include "simple_opaque_web_browser_frag.h" +#include "simple_opaque_web_browser_overlay_frag.h" #include "simple_transparent_web_browser_frag.h" +#include "simple_transparent_web_browser_overlay_frag.h" #include "glowLine_vert.h" #include "glowLine_frag.h" @@ -1760,66 +1762,61 @@ inline bool operator==(const SimpleProgramKey& a, const SimpleProgramKey& b) { return a.getRaw() == b.getRaw(); } -void GeometryCache::bindOpaqueWebBrowserProgram(gpu::Batch& batch) { - batch.setPipeline(getOpaqueWebBrowserProgram()); +static void buildWebShader(const std::string& vertShaderText, const std::string& fragShaderText, bool blendEnable, + gpu::ShaderPointer& shaderPointerOut, gpu::PipelinePointer& pipelinePointerOut) { + auto VS = gpu::Shader::createVertex(vertShaderText); + auto PS = gpu::Shader::createPixel(fragShaderText); + + shaderPointerOut = 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(*shaderPointerOut, slotBindings); + auto state = std::make_shared(); + state->setCullMode(gpu::State::CULL_NONE); + state->setDepthTest(true, true, gpu::LESS_EQUAL); + state->setBlendFunction(blendEnable, + 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); + + pipelinePointerOut = gpu::Pipeline::create(shaderPointerOut, state); +} + +void GeometryCache::bindOpaqueWebBrowserProgram(gpu::Batch& batch, bool isAA) { + batch.setPipeline(getOpaqueWebBrowserProgram(isAA)); // Set a default normal map batch.setResourceTexture(render::ShapePipeline::Slot::MAP::NORMAL_FITTING, DependencyManager::get()->getNormalFittingTexture()); } -gpu::PipelinePointer GeometryCache::getOpaqueWebBrowserProgram() { +gpu::PipelinePointer GeometryCache::getOpaqueWebBrowserProgram(bool isAA) { 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_opaque_web_browser_frag)); - - _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(*_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); + const bool BLEND_ENABLE = false; + buildWebShader(simple_vert, simple_opaque_web_browser_frag, BLEND_ENABLE, _simpleOpaqueWebBrowserShader, _simpleOpaqueWebBrowserPipeline); + buildWebShader(simple_vert, simple_opaque_web_browser_overlay_frag, BLEND_ENABLE, _simpleOpaqueWebBrowserOverlayShader, _simpleOpaqueWebBrowserOverlayPipeline); }); - return _simpleOpaqueWebBrowserPipeline; + return isAA ? _simpleOpaqueWebBrowserPipeline : _simpleOpaqueWebBrowserOverlayPipeline; } -void GeometryCache::bindTransparentWebBrowserProgram(gpu::Batch& batch) { - batch.setPipeline(getTransparentWebBrowserProgram()); +void GeometryCache::bindTransparentWebBrowserProgram(gpu::Batch& batch, bool isAA) { + batch.setPipeline(getTransparentWebBrowserProgram(isAA)); // Set a default normal map batch.setResourceTexture(render::ShapePipeline::Slot::MAP::NORMAL_FITTING, DependencyManager::get()->getNormalFittingTexture()); } -gpu::PipelinePointer GeometryCache::getTransparentWebBrowserProgram() { +gpu::PipelinePointer GeometryCache::getTransparentWebBrowserProgram(bool isAA) { 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); - 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); - - _simpleTransparentWebBrowserPipeline = gpu::Pipeline::create(_simpleTransparentWebBrowserShader, state); + const bool BLEND_ENABLE = true; + buildWebShader(simple_vert, simple_transparent_web_browser_frag, BLEND_ENABLE, _simpleTransparentWebBrowserShader, _simpleTransparentWebBrowserPipeline); + buildWebShader(simple_vert, simple_transparent_web_browser_overlay_frag, BLEND_ENABLE, _simpleTransparentWebBrowserOverlayShader, _simpleTransparentWebBrowserOverlayPipeline); }); - return _simpleTransparentWebBrowserPipeline; + return isAA ? _simpleTransparentWebBrowserPipeline : _simpleTransparentWebBrowserOverlayPipeline; } 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 84dfd8ccc3..e0a610a095 100644 --- a/libraries/render-utils/src/GeometryCache.h +++ b/libraries/render-utils/src/GeometryCache.h @@ -158,11 +158,11 @@ public: gpu::PipelinePointer getSimplePipeline(bool textured = false, bool transparent = false, bool culled = true, bool unlit = false, bool depthBias = false); - void bindOpaqueWebBrowserProgram(gpu::Batch& batch); - gpu::PipelinePointer getOpaqueWebBrowserProgram(); + void bindOpaqueWebBrowserProgram(gpu::Batch& batch, bool isAA); + gpu::PipelinePointer getOpaqueWebBrowserProgram(bool isAA); - void bindTransparentWebBrowserProgram(gpu::Batch& batch); - gpu::PipelinePointer getTransparentWebBrowserProgram(); + void bindTransparentWebBrowserProgram(gpu::Batch& batch, bool isAA); + gpu::PipelinePointer getTransparentWebBrowserProgram(bool isAA); render::ShapePipelinePointer getOpaqueShapePipeline() { return GeometryCache::_simpleOpaquePipeline; } render::ShapePipelinePointer getTransparentShapePipeline() { return GeometryCache::_simpleTransparentPipeline; } @@ -420,15 +420,21 @@ private: gpu::ShaderPointer _unlitShader; static render::ShapePipelinePointer _simpleOpaquePipeline; static render::ShapePipelinePointer _simpleTransparentPipeline; + static render::ShapePipelinePointer _simpleOpaqueOverlayPipeline; + static render::ShapePipelinePointer _simpleTransparentOverlayPipeline; static render::ShapePipelinePointer _simpleWirePipeline; gpu::PipelinePointer _glowLinePipeline; QHash _simplePrograms; gpu::ShaderPointer _simpleOpaqueWebBrowserShader; gpu::PipelinePointer _simpleOpaqueWebBrowserPipeline; - gpu::ShaderPointer _simpleTransparentWebBrowserShader; gpu::PipelinePointer _simpleTransparentWebBrowserPipeline; + + gpu::ShaderPointer _simpleOpaqueWebBrowserOverlayShader; + gpu::PipelinePointer _simpleOpaqueWebBrowserOverlayPipeline; + gpu::ShaderPointer _simpleTransparentWebBrowserOverlayShader; + gpu::PipelinePointer _simpleTransparentWebBrowserOverlayPipeline; }; #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 index 2921d6aea0..3acf104b55 100644 --- a/libraries/render-utils/src/simple_opaque_web_browser.slf +++ b/libraries/render-utils/src/simple_opaque_web_browser.slf @@ -2,7 +2,7 @@ <$VERSION_HEADER$> // Generated on <$_SCRIBE_DATE$> // -// simple_opaque_web_browser.frag +// simple_opaque_web_browser.slf // fragment shader // // Created by Anthony Thibault on 7/25/16. diff --git a/libraries/render-utils/src/simple_opaque_web_browser_overlay.slf b/libraries/render-utils/src/simple_opaque_web_browser_overlay.slf new file mode 100644 index 0000000000..6d4d35591f --- /dev/null +++ b/libraries/render-utils/src/simple_opaque_web_browser_overlay.slf @@ -0,0 +1,30 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// simple_opaque_web_browser_overlay.slf +// fragment shader +// +// Created by Anthony Thibault on 1/30/17. +// Copyright 2017 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 +// +// Same as simple_opaque_web_browser.slf except frame buffer is sRGB, so colorToLinearRGBA is not necessary. + +<@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); + _fragColor0 = vec4(_color.rgb * texel.rgb, 1.0); +} diff --git a/libraries/render-utils/src/simple_transparent_web_browser.slf b/libraries/render-utils/src/simple_transparent_web_browser.slf index b7606985e6..19079f5d92 100644 --- a/libraries/render-utils/src/simple_transparent_web_browser.slf +++ b/libraries/render-utils/src/simple_transparent_web_browser.slf @@ -2,7 +2,7 @@ <$VERSION_HEADER$> // Generated on <$_SCRIBE_DATE$> // -// simple_transparent_web_browser.frag +// simple_transparent_web_browser.slf // fragment shader // // Created by Anthony Thibault on 7/25/16. @@ -33,4 +33,3 @@ void main(void) { DEFAULT_FRESNEL, DEFAULT_ROUGHNESS); } - diff --git a/libraries/render-utils/src/simple_transparent_web_browser_overlay.slf b/libraries/render-utils/src/simple_transparent_web_browser_overlay.slf new file mode 100644 index 0000000000..af52389d5b --- /dev/null +++ b/libraries/render-utils/src/simple_transparent_web_browser_overlay.slf @@ -0,0 +1,31 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// simple_transparent_web_browser_overlay.slf +// fragment shader +// +// Created by Anthony Thibault on 1/30/17. +// Copyright 2017 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 +// +// Same as simple_transparent_web_browser.slf except frame buffer is sRGB, So colorToLinearRGBA is not necessary. +// + +<@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); + _fragColor0 = vec4(_color.rgb * texel.rgb, _color.a); +} diff --git a/scripts/system/libraries/WebTablet.js b/scripts/system/libraries/WebTablet.js index a342597c2d..6a0f159582 100644 --- a/scripts/system/libraries/WebTablet.js +++ b/scripts/system/libraries/WebTablet.js @@ -128,7 +128,8 @@ WebTablet = function (url, width, dpi, hand, clientOnly) { alpha: 1.0, parentID: this.tabletEntityID, parentJointIndex: -1, - showKeyboardFocusHighlight: false + showKeyboardFocusHighlight: false, + isAA: HMD.active }); var HOME_BUTTON_Y_OFFSET = (this.height / 2) - 0.035; @@ -293,6 +294,10 @@ WebTablet.prototype.onHmdChanged = function () { // compute position, rotation & parentJointIndex of the tablet this.calculateTabletAttachmentProperties(NO_HANDS, tabletProperties); Entities.editEntity(this.tabletEntityID, tabletProperties); + + // Full scene FXAA should be disabled on the overlay when the tablet in desktop mode. + // This should make the text more readable. + Overlays.editOverlay(this.webOverlayID, { isAA: HMD.active }); }; WebTablet.prototype.pickle = function () {