R2 Shaders
R2ShadowVariance.h
Go to the documentation of this file.
1 #ifndef R2_SHADOW_VARIANCE_H
2 #define R2_SHADOW_VARIANCE_H
3 
4 /// \file R2ShadowVariance.h
5 /// \brief Functions for variance shadows
6 
7 #include "R2LogDepth.h"
8 
9 /// A variance shadow
11  /// The minimum level of attenuation by the shadow (0.0 means "completely attenuated", 1.0 means "no attenuation")
13 
14  /// The minimum variance level. Used to eliminate shadow bias. Typically `0.00002f` will suffice for all scenes.
16 
17  /// The amount of bleed reduction (typically `[0.2, 1.0]`). Setting this value too high results in loss of detail in shadows.
19 
20  /// The logarithmic depth coefficient that was used to encode depth values
22 
23  /// The variance shadow map
24  sampler2D map;
25 };
26 
27 /// Compute an upper bound on the probability that the position at
28 /// `depth` is in shadow.
29 ///
30 /// @param s The shadow
31 /// @param moments The sampled shadow map depth moments
32 /// @param depth The current depth
33 ///
34 /// @return A value between `0.0` and `1.0`, where 1.0 indicates that the
35 /// area is certainly in shadow.
36 
37 float
39  const R2_shadow_variance_t s,
40  const vec2 moments,
41  const float depth)
42 {
43  float p = float (depth <= moments.x);
44  float variance = max (s.variance_minimum, moments.y - (moments.x * moments.x));
45  float delta = depth - moments.x;
46  float p_max = variance / (variance + (delta * delta));
47  return max (p, p_max);
48 }
49 
50 /// A linear step function that maps all values less than `min` to `min`, all
51 /// values greater than `max` to `max`, and linearly scales all values in `[min, max]`
52 /// to `[min, max]`.
53 ///
54 /// @param min The minimum value
55 /// @param max The maximum value
56 /// @param x The value to scale
57 ///
58 /// @return A linearly scaled value
59 
60 float
62  const float min,
63  const float max,
64  const float x)
65 {
66  float vsm = x - min;
67  float msm = max - min;
68  return clamp (vsm / msm, 0.0, 1.0);
69 }
70 
71 /// Apply light bleed reduction to the given shadow probability.
72 ///
73 /// @param s The shadow
74 /// @param p The shadow probability
75 ///
76 /// @return `p` with light bleed reduction applied
77 
78 float
80  const R2_shadow_variance_t s,
81  const float p_max)
82 {
83  return R2_varianceLinearStep (s.bleed_reduction, 1.0, p_max);
84 }
85 
86 /// Calculate a shadow factor for the given position.
87 ///
88 /// @param s The shadow
89 /// @param v The projective light vectors, including the position in various light coordinate spaces
90 ///
91 /// @return `s.factor_minimum` if the point is fully in shadow, or `1.0` if the point is
92 // definitely not in shadow.
93 
94 float
96  const R2_shadow_variance_t s,
98 {
99  float pos_light_depth =
103 
104  // Sample the variance map for the depth distribution
105  vec2 moments =
106  texture (s.map, v.surface_light_uv.xy).xy;
107 
108  // Calculate the probability that the point is in shadow.
109  float p_max =
110  R2_varianceChebyshevUpperBound (s, moments, pos_light_depth);
111 
112  // Apply light bleeding reduction
113  float p_reduced =
115 
116  return max (p_reduced, s.factor_minimum);
117 }
118 
119 #endif // R2_SHADOW_VARIANCE_H
vec4 surface_light_eye
The surface position in light-eye-space.
float R2_logDepthEncodePartial(const float z, const float depth_coefficient)
Definition: R2LogDepth.h:33
Vectors used when calculating projective lighting.
sampler2D map
The variance shadow map.
float variance_minimum
The minimum variance level. Used to eliminate shadow bias. Typically 0.00002f will suffice for all sc...
vec2 surface_light_uv
The surface position as UV coordinates from the perspective of the light.
float R2_varianceShadowFactor(const R2_shadow_variance_t s, const R2_light_projective_vectors_t v)
float R2_varianceLinearStep(const float min, const float max, const float x)
float R2_varianceLightBleedReduction(const R2_shadow_variance_t s, const float p_max)
float bleed_reduction
The amount of bleed reduction (typically [0.2, 1.0]). Setting this value too high results in loss of ...
float R2_logDepthPrepareEyeZ(const float z)
Definition: R2LogDepth.h:15
Logarithmic depth functions.
float depth_coefficient
The logarithmic depth coefficient that was used to encode depth values.
float factor_minimum
The minimum level of attenuation by the shadow (0.0 means "completely attenuated", 1.0 means "no attenuation")
A variance shadow.
float R2_varianceChebyshevUpperBound(const R2_shadow_variance_t s, const vec2 moments, const float depth)