mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-06-20 06:20:34 +02:00
Ready to plug multiple selections javascript side
This commit is contained in:
parent
1b67223e0e
commit
70f892e67d
4 changed files with 112 additions and 71 deletions
|
@ -16,23 +16,85 @@
|
||||||
<@include Outline_shared.slh@>
|
<@include Outline_shared.slh@>
|
||||||
|
|
||||||
uniform outlineParamsBuffer {
|
uniform outlineParamsBuffer {
|
||||||
OutlineParameters params;
|
OutlineParameters groups[GROUP_COUNT];
|
||||||
};
|
};
|
||||||
|
|
||||||
uniform sampler2D sceneDepthMap;
|
uniform sampler2D sceneDepthMap;
|
||||||
uniform sampler2D outlinedDepthMap;
|
uniform sampler2D outlinedDepthMap;
|
||||||
uniform sampler2D outlinedIdMap;
|
uniform sampler2D outlinedIdMap;
|
||||||
|
uniform int enabledGroupsMask;
|
||||||
|
|
||||||
in vec2 varTexCoord0;
|
in vec2 varTexCoord0;
|
||||||
out vec4 outFragColor;
|
out vec4 outFragColor;
|
||||||
|
|
||||||
const float FAR_Z = 1.0;
|
const float FAR_Z = 1.0;
|
||||||
const float ID_THRESHOLD = 1.f/64.f;
|
|
||||||
const float LINEAR_DEPTH_BIAS = 5e-3;
|
const float LINEAR_DEPTH_BIAS = 5e-3;
|
||||||
const float OPACITY_EPSILON = 5e-3;
|
const float OPACITY_EPSILON = 5e-3;
|
||||||
|
|
||||||
<@func main(IS_FILLED)@>
|
<@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<groupParams._blurKernelSize ; y++) {
|
||||||
|
uv = lineStartUv;
|
||||||
|
lineStartUv.y += deltaUv.y;
|
||||||
|
|
||||||
|
if (uv.y>=0.0 && uv.y<=1.0) {
|
||||||
|
for (x=0 ; x<groupParams._blurKernelSize ; x++) {
|
||||||
|
if (uv.x>=0.0 && uv.x<=1.0)
|
||||||
|
{
|
||||||
|
vec4 outlinedIdColor = texture(outlinedIdMap, uv);
|
||||||
|
float outlinedDepth = texture(outlinedDepthMap, uv).x;
|
||||||
|
int outlinedId = getGroupIndexFromColor(outlinedIdColor);
|
||||||
|
intensity += (outlinedDepth<FAR_Z /*&& outlinedId!=groupId*/) ? 1.0 : 0.0;
|
||||||
|
weight += 1.f;
|
||||||
|
}
|
||||||
|
uv.x += deltaUv.x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
intensity /= weight;
|
||||||
|
if (intensity < OPACITY_EPSILON) {
|
||||||
|
return vec4(0,0,0,0);
|
||||||
|
}
|
||||||
|
intensity = min(1.0, intensity / groupParams._threshold) * groupParams._intensity;
|
||||||
|
return vec4(groupParams._color.rgb, intensity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
// We offset by half a texel to be centered on the depth sample. If we don't do this
|
// We offset by half a texel to be centered on the depth sample. If we don't do this
|
||||||
// the blur will have a different width between the left / right sides and top / bottom
|
// the blur will have a different width between the left / right sides and top / bottom
|
||||||
|
@ -42,60 +104,25 @@ void main(void) {
|
||||||
vec4 outlinedIdColor = texture(outlinedIdMap, texCoord0);
|
vec4 outlinedIdColor = texture(outlinedIdMap, texCoord0);
|
||||||
float outlinedDepth = texture(outlinedDepthMap, texCoord0).x;
|
float outlinedDepth = texture(outlinedDepthMap, texCoord0).x;
|
||||||
float intensity = 0.0;
|
float intensity = 0.0;
|
||||||
|
int groupId = getGroupIndexFromColor(outlinedIdColor);
|
||||||
|
|
||||||
if (outlinedDepth < FAR_Z && distance(outlinedIdColor, params._idColor) < ID_THRESHOLD) {
|
vec4 finalColor = vec4(0,0,0,0);
|
||||||
// We're not on the far plane so we are on the outlined object, thus no outline to do!
|
int groupMask = 1;
|
||||||
<@if IS_FILLED@>
|
for (int i=0 ; i<GROUP_COUNT ; i++) {
|
||||||
// But we need to fill the interior
|
if ((enabledGroupsMask & groupMask)!=0) {
|
||||||
float sceneDepth = texture(sceneDepthMap, texCoord0).x;
|
vec4 groupColor = computeGroupOutline(groupId, outlinedDepth, i, texCoord0);
|
||||||
// Transform to linear depth for better precision
|
finalColor.rgb = mix(finalColor.rgb, groupColor.rgb, groupColor.a);
|
||||||
outlinedDepth = -evalZeyeFromZdb(outlinedDepth);
|
// If first group we encounter then don't mix the color
|
||||||
sceneDepth = -evalZeyeFromZdb(sceneDepth);
|
finalColor.rgb = finalColor.a==0 ? groupColor.rgb : finalColor.rgb;
|
||||||
|
finalColor.a = min(1, finalColor.a+groupColor.a*(1-finalColor.a));
|
||||||
// Are we occluded?
|
|
||||||
if (sceneDepth < (outlinedDepth-LINEAR_DEPTH_BIAS)) {
|
|
||||||
intensity = params._fillOpacityOccluded;
|
|
||||||
} else {
|
|
||||||
intensity = params._fillOpacityUnoccluded;
|
|
||||||
}
|
}
|
||||||
<@else@>
|
groupMask <<= 1;
|
||||||
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<params._blurKernelSize ; y++) {
|
|
||||||
uv = lineStartUv;
|
|
||||||
lineStartUv.y += deltaUv.y;
|
|
||||||
|
|
||||||
if (uv.y>=0.0 && uv.y<=1.0) {
|
|
||||||
for (x=0 ; x<params._blurKernelSize ; x++) {
|
|
||||||
if (uv.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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
outFragColor = vec4(params._color.rgb, intensity);
|
if (finalColor.a < OPACITY_EPSILON) {
|
||||||
|
discard;
|
||||||
|
}
|
||||||
|
outFragColor = finalColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
<@endfunc@>
|
<@endfunc@>
|
||||||
|
|
|
@ -94,6 +94,8 @@ glm::vec4 encodeIdToColor(unsigned int id) {
|
||||||
unsigned char id;
|
unsigned char id;
|
||||||
} groupId;
|
} 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);
|
assert(id < 254);
|
||||||
groupId.id = id+1;
|
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
|
// Normalize. Since we put 2 bits into each color component, each component has a maximum
|
||||||
// value of 3.
|
// value of 3.
|
||||||
idColor /= 3.f;
|
idColor /= GROUP_ID_COLOR_COMPONENT_MAX;
|
||||||
return idColor;
|
return idColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,15 +252,19 @@ void DrawOutline::run(const render::RenderContextPointer& renderContext, const I
|
||||||
if (_hasConfigurationChanged)
|
if (_hasConfigurationChanged)
|
||||||
{
|
{
|
||||||
auto& configuration = _configuration.edit();
|
auto& configuration = _configuration.edit();
|
||||||
configuration._color = _color;
|
|
||||||
configuration._intensity = _intensity;
|
for (auto groupId = 0; groupId < MAX_GROUP_COUNT; groupId++) {
|
||||||
configuration._fillOpacityUnoccluded = _fillOpacityUnoccluded;
|
auto& groupConfig = configuration._groups[groupId];
|
||||||
configuration._fillOpacityOccluded = _fillOpacityOccluded;
|
|
||||||
configuration._threshold = _threshold;
|
groupConfig._color = _color;
|
||||||
configuration._blurKernelSize = _blurKernelSize;
|
groupConfig._intensity = _intensity;
|
||||||
configuration._size.x = (_size * framebufferSize.y) / framebufferSize.x;
|
groupConfig._fillOpacityUnoccluded = _fillOpacityUnoccluded;
|
||||||
configuration._size.y = _size;
|
groupConfig._fillOpacityOccluded = _fillOpacityOccluded;
|
||||||
configuration._idColor = encodeIdToColor(0);
|
groupConfig._threshold = _threshold;
|
||||||
|
groupConfig._blurKernelSize = _blurKernelSize;
|
||||||
|
groupConfig._size.x = (_size * framebufferSize.y) / framebufferSize.x;
|
||||||
|
groupConfig._size.y = _size;
|
||||||
|
}
|
||||||
_hasConfigurationChanged = false;
|
_hasConfigurationChanged = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,15 +278,15 @@ void DrawOutline::run(const render::RenderContextPointer& renderContext, const I
|
||||||
batch.setModelTransform(gpu::Framebuffer::evalSubregionTexcoordTransform(framebufferSize, args->_viewport));
|
batch.setModelTransform(gpu::Framebuffer::evalSubregionTexcoordTransform(framebufferSize, args->_viewport));
|
||||||
batch.setPipeline(pipeline);
|
batch.setPipeline(pipeline);
|
||||||
|
|
||||||
|
auto enabledGroupsLoc = pipeline->getProgram()->getUniforms().findLocation("enabledGroupsMask");
|
||||||
|
|
||||||
batch.setUniformBuffer(OUTLINE_PARAMS_SLOT, _configuration);
|
batch.setUniformBuffer(OUTLINE_PARAMS_SLOT, _configuration);
|
||||||
batch.setUniformBuffer(FRAME_TRANSFORM_SLOT, frameTransform->getFrameTransformBuffer());
|
batch.setUniformBuffer(FRAME_TRANSFORM_SLOT, frameTransform->getFrameTransformBuffer());
|
||||||
batch.setResourceTexture(SCENE_DEPTH_SLOT, sceneDepthBuffer->getPrimaryDepthTexture());
|
batch.setResourceTexture(SCENE_DEPTH_SLOT, sceneDepthBuffer->getPrimaryDepthTexture());
|
||||||
batch.setResourceTexture(OUTLINED_DEPTH_SLOT, outlinedDepthTexture);
|
batch.setResourceTexture(OUTLINED_DEPTH_SLOT, outlinedDepthTexture);
|
||||||
batch.setResourceTexture(OUTLINED_ID_SLOT, outlinedIdTexture);
|
batch.setResourceTexture(OUTLINED_ID_SLOT, outlinedIdTexture);
|
||||||
|
batch._glUniform1i(enabledGroupsLoc, 1);
|
||||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||||
|
|
||||||
// Restore previous frame buffer
|
|
||||||
batch.setFramebuffer(destinationFrameBuffer);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,9 +94,13 @@ signals:
|
||||||
};
|
};
|
||||||
|
|
||||||
class DrawOutline {
|
class DrawOutline {
|
||||||
|
private:
|
||||||
|
|
||||||
|
#include "Outline_shared.slh"
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum {
|
enum {
|
||||||
MAX_GROUP_COUNT = 7
|
MAX_GROUP_COUNT = GROUP_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
using Inputs = render::VaryingSet4<DeferredFrameTransformPointer, OutlineRessourcesPointer, DeferredFramebufferPointer, gpu::FramebufferPointer>;
|
using Inputs = render::VaryingSet4<DeferredFrameTransformPointer, OutlineRessourcesPointer, DeferredFramebufferPointer, gpu::FramebufferPointer>;
|
||||||
|
@ -116,12 +120,14 @@ private:
|
||||||
OUTLINED_ID_SLOT,
|
OUTLINED_ID_SLOT,
|
||||||
|
|
||||||
OUTLINE_PARAMS_SLOT = 0,
|
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<OutlineParameters>;
|
using OutlineConfigurationBuffer = gpu::StructBuffer<OutlineConfiguration>;
|
||||||
|
|
||||||
static const gpu::PipelinePointer& getPipeline(bool isFilled);
|
static const gpu::PipelinePointer& getPipeline(bool isFilled);
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,10 @@
|
||||||
# define VEC4 vec4
|
# define VEC4 vec4
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define GROUP_COUNT 7
|
||||||
|
#define GROUP_ID_COLOR_COMPONENT_BITS 2
|
||||||
|
#define GROUP_ID_COLOR_COMPONENT_MAX 3
|
||||||
|
|
||||||
struct OutlineParameters
|
struct OutlineParameters
|
||||||
{
|
{
|
||||||
VEC3 _color;
|
VEC3 _color;
|
||||||
|
@ -18,8 +22,6 @@ struct OutlineParameters
|
||||||
float _fillOpacityUnoccluded;
|
float _fillOpacityUnoccluded;
|
||||||
float _fillOpacityOccluded;
|
float _fillOpacityOccluded;
|
||||||
|
|
||||||
VEC4 _idColor;
|
|
||||||
|
|
||||||
float _threshold;
|
float _threshold;
|
||||||
int _blurKernelSize;
|
int _blurKernelSize;
|
||||||
float padding2;
|
float padding2;
|
||||||
|
|
Loading…
Reference in a new issue