From 8957cc5b2be372aeb6327ba2716490280c768ee4 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 22 Aug 2019 08:12:25 -0700 Subject: [PATCH] render opaque PolyLines with opaque pipepline --- .../src/RenderablePolyLineEntityItem.cpp | 41 +++++++++++++++---- .../src/RenderablePolyLineEntityItem.h | 3 +- .../src/entities-renderer/paintStroke.slp | 2 +- .../entities-renderer/src/paintStroke.slf | 6 ++- .../render-utils/src/DeferredBufferWrite.slh | 3 +- 5 files changed, 41 insertions(+), 14 deletions(-) diff --git a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp index 45e718e1d5..9a762b3b3a 100644 --- a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp @@ -55,23 +55,41 @@ void PolyLineEntityRenderer::updateModelTransformAndBound() { } } -void PolyLineEntityRenderer::buildPipelines() { - // FIXME: opaque pipelines +bool PolyLineEntityRenderer::isTransparent() const { + return _glow || (_textureLoaded && _texture->getGPUTexture() && _texture->getGPUTexture()->getUsage().isAlpha()); +} +void PolyLineEntityRenderer::buildPipelines() { static const std::vector> keys = { { render::Args::DEFERRED, false }, { render::Args::DEFERRED, true }, { render::Args::FORWARD, false }, { render::Args::FORWARD, true }, }; for (auto& key : keys) { - gpu::ShaderPointer program = gpu::Shader::createProgram(key.first == render::Args::DEFERRED ? shader::entities_renderer::program::paintStroke : shader::entities_renderer::program::paintStroke_forward); + gpu::ShaderPointer program; + render::Args::RenderMethod renderMethod = key.first; + bool transparent = key.second; + + if (renderMethod == render::Args::DEFERRED) { + if (transparent) { + program = gpu::Shader::createProgram(shader::entities_renderer::program::paintStroke_translucent); + } else { + program = gpu::Shader::createProgram(shader::entities_renderer::program::paintStroke); + } + } else { // render::Args::FORWARD + program = gpu::Shader::createProgram(shader::entities_renderer::program::paintStroke_forward); + } gpu::StatePointer state = gpu::StatePointer(new gpu::State()); state->setCullMode(gpu::State::CullMode::CULL_NONE); - state->setDepthTest(true, !key.second, gpu::LESS_EQUAL); - PrepareStencil::testMask(*state); + state->setDepthTest(true, !transparent, gpu::LESS_EQUAL); + if (transparent) { + PrepareStencil::testMask(*state); + } else { + PrepareStencil::testMaskDrawShape(*state); + } - state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, + state->setBlendFunction(transparent, 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); _pipelines[key] = gpu::Pipeline::create(program, state); @@ -79,11 +97,16 @@ void PolyLineEntityRenderer::buildPipelines() { } ItemKey PolyLineEntityRenderer::getKey() { - return ItemKey::Builder::transparentShape().withTypeMeta().withTagBits(getTagMask()).withLayer(getHifiRenderLayer()); + return isTransparent() ? + ItemKey::Builder::transparentShape().withTypeMeta().withTagBits(getTagMask()).withLayer(getHifiRenderLayer()) : + ItemKey::Builder::opaqueShape().withTypeMeta().withTagBits(getTagMask()).withLayer(getHifiRenderLayer()); } ShapeKey PolyLineEntityRenderer::getShapeKey() { - auto builder = ShapeKey::Builder().withOwnPipeline().withTranslucent().withoutCullFace(); + auto builder = ShapeKey::Builder().withOwnPipeline().withoutCullFace(); + if (isTransparent()) { + builder.withTranslucent(); + } if (_primitiveMode == PrimitiveMode::LINES) { builder.withWireframe(); } @@ -308,7 +331,7 @@ void PolyLineEntityRenderer::doRender(RenderArgs* args) { buildPipelines(); } - batch.setPipeline(_pipelines[{args->_renderMethod, _glow}]); + batch.setPipeline(_pipelines[{args->_renderMethod, isTransparent()}]); batch.setModelTransform(transform); batch.setResourceTexture(0, texture); batch.draw(gpu::TRIANGLE_STRIP, (gpu::uint32)(2 * numVertices), 0); diff --git a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.h b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.h index 97a45cef19..41b66c0e51 100644 --- a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.h +++ b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.h @@ -27,8 +27,7 @@ public: void updateModelTransformAndBound() override; - // FIXME: shouldn't always be transparent: take into account texture and glow - virtual bool isTransparent() const override { return true; } + virtual bool isTransparent() const override; protected: virtual bool needsRenderUpdate() const override; diff --git a/libraries/entities-renderer/src/entities-renderer/paintStroke.slp b/libraries/entities-renderer/src/entities-renderer/paintStroke.slp index e283f4edcb..acdda4dece 100644 --- a/libraries/entities-renderer/src/entities-renderer/paintStroke.slp +++ b/libraries/entities-renderer/src/entities-renderer/paintStroke.slp @@ -1 +1 @@ -DEFINES forward \ No newline at end of file +DEFINES translucent:f forward diff --git a/libraries/entities-renderer/src/paintStroke.slf b/libraries/entities-renderer/src/paintStroke.slf index 4ae242655c..3d5cc190d0 100644 --- a/libraries/entities-renderer/src/paintStroke.slf +++ b/libraries/entities-renderer/src/paintStroke.slf @@ -34,7 +34,11 @@ void main(void) { texel.a *= mix(1.0, pow(1.0 - min(1.0, abs(_distanceFromCenter)), 10.0), _polylineData.faceCameraGlow.y); <@if not HIFI_USE_FORWARD@> - packDeferredFragmentTranslucent((2.0 * float(gl_FrontFacing) - 1.0) * _normalWS, texel.a, texel.rgb, DEFAULT_ROUGHNESS); + <@if HIFI_USE_TRANSLUCENT@> + packDeferredFragmentTranslucent((2.0 * float(gl_FrontFacing) - 1.0) * _normalWS, texel.a, texel.rgb, DEFAULT_ROUGHNESS); + <@else@> + packDeferredFragmentUnlit((2.0 * float(gl_FrontFacing) - 1.0) * _normalWS, texel.a, texel.rgb); + <@endif@> <@else@> _fragColor0 = texel; <@endif@> diff --git a/libraries/render-utils/src/DeferredBufferWrite.slh b/libraries/render-utils/src/DeferredBufferWrite.slh index de4581d66e..de3d0a3087 100644 --- a/libraries/render-utils/src/DeferredBufferWrite.slh +++ b/libraries/render-utils/src/DeferredBufferWrite.slh @@ -52,7 +52,8 @@ void packDeferredFragmentLightmap(vec3 normal, float alpha, vec3 albedo, float r } void packDeferredFragmentUnlit(vec3 normal, float alpha, vec3 color) { - if (alpha < 1.0) { + // to reduce texel flickering for floating point error we discard when alpha is "almost one" + if (alpha < 0.999999) { discard; } _fragColor0 = vec4(color, packUnlit());