1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
/* Based on:
* "Stochastic Screen Space Reflections"
* by Tomasz Stachowiak.
* https://www.ea.com/frostbite/news/stochastic-screen-space-reflections
* and
* "Stochastic all the things: raytracing in hybrid real-time rendering"
* by Tomasz Stachowiak.
* https://media.contentapi.ea.com/content/dam/ea/seed/presentations/dd18-seed-raytracing-in-hybrid-real-time-rendering.pdf
*/
uniform ivec2 halfresOffset;
struct HitData {
/** Hit direction scaled by intersection time. */
vec3 hit_dir;
/** Screen space [0..1] depth of the reflection hit position, or -1.0 for planar reflections. */
float hit_depth;
/** Inverse probability of ray spawning in this direction. */
float ray_pdf_inv;
/** True if ray has hit valid geometry. */
bool is_hit;
/** True if ray was generated from a planar reflection probe. */
bool is_planar;
};
void encode_hit_data(HitData data, vec3 hit_sP, vec3 vP, out vec4 hit_data, out float hit_depth)
{
vec3 hit_vP = get_view_space_from_depth(hit_sP.xy, hit_sP.z);
hit_data.xyz = hit_vP - vP;
hit_depth = data.is_planar ? -1.0 : hit_sP.z;
/* Record 1.0 / pdf to reduce the computation in the resolve phase. */
/* Encode hit validity in sign. */
hit_data.w = data.ray_pdf_inv * ((data.is_hit) ? 1.0 : -1.0);
}
HitData decode_hit_data(vec4 hit_data, float hit_depth)
{
HitData data;
data.hit_dir.xyz = hit_data.xyz;
data.hit_depth = hit_depth;
data.is_planar = (hit_depth == -1.0);
data.ray_pdf_inv = abs(hit_data.w);
data.is_hit = (hit_data.w > 0.0);
return data;
}
/* Blue noise categorised into 4 sets of samples.
* See "Stochastic all the things" presentation slide 32-37. */
const int resolve_samples_count = 9;
const vec2 resolve_sample_offsets[36] = vec2[36](
/* Set 1. */
/* First Ring (2x2). */
vec2(0, 0),
/* Second Ring (6x6). */
vec2(-1, 3),
vec2(1, 3),
vec2(-1, 1),
vec2(3, 1),
vec2(-2, 0),
vec2(3, 0),
vec2(2, -1),
vec2(1, -2),
/* Set 2. */
/* First Ring (2x2). */
vec2(1, 1),
/* Second Ring (6x6). */
vec2(-2, 3),
vec2(3, 3),
vec2(0, 2),
vec2(2, 2),
vec2(-2, -1),
vec2(1, -1),
vec2(0, -2),
vec2(3, -2),
/* Set 3. */
/* First Ring (2x2). */
vec2(0, 1),
/* Second Ring (6x6). */
vec2(0, 3),
vec2(3, 2),
vec2(-2, 1),
vec2(2, 1),
vec2(-1, 0),
vec2(-2, -2),
vec2(0, -1),
vec2(2, -2),
/* Set 4. */
/* First Ring (2x2). */
vec2(1, 0),
/* Second Ring (6x6). */
vec2(2, 3),
vec2(-2, 2),
vec2(-1, 2),
vec2(1, 2),
vec2(2, 0),
vec2(-1, -1),
vec2(3, -1),
vec2(-1, -2));
|