<@include gpu/Config.slh@><$VERSION_HEADER$><!// Highlight.slh// fragment shader//// Created by Olivier Prat on 9/7/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!><@include DeferredTransform.slh@><$declareDeferredFrameTransform()$><@include Highlight_shared.slh@>UNIFORM_BUFFER(RENDER_UTILS_BUFFER_HIGHLIGHT_PARAMS, highlightParamsBuffer) { HighlightParameters params;};TEXTURE(RENDER_UTILS_TEXTURE_HIGHLIGHT_SCENE_DEPTH, sampler2D, sceneDepthMap);TEXTURE(RENDER_UTILS_TEXTURE_HIGHLIGHT_DEPTH, sampler2D, highlightedDepthMap);INPUT(0, vec2, varTexCoord0);OUTPUT(0, vec4, outFragColor);const float FAR_Z = 1.0;const float OPACITY_EPSILON = 5e-3;<@func main(IS_FILLED)@>void main(void) { // 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 // sides of the silhouette float highlightedDepth = texture(highlightedDepthMap, varTexCoord0).x; if (highlightedDepth < FAR_Z) { // We're not on the far plane so we are on the highlighted object, thus no outline to do!<@if IS_FILLED@> // But we need to fill the interior float sceneDepth = texture(sceneDepthMap, varTexCoord0).x; // Transform to linear depth for better precision highlightedDepth = -evalZeyeFromZdb(highlightedDepth); sceneDepth = -evalZeyeFromZdb(sceneDepth); outFragColor = mix(vec4(params._fillUnoccludedColor, params._fillUnoccludedAlpha), vec4(params._fillOccludedColor, params._fillOccludedAlpha), float(sceneDepth < highlightedDepth));<@else@> discard;<@endif@> } else { vec2 halfTexel = getInvWidthHeight() / 2.0; vec2 texCoord0 = varTexCoord0+halfTexel; float weight = 0.0; vec2 deltaUv = params._size / float(params._blurKernelSize); vec2 lineStartUv = texCoord0 - params._size / 2.0; vec2 uv; int x; int y; float intensity = 0.0; float outlinedDepth = 0.0; float sumOutlineDepth = 0.0; 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(highlightedDepthMap, uv).x; float touch = (outlinedDepth < FAR_Z) ? 1.0 : 0.0; sumOutlineDepth = max(outlinedDepth * touch, sumOutlineDepth); intensity += touch; weight += 1.0; } uv.x += deltaUv.x; } } } sumOutlineDepth = mix(FAR_Z, sumOutlineDepth, float(intensity > 0.0)); intensity /= weight; if (intensity < OPACITY_EPSILON) { discard; } intensity = min(1.0, intensity / params._threshold); // But we need to check the scene depth against the depth of the outline float sceneDepth = texture(sceneDepthMap, texCoord0).x; // Transform to linear depth for better precision outlinedDepth = -evalZeyeFromZdb(sumOutlineDepth); sceneDepth = -evalZeyeFromZdb(sceneDepth); // Are we occluded? outFragColor = mix(vec4(params._outlineUnoccludedColor, intensity * params._outlineUnoccludedAlpha), vec4(params._outlineOccludedColor, intensity * params._outlineOccludedAlpha), float(sceneDepth < outlinedDepth)); }}<@endfunc@>
<@include gpu/Config.slh@>
<$VERSION_HEADER$>
<!
// Highlight.slh
// fragment shader
//
// Created by Olivier Prat on 9/7/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
!>
<@include DeferredTransform.slh@>
<$declareDeferredFrameTransform()$>
<@include Highlight_shared.slh@>
UNIFORM_BUFFER(RENDER_UTILS_BUFFER_HIGHLIGHT_PARAMS, highlightParamsBuffer) {
HighlightParameters params;
};
TEXTURE(RENDER_UTILS_TEXTURE_HIGHLIGHT_SCENE_DEPTH, sampler2D, sceneDepthMap);
TEXTURE(RENDER_UTILS_TEXTURE_HIGHLIGHT_DEPTH, sampler2D, highlightedDepthMap);
INPUT(0, vec2, varTexCoord0);
OUTPUT(0, vec4, outFragColor);
const float FAR_Z = 1.0;
const float OPACITY_EPSILON = 5e-3;
<@func main(IS_FILLED)@>
void main(void) {
// 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
// sides of the silhouette
float highlightedDepth = texture(highlightedDepthMap, varTexCoord0).x;
if (highlightedDepth < FAR_Z) {
// We're not on the far plane so we are on the highlighted object, thus no outline to do!
<@if IS_FILLED@>
// But we need to fill the interior
float sceneDepth = texture(sceneDepthMap, varTexCoord0).x;
// Transform to linear depth for better precision
highlightedDepth = -evalZeyeFromZdb(highlightedDepth);
sceneDepth = -evalZeyeFromZdb(sceneDepth);
outFragColor = mix(vec4(params._fillUnoccludedColor, params._fillUnoccludedAlpha),
vec4(params._fillOccludedColor, params._fillOccludedAlpha),
float(sceneDepth < highlightedDepth));
<@else@>
discard;
<@endif@>
} else {
vec2 halfTexel = getInvWidthHeight() / 2.0;
vec2 texCoord0 = varTexCoord0+halfTexel;
float weight = 0.0;
vec2 deltaUv = params._size / float(params._blurKernelSize);
vec2 lineStartUv = texCoord0 - params._size / 2.0;
vec2 uv;
int x;
int y;
float intensity = 0.0;
float outlinedDepth = 0.0;
float sumOutlineDepth = 0.0;
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(highlightedDepthMap, uv).x;
float touch = (outlinedDepth < FAR_Z) ? 1.0 : 0.0;
sumOutlineDepth = max(outlinedDepth * touch, sumOutlineDepth);
intensity += touch;
weight += 1.0;
}
uv.x += deltaUv.x;
}
}
}
sumOutlineDepth = mix(FAR_Z, sumOutlineDepth, float(intensity > 0.0));
intensity /= weight;
if (intensity < OPACITY_EPSILON) {
discard;
}
intensity = min(1.0, intensity / params._threshold);
// But we need to check the scene depth against the depth of the outline
float sceneDepth = texture(sceneDepthMap, texCoord0).x;
// Transform to linear depth for better precision
outlinedDepth = -evalZeyeFromZdb(sumOutlineDepth);
sceneDepth = -evalZeyeFromZdb(sceneDepth);
// Are we occluded?
outFragColor = mix(vec4(params._outlineUnoccludedColor, intensity * params._outlineUnoccludedAlpha),
vec4(params._outlineOccludedColor, intensity * params._outlineOccludedAlpha),
float(sceneDepth < outlinedDepth));
}
}
<@endfunc@>