overte-HifiExperiments/libraries/render-utils/src/Outline.slf

90 lines
2.8 KiB
Text

<@include gpu/Config.slh@>
<$VERSION_HEADER$>
//
// Add outline effect based on two zbuffers : one containing the total scene z and another
// with the z of only the objects to be outlined
//
// Created by Olivier Prat on 08/09/2017
// 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 Outline_shared.slh@>
uniform outlineParamsBuffer {
OutlineParameters params;
};
uniform sampler2D sceneDepthMap;
uniform sampler2D outlinedDepthMap;
in vec2 varTexCoord0;
out vec4 outFragColor;
const float FAR_Z = 1.0;
const float LINEAR_DEPTH_BIAS = 5e-3;
const float OPACITY_EPSILON = 5e-3;
void main(void) {
float outlinedDepth = texture(outlinedDepthMap, varTexCoord0).x;
float intensity = 0.0;
if (outlinedDepth < FAR_Z) {
// We're not on the far plane so we are on the outlined object, thus no outline to do!
// But maybe we need to fill the interior
// TODO: this should be done as another shader with switch done on CPU
if (params._fillOpacityUnoccluded>OPACITY_EPSILON && params._fillOpacityUnoccluded>OPACITY_EPSILON) {
float sceneDepth = texture(sceneDepthMap, varTexCoord0).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;
}
} else {
discard;
}
} else {
float weight = 0.0;
vec2 deltaUv = params._size / params._blurKernelSize;
vec2 lineStartUv = varTexCoord0 - 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;
intensity += (outlinedDepth < FAR_Z) ? 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);
}