0027607: Visualization - Implement adaptive screen space sampling in path tracing
[occt.git] / src / Shaders / Display.fs
1 #ifdef ADAPTIVE_SAMPLING
2
3   #extension GL_ARB_shader_image_load_store : require
4
5   //! OpenGL image used for accumulating rendering result.
6   volatile restrict layout(size1x32) uniform image2D uRenderImage;
7
8   //! OpenGL image storing variance of sampled pixels blocks.
9   volatile restrict layout(size1x32) uniform iimage2D uVarianceImage;
10
11 #else // ADAPTIVE_SAMPLING
12
13   //! Input image.
14   uniform sampler2D uInputTexture;
15
16   //! Ray tracing depth image.
17   uniform sampler2D uDepthTexture;
18
19 #endif // ADAPTIVE_SAMPLING
20
21 //! Number of accumulated frames.
22 uniform int uAccumFrames;
23
24 //! Is debug mode enabled for importance screen sampling.
25 uniform int uDebugAdaptive;
26
27 //! Output pixel color.
28 out vec4 OutColor;
29
30 //! RGB weight factors to calculate luminance.
31 #define LUMA vec3 (0.2126f, 0.7152f, 0.0722f)
32
33 //! Scale factor used to quantize visual error.
34 #define SCALE_FACTOR 1.0e6f
35
36 // =======================================================================
37 // function : main
38 // purpose  :
39 // =======================================================================
40 void main (void)
41 {
42 #ifndef ADAPTIVE_SAMPLING
43
44   vec4 aColor = texelFetch (uInputTexture, ivec2 (gl_FragCoord.xy), 0);
45
46 #ifdef PATH_TRACING
47   float aDepth = aColor.w; // path tracing uses averaged depth
48 #else
49   float aDepth = texelFetch (uDepthTexture, ivec2 (gl_FragCoord.xy), 0).r;
50 #endif
51
52   gl_FragDepth = aDepth;
53
54 #else // ADAPTIVE_SAMPLING
55
56   ivec2 aPixel = ivec2 (gl_FragCoord.xy);
57
58   vec4 aColor = vec4 (0.0);
59
60   // fetch accumulated color and total number of samples
61   aColor.x = imageLoad (uRenderImage, ivec2 (3 * aPixel.x + 0,
62                                              2 * aPixel.y + 0)).x;
63   aColor.y = imageLoad (uRenderImage, ivec2 (3 * aPixel.x + 1,
64                                              2 * aPixel.y + 0)).x;
65   aColor.z = imageLoad (uRenderImage, ivec2 (3 * aPixel.x + 1,
66                                              2 * aPixel.y + 1)).x;
67   aColor.w = imageLoad (uRenderImage, ivec2 (3 * aPixel.x + 0,
68                                              2 * aPixel.y + 1)).x;
69
70   // calculate normalization factor
71   float aSampleWeight = 1.f / max (1.0, aColor.w);
72
73   // calculate averaged depth value
74   gl_FragDepth = imageLoad (uRenderImage, ivec2 (3 * aPixel.x + 2,
75                                                  2 * aPixel.y + 1)).x * aSampleWeight;
76
77   // calculate averaged radiance for all samples and even samples only
78   float aHalfRad = imageLoad (uRenderImage, ivec2 (3 * aPixel.x + 2,
79                                                    2 * aPixel.y + 0)).x * aSampleWeight * 2.f;
80
81   float aAverRad = dot (aColor.rgb, LUMA) * aSampleWeight;
82
83   // apply our 'tone mapping' operator (gamma correction and clamping)
84   aHalfRad = min (1.f, sqrt (aHalfRad));
85   aAverRad = min (1.f, sqrt (aAverRad));
86
87   // calculate visual error
88   float anError = (aAverRad - aHalfRad) * (aAverRad - aHalfRad);
89
90   // accumulate visual error to current block
91   imageAtomicAdd (uVarianceImage, ivec2 (aPixel / vec2 (BLOCK_SIZE)), int (anError * SCALE_FACTOR));
92
93   if (uDebugAdaptive == 0) // normal rendering
94   {
95     aColor = vec4 (aColor.rgb * aSampleWeight, 1.0);
96   }
97   else // showing number of samples
98   {
99     aColor = vec4 (0.5f * aColor.rgb * aSampleWeight + vec3 (0.f, aColor.w / uAccumFrames * 0.35f, 0.f), 1.0);
100   }
101
102 #endif // ADAPTIVE_SAMPLING
103
104 #ifdef PATH_TRACING
105
106    // apply gamma correction (we use gamma = 2)
107    OutColor = vec4 (sqrt (aColor.rgb), 0.f);
108
109 #else // not PATH_TRACING
110
111    OutColor = aColor;
112
113 #endif
114 }