0030483: Visualization, Path Tracing - make Tile Size configurable
[occt.git] / src / Shaders / Display.fs
1 #ifdef ADAPTIVE_SAMPLING
2
3   #extension GL_ARB_shader_image_load_store : require
4
5   #extension GL_ARB_shader_image_size : enable
6
7   //! OpenGL image used for accumulating rendering result.
8   volatile restrict layout(size1x32) uniform image2D uRenderImage;
9
10   //! OpenGL image storing variance of sampled pixels blocks.
11   volatile restrict layout(size1x32) uniform iimage2D uVarianceImage;
12
13   //! Scale factor used to quantize visual error (float) into signed integer.
14   uniform float uVarianceScaleFactor;
15
16   //! Screen space tile size.
17   uniform ivec2 uTileSize;
18
19 #else // ADAPTIVE_SAMPLING
20
21   //! Input image.
22   uniform sampler2D uInputTexture;
23
24   //! Ray tracing depth image.
25   uniform sampler2D uDepthTexture;
26
27 #endif // ADAPTIVE_SAMPLING
28
29 //! Number of accumulated frames.
30 uniform int uAccumFrames;
31
32 //! Is debug mode enabled for importance screen sampling.
33 uniform int uDebugAdaptive;
34
35 //! Exposure value for tone mapping.
36 uniform float uExposure;
37
38 #ifdef TONE_MAPPING_FILMIC
39
40 //! White point value for filmic tone mapping.
41 uniform float uWhitePoint;
42
43 #endif // TONE_MAPPING
44
45 //! Output pixel color.
46 out vec4 OutColor;
47
48 //! RGB weight factors to calculate luminance.
49 #define LUMA vec3 (0.2126f, 0.7152f, 0.0722f)
50
51 // =======================================================================
52 // function : ToneMappingFilmic
53 // purpose  :
54 // =======================================================================
55 vec4 ToneMappingFilmic(vec4 theColor, float theWhitePoint)
56 {
57   vec4 aPackColor = vec4 (theColor.rgb, theWhitePoint);
58   vec4 aFilmicCurve = 1.425f * aPackColor + vec4 (0.05f);
59   vec4 aResultColor = (aPackColor * aFilmicCurve + vec4 (0.004f)) / (aPackColor * (aFilmicCurve + vec4 (0.55f)) + vec4 (0.0491f)) - vec4 (0.0821f);
60   return vec4 (aResultColor.rgb / aResultColor.www, 1.0);
61 }
62
63 // =======================================================================
64 // function : main
65 // purpose  :
66 // =======================================================================
67 void main (void)
68 {
69 #ifndef ADAPTIVE_SAMPLING
70
71   vec4 aColor = texelFetch (uInputTexture, ivec2 (gl_FragCoord.xy), 0);
72
73 #ifdef PATH_TRACING
74   float aDepth = aColor.w; // path tracing uses averaged depth
75 #else
76   float aDepth = texelFetch (uDepthTexture, ivec2 (gl_FragCoord.xy), 0).r;
77 #endif
78
79   gl_FragDepth = aDepth;
80
81 #else // ADAPTIVE_SAMPLING
82
83   ivec2 aPixel = ivec2 (gl_FragCoord.xy);
84
85   vec4 aColor = vec4 (0.0);
86
87   // fetch accumulated color and total number of samples
88   aColor.x = imageLoad (uRenderImage, ivec2 (3 * aPixel.x + 0,
89                                              2 * aPixel.y + 0)).x;
90   aColor.y = imageLoad (uRenderImage, ivec2 (3 * aPixel.x + 1,
91                                              2 * aPixel.y + 0)).x;
92   aColor.z = imageLoad (uRenderImage, ivec2 (3 * aPixel.x + 1,
93                                              2 * aPixel.y + 1)).x;
94   aColor.w = imageLoad (uRenderImage, ivec2 (3 * aPixel.x + 0,
95                                              2 * aPixel.y + 1)).x;
96
97   // calculate normalization factor
98   float aSampleWeight = 1.f / max (1.0, aColor.w);
99
100   // calculate averaged depth value
101   gl_FragDepth = imageLoad (uRenderImage, ivec2 (3 * aPixel.x + 2,
102                                                  2 * aPixel.y + 1)).x * aSampleWeight;
103
104   // calculate averaged radiance for all samples and even samples only
105   float aHalfRad = imageLoad (uRenderImage, ivec2 (3 * aPixel.x + 2,
106                                                    2 * aPixel.y + 0)).x * aSampleWeight * 2.f;
107
108   float aAverRad = dot (aColor.rgb, LUMA) * aSampleWeight;
109
110   // apply our 'tone mapping' operator (gamma correction and clamping)
111   aHalfRad = min (1.f, sqrt (aHalfRad));
112   aAverRad = min (1.f, sqrt (aAverRad));
113
114   // calculate visual error
115   float anError = (aAverRad - aHalfRad) * (aAverRad - aHalfRad);
116
117   // accumulate visual error to current block; estimated error is written only
118   // after the first 40 samples and path length has reached 10 bounces or more
119   imageAtomicAdd (uVarianceImage, aPixel / uTileSize,
120                   int (mix (uVarianceScaleFactor, anError * uVarianceScaleFactor, aColor.w > 40.f)));
121
122   if (uDebugAdaptive == 0) // normal rendering
123   {
124     aColor = vec4 (aColor.rgb * aSampleWeight, 1.0);
125   }
126   else // showing number of samples
127   {
128     vec2 aRatio = vec2 (1.f, 1.f);
129
130 #ifdef GL_ARB_shader_image_size
131     aRatio = vec2 (imageSize (uRenderImage)) / vec2 (3.f * 512.f, 2.f * 512.f);
132 #endif
133
134     aColor = vec4 (0.5f * aColor.rgb * aSampleWeight + vec3 (0.f, sqrt (aRatio.x * aRatio.y) * aColor.w / uAccumFrames * 0.35f, 0.f), 1.0);
135   }
136
137 #endif // ADAPTIVE_SAMPLING
138
139 #ifdef PATH_TRACING
140
141   aColor *= pow (2, uExposure);
142
143 #ifdef TONE_MAPPING_FILMIC
144   aColor = ToneMappingFilmic (aColor, uWhitePoint);
145 #endif // TONE_MAPPING
146
147   // apply gamma correction (we use gamma = 2)
148   OutColor = vec4 (sqrt (aColor.rgb), 0.f);
149
150 #else // not PATH_TRACING
151
152   OutColor = aColor;
153
154 #endif
155 }