mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-06-21 07:21:00 +02:00
99 lines
2.6 KiB
Text
Executable file
99 lines
2.6 KiB
Text
Executable file
<!
|
|
// Shadow.slh
|
|
// libraries/render-utils/src
|
|
//
|
|
// Created by Sam Gateau on 1/4/15.
|
|
// Copyright 2013 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
|
|
!>
|
|
<@if not SHADOW_SLH@>
|
|
<@def SHADOW_SLH@>
|
|
|
|
// the shadow texture
|
|
uniform sampler2DShadow shadowMap;
|
|
|
|
struct ShadowTransform {
|
|
mat4 projection;
|
|
mat4 viewInverse;
|
|
|
|
float bias;
|
|
float scale;
|
|
};
|
|
|
|
uniform shadowTransformBuffer {
|
|
ShadowTransform _shadowTransform;
|
|
};
|
|
|
|
mat4 getShadowViewInverse() {
|
|
return _shadowTransform.viewInverse;
|
|
}
|
|
|
|
mat4 getShadowProjection() {
|
|
return _shadowTransform.projection;
|
|
}
|
|
|
|
float getShadowScale() {
|
|
return _shadowTransform.scale;
|
|
}
|
|
|
|
float getShadowBias() {
|
|
return _shadowTransform.bias;
|
|
}
|
|
|
|
// Compute the texture coordinates from world coordinates
|
|
vec4 evalShadowTexcoord(vec4 position) {
|
|
mat4 biasMatrix = mat4(
|
|
0.5, 0.0, 0.0, 0.0,
|
|
0.0, 0.5, 0.0, 0.0,
|
|
0.0, 0.0, 0.5, 0.0,
|
|
0.5, 0.5, 0.5, 1.0);
|
|
float bias = -getShadowBias();
|
|
|
|
vec4 shadowCoord = biasMatrix * getShadowProjection() * getShadowViewInverse() * position;
|
|
return vec4(shadowCoord.xy, shadowCoord.z + bias, 1.0);
|
|
}
|
|
|
|
// Sample the shadowMap with PCF (built-in)
|
|
float fetchShadow(vec3 shadowTexcoord) {
|
|
return texture(shadowMap, shadowTexcoord);
|
|
}
|
|
|
|
vec2 PCFkernel[4] = vec2[4](
|
|
vec2(-1.5, 0.5),
|
|
vec2(0.5, 0.5),
|
|
vec2(-1.5, -1.5),
|
|
vec2(0.5, -1.5)
|
|
);
|
|
|
|
float evalShadowAttenuationPCF(vec4 position, vec4 shadowTexcoord) {
|
|
float pcfRadius = 3.0;
|
|
float shadowScale = getShadowScale();
|
|
|
|
// Offset for efficient PCF, see http://http.developer.nvidia.com/GPUGems/gpugems_ch11.html
|
|
vec2 offset = pcfRadius * step(fract(position.xy), vec2(0.5, 0.5));
|
|
|
|
float shadowAttenuation = (0.25 * (
|
|
fetchShadow(shadowTexcoord.xyz + shadowScale * vec3(offset + PCFkernel[0], 0.0)) +
|
|
fetchShadow(shadowTexcoord.xyz + shadowScale * vec3(offset + PCFkernel[1], 0.0)) +
|
|
fetchShadow(shadowTexcoord.xyz + shadowScale * vec3(offset + PCFkernel[2], 0.0)) +
|
|
fetchShadow(shadowTexcoord.xyz + shadowScale * vec3(offset + PCFkernel[3], 0.0))
|
|
));
|
|
|
|
return shadowAttenuation;
|
|
}
|
|
|
|
float evalShadowAttenuation(vec4 position) {
|
|
vec4 shadowTexcoord = evalShadowTexcoord(position);
|
|
if (shadowTexcoord.x < 0.0 || shadowTexcoord.x > 1.0 ||
|
|
shadowTexcoord.y < 0.0 || shadowTexcoord.y > 1.0 ||
|
|
shadowTexcoord.z < 0.0 || shadowTexcoord.z > 1.0) {
|
|
// If a point is not in the map, do not attenuate
|
|
return 1.0;
|
|
}
|
|
|
|
return evalShadowAttenuationPCF(position, shadowTexcoord);
|
|
}
|
|
|
|
<@endif@>
|