From 70f892e67d47847c60268cfd0469b04f147fc986 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Mon, 16 Oct 2017 17:02:13 +0200 Subject: [PATCH] Ready to plug multiple selections javascript side --- libraries/render-utils/src/Outline.slh | 131 +++++++++++------- libraries/render-utils/src/OutlineEffect.cpp | 32 +++-- libraries/render-utils/src/OutlineEffect.h | 14 +- libraries/render-utils/src/Outline_shared.slh | 6 +- 4 files changed, 112 insertions(+), 71 deletions(-) diff --git a/libraries/render-utils/src/Outline.slh b/libraries/render-utils/src/Outline.slh index 4e71116f79..c58d1c7689 100644 --- a/libraries/render-utils/src/Outline.slh +++ b/libraries/render-utils/src/Outline.slh @@ -16,23 +16,85 @@ <@include Outline_shared.slh@> uniform outlineParamsBuffer { - OutlineParameters params; + OutlineParameters groups[GROUP_COUNT]; }; uniform sampler2D sceneDepthMap; uniform sampler2D outlinedDepthMap; uniform sampler2D outlinedIdMap; +uniform int enabledGroupsMask; in vec2 varTexCoord0; out vec4 outFragColor; const float FAR_Z = 1.0; -const float ID_THRESHOLD = 1.f/64.f; const float LINEAR_DEPTH_BIAS = 5e-3; const float OPACITY_EPSILON = 5e-3; <@func main(IS_FILLED)@> +int getGroupIndexFromColor(vec4 color) { + ivec4 id = ivec4(color * GROUP_ID_COLOR_COMPONENT_MAX) << ivec4(0, GROUP_ID_COLOR_COMPONENT_BITS, GROUP_ID_COLOR_COMPONENT_BITS*2, GROUP_ID_COLOR_COMPONENT_BITS*3); + return (id.r | id.g | id.b | id.a) - 1; +} + +vec4 computeGroupOutline(int centerGroupId, float centerDepth, int groupId, vec2 texCoord) { + float intensity = 0.0; + + if (centerGroupId==groupId && centerDepth < FAR_Z) { + // We're on the outlined object, thus no outline to do! +<@if IS_FILLED@> + OutlineParameters groupParams = groups[groupId]; + + // But we need to fill the interior + float sceneDepth = texture(sceneDepthMap, texCoord).x; + // Transform to linear depth for better precision + centerDepth = -evalZeyeFromZdb(centerDepth); + sceneDepth = -evalZeyeFromZdb(sceneDepth); + + // Are we occluded? + intensity = (sceneDepth < (centerDepth-LINEAR_DEPTH_BIAS)) ? groupParams._fillOpacityOccluded : groupParams._fillOpacityUnoccluded; + return vec4(groupParams._color.rgb, intensity); +<@else@> + return vec4(0,0,0,0); +<@endif@> + } else { + OutlineParameters groupParams = groups[groupId]; + float weight = 0.0; + vec2 deltaUv = groupParams._size / groupParams._blurKernelSize; + vec2 lineStartUv = texCoord - groupParams._size / 2.0; + vec2 uv; + int x; + int y; + + for (y=0 ; y=0.0 && uv.y<=1.0) { + for (x=0 ; x=0.0 && uv.x<=1.0) + { + vec4 outlinedIdColor = texture(outlinedIdMap, uv); + float outlinedDepth = texture(outlinedDepthMap, uv).x; + int outlinedId = getGroupIndexFromColor(outlinedIdColor); + intensity += (outlinedDepth - // But we need to fill the interior - float sceneDepth = texture(sceneDepthMap, texCoord0).x; - // Transform to linear depth for better precision - outlinedDepth = -evalZeyeFromZdb(outlinedDepth); - sceneDepth = -evalZeyeFromZdb(sceneDepth); - - // Are we occluded? - if (sceneDepth < (outlinedDepth-LINEAR_DEPTH_BIAS)) { - intensity = params._fillOpacityOccluded; - } else { - intensity = params._fillOpacityUnoccluded; + vec4 finalColor = vec4(0,0,0,0); + int groupMask = 1; + for (int i=0 ; i - discard; -<@endif@> - } else { - float weight = 0.0; - vec2 deltaUv = params._size / params._blurKernelSize; - vec2 lineStartUv = texCoord0 - params._size / 2.0; - vec2 uv; - int x; - int y; - - for (y=0 ; y=0.0 && uv.y<=1.0) { - for (x=0 ; x=0.0 && uv.x<=1.0) - { - outlinedDepth = texture(outlinedDepthMap, uv).x; - outlinedIdColor = texture(outlinedIdMap, uv); - intensity += (outlinedDepth < FAR_Z && distance(outlinedIdColor, params._idColor) < ID_THRESHOLD) ? 1.0 : 0.0; - weight += 1.f; - } - uv.x += deltaUv.x; - } - } - } - - intensity /= weight; - if (intensity < OPACITY_EPSILON) { - discard; - } - - intensity = min(1.0, intensity / params._threshold) * params._intensity; + groupMask <<= 1; } - outFragColor = vec4(params._color.rgb, intensity); + if (finalColor.a < OPACITY_EPSILON) { + discard; + } + outFragColor = finalColor; } <@endfunc@> diff --git a/libraries/render-utils/src/OutlineEffect.cpp b/libraries/render-utils/src/OutlineEffect.cpp index 0ffd2581cf..2cb19826f4 100644 --- a/libraries/render-utils/src/OutlineEffect.cpp +++ b/libraries/render-utils/src/OutlineEffect.cpp @@ -94,6 +94,8 @@ glm::vec4 encodeIdToColor(unsigned int id) { unsigned char id; } groupId; + static_assert(GROUP_ID_COLOR_COMPONENT_BITS == 2, "Assuming two bits per component contrary to GLSL shader code. See Outline_shared.slh"); + assert(id < 254); groupId.id = id+1; @@ -101,7 +103,7 @@ glm::vec4 encodeIdToColor(unsigned int id) { // Normalize. Since we put 2 bits into each color component, each component has a maximum // value of 3. - idColor /= 3.f; + idColor /= GROUP_ID_COLOR_COMPONENT_MAX; return idColor; } @@ -250,15 +252,19 @@ void DrawOutline::run(const render::RenderContextPointer& renderContext, const I if (_hasConfigurationChanged) { auto& configuration = _configuration.edit(); - configuration._color = _color; - configuration._intensity = _intensity; - configuration._fillOpacityUnoccluded = _fillOpacityUnoccluded; - configuration._fillOpacityOccluded = _fillOpacityOccluded; - configuration._threshold = _threshold; - configuration._blurKernelSize = _blurKernelSize; - configuration._size.x = (_size * framebufferSize.y) / framebufferSize.x; - configuration._size.y = _size; - configuration._idColor = encodeIdToColor(0); + + for (auto groupId = 0; groupId < MAX_GROUP_COUNT; groupId++) { + auto& groupConfig = configuration._groups[groupId]; + + groupConfig._color = _color; + groupConfig._intensity = _intensity; + groupConfig._fillOpacityUnoccluded = _fillOpacityUnoccluded; + groupConfig._fillOpacityOccluded = _fillOpacityOccluded; + groupConfig._threshold = _threshold; + groupConfig._blurKernelSize = _blurKernelSize; + groupConfig._size.x = (_size * framebufferSize.y) / framebufferSize.x; + groupConfig._size.y = _size; + } _hasConfigurationChanged = false; } @@ -272,15 +278,15 @@ void DrawOutline::run(const render::RenderContextPointer& renderContext, const I batch.setModelTransform(gpu::Framebuffer::evalSubregionTexcoordTransform(framebufferSize, args->_viewport)); batch.setPipeline(pipeline); + auto enabledGroupsLoc = pipeline->getProgram()->getUniforms().findLocation("enabledGroupsMask"); + batch.setUniformBuffer(OUTLINE_PARAMS_SLOT, _configuration); batch.setUniformBuffer(FRAME_TRANSFORM_SLOT, frameTransform->getFrameTransformBuffer()); batch.setResourceTexture(SCENE_DEPTH_SLOT, sceneDepthBuffer->getPrimaryDepthTexture()); batch.setResourceTexture(OUTLINED_DEPTH_SLOT, outlinedDepthTexture); batch.setResourceTexture(OUTLINED_ID_SLOT, outlinedIdTexture); + batch._glUniform1i(enabledGroupsLoc, 1); batch.draw(gpu::TRIANGLE_STRIP, 4); - - // Restore previous frame buffer - batch.setFramebuffer(destinationFrameBuffer); }); } } diff --git a/libraries/render-utils/src/OutlineEffect.h b/libraries/render-utils/src/OutlineEffect.h index ce0b2917a4..6e4c0a18a8 100644 --- a/libraries/render-utils/src/OutlineEffect.h +++ b/libraries/render-utils/src/OutlineEffect.h @@ -94,9 +94,13 @@ signals: }; class DrawOutline { +private: + +#include "Outline_shared.slh" + public: enum { - MAX_GROUP_COUNT = 7 + MAX_GROUP_COUNT = GROUP_COUNT }; using Inputs = render::VaryingSet4; @@ -116,12 +120,14 @@ private: OUTLINED_ID_SLOT, OUTLINE_PARAMS_SLOT = 0, - FRAME_TRANSFORM_SLOT + FRAME_TRANSFORM_SLOT, }; -#include "Outline_shared.slh" + struct OutlineConfiguration { + OutlineParameters _groups[MAX_GROUP_COUNT]; + }; - using OutlineConfigurationBuffer = gpu::StructBuffer; + using OutlineConfigurationBuffer = gpu::StructBuffer; static const gpu::PipelinePointer& getPipeline(bool isFilled); diff --git a/libraries/render-utils/src/Outline_shared.slh b/libraries/render-utils/src/Outline_shared.slh index 5ce21c85b4..98d803c28b 100644 --- a/libraries/render-utils/src/Outline_shared.slh +++ b/libraries/render-utils/src/Outline_shared.slh @@ -9,6 +9,10 @@ # define VEC4 vec4 #endif +#define GROUP_COUNT 7 +#define GROUP_ID_COLOR_COMPONENT_BITS 2 +#define GROUP_ID_COLOR_COMPONENT_MAX 3 + struct OutlineParameters { VEC3 _color; @@ -18,8 +22,6 @@ struct OutlineParameters float _fillOpacityUnoccluded; float _fillOpacityOccluded; - VEC4 _idColor; - float _threshold; int _blurKernelSize; float padding2;