3 // Seed for random number generator (generated on CPU).
4 uniform int uFrameRndSeed;
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;
11 #ifndef ADAPTIVE_SAMPLING
12 //! Weight of current frame related to accumulated samples.
13 uniform float uSampleWeight;
15 //! Input accumulated image.
16 uniform sampler2D uAccumTexture;
19 //! Maximum radiance that can be added to the pixel. Decreases noise
20 //! level, but introduces some bias.
21 #define MAX_RADIANCE vec3 (25.f)
23 // =======================================================================
26 // =======================================================================
29 SeedRand (uFrameRndSeed, uWinSizeX, uBlockedRngEnabled == 0 ? 1 : 16);
33 SRay aRay = GenerateRay (vPixel);
37 ivec2 aFragCoord = ivec2 (gl_FragCoord.xy);
39 #ifdef ADAPTIVE_SAMPLING
41 ivec2 aTileXY = imageLoad (uOffsetImage, ivec2 (aFragCoord.x / BLOCK_SIZE,
42 aFragCoord.y / BLOCK_SIZE)).xy;
44 ivec2 aRealBlockSize = ivec2 (min (uWinSizeX - aTileXY.x, BLOCK_SIZE),
45 min (uWinSizeY - aTileXY.y, BLOCK_SIZE));
47 aFragCoord.x = aTileXY.x + (aFragCoord.x % aRealBlockSize.x);
48 aFragCoord.y = aTileXY.y + (aFragCoord.y % aRealBlockSize.y);
50 #endif // ADAPTIVE_SAMPLING
52 vec2 aPnt = vec2 (aFragCoord.x + RandFloat(),
53 aFragCoord.y + RandFloat());
55 SRay aRay = GenerateRay (aPnt / vec2 (uWinSizeX, uWinSizeY));
57 #endif // PATH_TRACING
59 vec3 aInvDirect = InverseDirection (aRay.Direct);
63 vec4 aColor = PathTrace (aRay, aInvDirect);
65 if (any (isnan (aColor.rgb)))
70 aColor.rgb = min (aColor.rgb, MAX_RADIANCE);
72 #ifdef ADAPTIVE_SAMPLING
74 // accumulate RGB color and depth
75 imageAtomicAdd (uRenderImage, ivec2 (3 * aFragCoord.x + 0,
76 2 * aFragCoord.y + 0), aColor.r);
77 imageAtomicAdd (uRenderImage, ivec2 (3 * aFragCoord.x + 1,
78 2 * aFragCoord.y + 0), aColor.g);
79 imageAtomicAdd (uRenderImage, ivec2 (3 * aFragCoord.x + 1,
80 2 * aFragCoord.y + 1), aColor.b);
81 imageAtomicAdd (uRenderImage, ivec2 (3 * aFragCoord.x + 2,
82 2 * aFragCoord.y + 1), aColor.w);
84 // accumulate number of samples
85 float aNbSamples = imageAtomicAdd (uRenderImage, ivec2 (3 * aFragCoord.x + 0,
86 2 * aFragCoord.y + 1), 1.0);
88 if (int (aNbSamples) % 2 == 0) // accumulate luminance for even samples only
90 imageAtomicAdd (uRenderImage, ivec2 (3 * aFragCoord.x + 2,
91 2 * aFragCoord.y + 0), dot (LUMA, aColor.rgb));
94 discard; // fragment should not be written to frame buffer
98 OutColor = mix (texture2D (uAccumTexture, vPixel), aColor, uSampleWeight);
100 #endif // ADAPTIVE_SAMPLING
104 OutColor = clamp (Radiance (aRay, aInvDirect), 0.f, 1.f);
106 #endif // PATH_TRACING