e3937ff992e235e06e195024b4231632c0d4802f
[occt.git] / src / Shaders / RaytraceRender.fs
1 out vec4 OutColor;
2
3 // Seed for random number generator (generated on CPU).
4 uniform int uFrameRndSeed;
5
6 //! Enables/disables using of single RNG seed for 16x16 image
7 //! blocks. Increases performance up to 4x, but the noise has
8 //! become structured. Can be used fo final rendering.
9 uniform int uBlockedRngEnabled;
10
11 //! Number of previously rendered frames (used in non-ISS mode).
12 uniform int uAccumSamples;
13
14 #ifndef ADAPTIVE_SAMPLING
15   //! Input image with previously accumulated samples.
16   uniform sampler2D uAccumTexture;
17 #endif
18
19 //! Maximum radiance that can be added to the pixel.
20 //! Decreases noise level, but introduces some bias.
21 uniform float uMaxRadiance = 50.f;
22
23 // =======================================================================
24 // function : main
25 // purpose  :
26 // =======================================================================
27 void main (void)
28 {
29   SeedRand (uFrameRndSeed, uWinSizeX, uBlockedRngEnabled == 0 ? 1 : 16);
30
31 #ifndef PATH_TRACING
32
33   SRay aRay = GenerateRay (vPixel);
34
35 #else
36
37   ivec2 aFragCoord = ivec2 (gl_FragCoord.xy);
38
39 #ifdef ADAPTIVE_SAMPLING
40
41   ivec2 aTileXY = imageLoad (uOffsetImage, ivec2 (aFragCoord.x / BLOCK_SIZE,
42                                                   aFragCoord.y / BLOCK_SIZE)).xy;
43
44   ivec2 aRealBlockSize = ivec2 (min (uWinSizeX - aTileXY.x, BLOCK_SIZE),
45                                 min (uWinSizeY - aTileXY.y, BLOCK_SIZE));
46
47   aFragCoord.x = aTileXY.x + (aFragCoord.x % aRealBlockSize.x);
48   aFragCoord.y = aTileXY.y + (aFragCoord.y % aRealBlockSize.y);
49
50 #endif // ADAPTIVE_SAMPLING
51
52   vec2 aPnt = vec2 (aFragCoord.x + RandFloat(),
53                     aFragCoord.y + RandFloat());
54
55   SRay aRay = GenerateRay (aPnt / vec2 (uWinSizeX, uWinSizeY));
56
57 #endif // PATH_TRACING
58
59   vec3 aInvDirect = InverseDirection (aRay.Direct);
60
61 #ifdef PATH_TRACING
62
63 #ifndef ADAPTIVE_SAMPLING
64
65   vec4 aColor = PathTrace (aRay, aInvDirect, uAccumSamples);
66
67 #else
68
69   float aNbSamples = imageAtomicAdd (uRenderImage, ivec2 (3 * aFragCoord.x + 0,
70                                                           2 * aFragCoord.y + 1), 1.0);
71
72   vec4 aColor = PathTrace (aRay, aInvDirect, int (aNbSamples));
73
74 #endif
75
76   if (any (isnan (aColor.rgb)))
77   {
78     aColor.rgb = ZERO;
79   }
80
81   aColor.rgb = min (aColor.rgb, vec3 (uMaxRadiance));
82
83 #ifdef ADAPTIVE_SAMPLING
84
85   // accumulate RGB color and depth
86   imageAtomicAdd (uRenderImage, ivec2 (3 * aFragCoord.x + 0,
87                                        2 * aFragCoord.y + 0), aColor.r);
88   imageAtomicAdd (uRenderImage, ivec2 (3 * aFragCoord.x + 1,
89                                        2 * aFragCoord.y + 0), aColor.g);
90   imageAtomicAdd (uRenderImage, ivec2 (3 * aFragCoord.x + 1,
91                                        2 * aFragCoord.y + 1), aColor.b);
92   imageAtomicAdd (uRenderImage, ivec2 (3 * aFragCoord.x + 2,
93                                        2 * aFragCoord.y + 1), aColor.w);
94
95   if (int (aNbSamples) % 2 == 0) // accumulate luminance for even samples only
96   {
97     imageAtomicAdd (uRenderImage, ivec2 (3 * aFragCoord.x + 2,
98                                          2 * aFragCoord.y + 0), dot (LUMA, aColor.rgb));
99   }
100
101 #else
102
103   if (uAccumSamples == 0)
104   {
105     OutColor = aColor;
106   }
107   else
108   {
109     OutColor = mix (texture2D (uAccumTexture, vPixel), aColor, 1.f / (uAccumSamples + 1));
110   }
111
112 #endif // ADAPTIVE_SAMPLING
113
114 #else
115
116   OutColor = clamp (Radiance (aRay, aInvDirect), 0.f, 1.f);
117
118 #endif // PATH_TRACING
119 }