0030476: Visualization, Path Tracing - Adaptive Screen Sampling leads to unstable...
[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 #ifdef ADAPTIVE_SAMPLING
24 //! Wrapper over imageLoad()+imageStore() having similar syntax as imageAtomicAdd().
25 //! Modifies one component of 3Wx2H uRenderImage:
26 //! |RGL| Red, Green, Luminance
27 //! |SBH| Samples, Blue, Hit time transformed into OpenGL NDC space
28 //! Returns previous value of the component.
29 float addRenderImageComp (in ivec2 theFrag, in ivec2 theComp, in float theVal)
30 {
31   ivec2 aCoord = ivec2 (3 * theFrag.x + theComp.x,
32                         2 * theFrag.y + theComp.y);
33 #ifdef ADAPTIVE_SAMPLING_ATOMIC
34   return imageAtomicAdd (uRenderImage, aCoord, theVal);
35 #else
36   float aVal = imageLoad (uRenderImage, aCoord).x;
37   imageStore (uRenderImage, aCoord, vec4 (aVal + theVal));
38   return aVal;
39 #endif
40 }
41 #endif
42
43 // =======================================================================
44 // function : main
45 // purpose  :
46 // =======================================================================
47 void main (void)
48 {
49   SeedRand (uFrameRndSeed, uWinSizeX, uBlockedRngEnabled == 0 ? 1 : 16);
50
51 #ifndef PATH_TRACING
52
53   SRay aRay = GenerateRay (vPixel);
54
55 #else
56
57   ivec2 aFragCoord = ivec2 (gl_FragCoord.xy);
58
59 #ifdef ADAPTIVE_SAMPLING
60
61 #ifdef ADAPTIVE_SAMPLING_ATOMIC
62   ivec2 aTileXY = imageLoad (uOffsetImage, aFragCoord / uTileSize).xy * uTileSize;
63   if (aTileXY.x < 0) { discard; }
64
65   ivec2 aRealBlockSize = ivec2 (min (uWinSizeX - aTileXY.x, uTileSize.x),
66                                 min (uWinSizeY - aTileXY.y, uTileSize.y));
67
68   aFragCoord.x = aTileXY.x + (aFragCoord.x % aRealBlockSize.x);
69   aFragCoord.y = aTileXY.y + (aFragCoord.y % aRealBlockSize.y);
70 #else
71   int aNbTileSamples = imageAtomicAdd (uTilesImage, aFragCoord / uTileSize, int(-1));
72   if (aNbTileSamples <= 0)
73   {
74     discard;
75   }
76 #endif
77
78 #endif // ADAPTIVE_SAMPLING
79
80   vec2 aPnt = vec2 (aFragCoord.x + RandFloat(),
81                     aFragCoord.y + RandFloat());
82
83   SRay aRay = GenerateRay (aPnt / vec2 (uWinSizeX, uWinSizeY));
84
85 #endif // PATH_TRACING
86
87   vec3 aInvDirect = InverseDirection (aRay.Direct);
88
89 #ifdef PATH_TRACING
90
91 #ifndef ADAPTIVE_SAMPLING
92
93   vec4 aColor = PathTrace (aRay, aInvDirect, uAccumSamples);
94
95 #else
96
97   float aNbSamples = addRenderImageComp (aFragCoord, ivec2 (0, 1), 1.0);
98   vec4 aColor = PathTrace (aRay, aInvDirect, int (aNbSamples));
99
100 #endif
101
102   if (any (isnan (aColor.rgb)))
103   {
104     aColor.rgb = ZERO;
105   }
106
107   aColor.rgb = min (aColor.rgb, vec3 (uMaxRadiance));
108
109 #ifdef ADAPTIVE_SAMPLING
110
111   // accumulate RGB color and depth
112   addRenderImageComp (aFragCoord, ivec2 (0, 0), aColor.r);
113   addRenderImageComp (aFragCoord, ivec2 (1, 0), aColor.g);
114   addRenderImageComp (aFragCoord, ivec2 (1, 1), aColor.b);
115   addRenderImageComp (aFragCoord, ivec2 (2, 1), aColor.w);
116
117   if (int (aNbSamples) % 2 == 0) // accumulate luminance for even samples only
118   {
119     addRenderImageComp (aFragCoord, ivec2 (2, 0), dot (LUMA, aColor.rgb));
120   }
121
122 #else
123
124   if (uAccumSamples == 0)
125   {
126     OutColor = aColor;
127   }
128   else
129   {
130     OutColor = mix (texture2D (uAccumTexture, vPixel), aColor, 1.f / (uAccumSamples + 1));
131   }
132
133 #endif // ADAPTIVE_SAMPLING
134
135 #else
136
137   OutColor = clamp (Radiance (aRay, aInvDirect), 0.f, 1.f);
138
139 #endif // PATH_TRACING
140 }