0031279: Visualization, TKOpenGl - environment background is misplaced within Ray...
[occt.git] / src / Shaders / Shaders_RaytraceBase_fs.pxx
CommitLineData
ee5befae 1// This file has been automatically generated from resource file src/Shaders/RaytraceBase.fs
2
3static const char Shaders_RaytraceBase_fs[] =
4 "#ifdef ADAPTIVE_SAMPLING\n"
5 " #extension GL_ARB_shader_image_load_store : require\n"
e084dbbc 6 "#endif\n"
7 "#ifdef ADAPTIVE_SAMPLING_ATOMIC\n"
ee5befae 8 " #extension GL_NV_shader_atomic_float : require\n"
9 "#endif\n"
10 "\n"
11 "#ifdef USE_TEXTURES\n"
12 " #extension GL_ARB_bindless_texture : require\n"
13 "#endif\n"
14 "\n"
15 "//! Normalized pixel coordinates.\n"
16 "in vec2 vPixel;\n"
17 "\n"
18 "//! Sub-pixel offset in X direction for FSAA.\n"
19 "uniform float uOffsetX = 0.f;\n"
20 "//! Sub-pixel offset in Y direction for FSAA.\n"
21 "uniform float uOffsetY = 0.f;\n"
22 "\n"
23 "//! Origin of viewing ray in left-top corner.\n"
24 "uniform vec3 uOriginLT;\n"
25 "//! Origin of viewing ray in left-bottom corner.\n"
26 "uniform vec3 uOriginLB;\n"
27 "//! Origin of viewing ray in right-top corner.\n"
28 "uniform vec3 uOriginRT;\n"
29 "//! Origin of viewing ray in right-bottom corner.\n"
30 "uniform vec3 uOriginRB;\n"
31 "\n"
32 "//! Width of the rendering window.\n"
33 "uniform int uWinSizeX;\n"
34 "//! Height of the rendering window.\n"
35 "uniform int uWinSizeY;\n"
36 "\n"
37 "//! Direction of viewing ray in left-top corner.\n"
38 "uniform vec3 uDirectLT;\n"
39 "//! Direction of viewing ray in left-bottom corner.\n"
40 "uniform vec3 uDirectLB;\n"
41 "//! Direction of viewing ray in right-top corner.\n"
42 "uniform vec3 uDirectRT;\n"
43 "//! Direction of viewing ray in right-bottom corner.\n"
44 "uniform vec3 uDirectRB;\n"
45 "\n"
46 "//! Inverse model-view-projection matrix.\n"
47 "uniform mat4 uUnviewMat;\n"
48 "\n"
49 "//! Model-view-projection matrix.\n"
50 "uniform mat4 uViewMat;\n"
51 "\n"
52 "//! Texture buffer of data records of bottom-level BVH nodes.\n"
53 "uniform isamplerBuffer uSceneNodeInfoTexture;\n"
54 "//! Texture buffer of minimum points of bottom-level BVH nodes.\n"
55 "uniform samplerBuffer uSceneMinPointTexture;\n"
56 "//! Texture buffer of maximum points of bottom-level BVH nodes.\n"
57 "uniform samplerBuffer uSceneMaxPointTexture;\n"
58 "//! Texture buffer of transformations of high-level BVH nodes.\n"
59 "uniform samplerBuffer uSceneTransformTexture;\n"
60 "\n"
61 "//! Texture buffer of vertex coords.\n"
62 "uniform samplerBuffer uGeometryVertexTexture;\n"
63 "//! Texture buffer of vertex normals.\n"
64 "uniform samplerBuffer uGeometryNormalTexture;\n"
65 "#ifdef USE_TEXTURES\n"
66 " //! Texture buffer of per-vertex UV-coordinates.\n"
67 " uniform samplerBuffer uGeometryTexCrdTexture;\n"
68 "#endif\n"
69 "//! Texture buffer of triangle indices.\n"
70 "uniform isamplerBuffer uGeometryTriangTexture;\n"
71 "\n"
72 "//! Texture buffer of material properties.\n"
73 "uniform samplerBuffer uRaytraceMaterialTexture;\n"
74 "//! Texture buffer of light source properties.\n"
75 "uniform samplerBuffer uRaytraceLightSrcTexture;\n"
89d855ba 76 "\n"
77 "#ifdef BACKGROUND_CUBEMAP\n"
78 " //! Environment cubemap texture.\n"
79 " uniform samplerCube uEnvMapTexture;\n"
80 " //! Coefficient of Y controlling horizontal flip of cubemap\n"
81 " uniform int uYCoeff;\n"
82 " //! Coefficient of Z controlling vertical flip of cubemap\n"
83 " uniform int uZCoeff;\n"
84 "#else\n"
85 " //! Environment map texture.\n"
86 " uniform sampler2D uEnvMapTexture;\n"
87 "#endif\n"
ee5befae 88 "\n"
89 "//! Total number of light sources.\n"
90 "uniform int uLightCount;\n"
91 "//! Intensity of global ambient light.\n"
92 "uniform vec4 uGlobalAmbient;\n"
93 "\n"
94 "//! Enables/disables hard shadows.\n"
95 "uniform int uShadowsEnabled;\n"
96 "//! Enables/disables specular reflections.\n"
97 "uniform int uReflectEnabled;\n"
89d855ba 98 "//! Enables/disables environment map lighting.\n"
99 "uniform int uEnvMapEnabled;\n"
ee5befae 100 "//! Enables/disables environment map background.\n"
89d855ba 101 "uniform int uEnvMapForBack;\n"
ee5befae 102 "\n"
103 "//! Radius of bounding sphere of the scene.\n"
104 "uniform float uSceneRadius;\n"
105 "//! Scene epsilon to prevent self-intersections.\n"
106 "uniform float uSceneEpsilon;\n"
107 "\n"
108 "#ifdef USE_TEXTURES\n"
109 " //! Unique 64-bit handles of OpenGL textures.\n"
110 " uniform uvec2 uTextureSamplers[MAX_TEX_NUMBER];\n"
111 "#endif\n"
112 "\n"
113 "#ifdef ADAPTIVE_SAMPLING\n"
114 " //! OpenGL image used for accumulating rendering result.\n"
e084dbbc 115 " volatile restrict layout(r32f) uniform image2D uRenderImage;\n"
ee5befae 116 "\n"
e084dbbc 117 "#ifdef ADAPTIVE_SAMPLING_ATOMIC\n"
ee5befae 118 " //! OpenGL image storing offsets of sampled pixels blocks.\n"
e084dbbc 119 " coherent restrict layout(rg32i) uniform iimage2D uOffsetImage;\n"
120 "#else\n"
121 " //! OpenGL image defining per-tile amount of samples.\n"
122 " volatile restrict layout(r32i) uniform iimage2D uTilesImage;\n"
123 "#endif\n"
66d1cdc6 124 "\n"
125 " //! Screen space tile size.\n"
126 " uniform ivec2 uTileSize;\n"
ee5befae 127 "#endif\n"
128 "\n"
129 "//! Top color of gradient background.\n"
130 "uniform vec4 uBackColorTop = vec4 (0.0);\n"
131 "//! Bottom color of gradient background.\n"
132 "uniform vec4 uBackColorBot = vec4 (0.0);\n"
133 "\n"
b27ab03d 134 "//! Aperture radius of camera used for depth-of-field\n"
135 "uniform float uApertureRadius = 0.f;\n"
136 "\n"
137 "//! Focal distance of camera used for depth-of field\n"
138 "uniform float uFocalPlaneDist = 10.f;\n"
139 "\n"
140 "//! Camera position used for projective mode\n"
141 "uniform vec3 uEyeOrig;\n"
142 "\n"
143 "//! Camera view direction used for projective mode\n"
144 "uniform vec3 uEyeView;\n"
145 "\n"
146 "//! Camera's screen vertical direction used for projective mode\n"
147 "uniform vec3 uEyeVert;\n"
148 "\n"
149 "//! Camera's screen horizontal direction used for projective mode\n"
150 "uniform vec3 uEyeSide;\n"
151 "\n"
152 "//! Camera's screen size used for projective mode\n"
153 "uniform vec2 uEyeSize;\n"
154 "\n"
ee5befae 155 "/////////////////////////////////////////////////////////////////////////////////////////\n"
156 "// Specific data types\n"
157 "\n"
158 "//! Stores ray parameters.\n"
159 "struct SRay\n"
160 "{\n"
161 " vec3 Origin;\n"
162 "\n"
163 " vec3 Direct;\n"
164 "};\n"
165 "\n"
166 "//! Stores intersection parameters.\n"
167 "struct SIntersect\n"
168 "{\n"
169 " float Time;\n"
170 "\n"
171 " vec2 UV;\n"
172 "\n"
173 " vec3 Normal;\n"
174 "};\n"
175 "\n"
78607702 176 "//! Stores triangle's vertex indexes and vertexes itself\n"
177 "struct STriangle\n"
178 "{\n"
179 " ivec4 TriIndex;\n"
180 "\n"
181 " vec3 Points[3];\n"
182 "};\n"
183 "\n"
ee5befae 184 "/////////////////////////////////////////////////////////////////////////////////////////\n"
185 "// Some useful constants\n"
186 "\n"
187 "#define MAXFLOAT 1e15f\n"
188 "\n"
189 "#define SMALL vec3 (exp2 (-80.0f))\n"
190 "\n"
191 "#define ZERO vec3 (0.0f, 0.0f, 0.0f)\n"
192 "#define UNIT vec3 (1.0f, 1.0f, 1.0f)\n"
193 "\n"
194 "#define AXIS_X vec3 (1.0f, 0.0f, 0.0f)\n"
195 "#define AXIS_Y vec3 (0.0f, 1.0f, 0.0f)\n"
196 "#define AXIS_Z vec3 (0.0f, 0.0f, 1.0f)\n"
197 "\n"
6e728f3b 198 "#define M_PI 3.141592653f\n"
199 "#define M_2_PI 6.283185307f\n"
200 "#define M_PI_2 1.570796327f\n"
ee5befae 201 "\n"
202 "#define LUMA vec3 (0.2126f, 0.7152f, 0.0722f)\n"
203 "\n"
204 "// =======================================================================\n"
205 "// function : MatrixRowMultiplyDir\n"
206 "// purpose : Multiplies a vector by matrix\n"
207 "// =======================================================================\n"
208 "vec3 MatrixRowMultiplyDir (in vec3 v,\n"
209 " in vec4 m0,\n"
210 " in vec4 m1,\n"
211 " in vec4 m2)\n"
212 "{\n"
213 " return vec3 (dot (m0.xyz, v),\n"
214 " dot (m1.xyz, v),\n"
215 " dot (m2.xyz, v));\n"
216 "}\n"
217 "\n"
218 "//! 32-bit state of random number generator.\n"
219 "uint RandState;\n"
220 "\n"
221 "// =======================================================================\n"
222 "// function : SeedRand\n"
223 "// purpose : Applies hash function by Thomas Wang to randomize seeds\n"
224 "// (see http://www.burtleburtle.net/bob/hash/integer.html)\n"
225 "// =======================================================================\n"
226 "void SeedRand (in int theSeed, in int theSizeX, in int theRadius)\n"
227 "{\n"
228 " RandState = uint (int (gl_FragCoord.y) / theRadius * theSizeX + int (gl_FragCoord.x) / theRadius + theSeed);\n"
229 "\n"
230 " RandState = (RandState + 0x479ab41du) + (RandState << 8);\n"
231 " RandState = (RandState ^ 0xe4aa10ceu) ^ (RandState >> 5);\n"
232 " RandState = (RandState + 0x9942f0a6u) - (RandState << 14);\n"
233 " RandState = (RandState ^ 0x5aedd67du) ^ (RandState >> 3);\n"
234 " RandState = (RandState + 0x17bea992u) + (RandState << 7);\n"
235 "}\n"
236 "\n"
237 "// =======================================================================\n"
238 "// function : RandInt\n"
239 "// purpose : Generates integer using Xorshift algorithm by G. Marsaglia\n"
240 "// =======================================================================\n"
241 "uint RandInt()\n"
242 "{\n"
243 " RandState ^= (RandState << 13);\n"
244 " RandState ^= (RandState >> 17);\n"
245 " RandState ^= (RandState << 5);\n"
246 "\n"
247 " return RandState;\n"
248 "}\n"
249 "\n"
250 "// =======================================================================\n"
251 "// function : RandFloat\n"
252 "// purpose : Generates a random float in 0 <= x < 1 range\n"
253 "// =======================================================================\n"
254 "float RandFloat()\n"
255 "{\n"
256 " return float (RandInt()) * (1.f / 4294967296.f);\n"
257 "}\n"
258 "\n"
259 "// =======================================================================\n"
260 "// function : MatrixColMultiplyPnt\n"
261 "// purpose : Multiplies a vector by matrix\n"
262 "// =======================================================================\n"
263 "vec3 MatrixColMultiplyPnt (in vec3 v,\n"
264 " in vec4 m0,\n"
265 " in vec4 m1,\n"
266 " in vec4 m2,\n"
267 " in vec4 m3)\n"
268 "{\n"
269 " return vec3 (m0.x * v.x + m1.x * v.y + m2.x * v.z + m3.x,\n"
270 " m0.y * v.x + m1.y * v.y + m2.y * v.z + m3.y,\n"
271 " m0.z * v.x + m1.z * v.y + m2.z * v.z + m3.z);\n"
272 "}\n"
273 "\n"
274 "// =======================================================================\n"
275 "// function : MatrixColMultiplyDir\n"
276 "// purpose : Multiplies a vector by matrix\n"
277 "// =======================================================================\n"
278 "vec3 MatrixColMultiplyDir (in vec3 v,\n"
279 " in vec4 m0,\n"
280 " in vec4 m1,\n"
281 " in vec4 m2)\n"
282 "{\n"
283 " return vec3 (m0.x * v.x + m1.x * v.y + m2.x * v.z,\n"
284 " m0.y * v.x + m1.y * v.y + m2.y * v.z,\n"
285 " m0.z * v.x + m1.z * v.y + m2.z * v.z);\n"
286 "}\n"
287 "\n"
288 "//=======================================================================\n"
289 "// function : InverseDirection\n"
290 "// purpose : Returns safely inverted direction of the given one\n"
291 "//=======================================================================\n"
292 "vec3 InverseDirection (in vec3 theInput)\n"
293 "{\n"
294 " vec3 anInverse = 1.f / max (abs (theInput), SMALL);\n"
295 "\n"
296 " return mix (-anInverse, anInverse, step (ZERO, theInput));\n"
297 "}\n"
298 "\n"
299 "//=======================================================================\n"
300 "// function : BackgroundColor\n"
301 "// purpose : Returns color of gradient background\n"
302 "//=======================================================================\n"
303 "vec4 BackgroundColor()\n"
304 "{\n"
e084dbbc 305 "#ifdef ADAPTIVE_SAMPLING_ATOMIC\n"
ee5befae 306 "\n"
307 " ivec2 aFragCoord = ivec2 (gl_FragCoord.xy);\n"
308 "\n"
66d1cdc6 309 " ivec2 aTileXY = imageLoad (uOffsetImage, aFragCoord / uTileSize).xy * uTileSize;\n"
ee5befae 310 "\n"
66d1cdc6 311 " aTileXY.y += aFragCoord.y % min (uWinSizeY - aTileXY.y, uTileSize.y);\n"
ee5befae 312 "\n"
313 " return mix (uBackColorBot, uBackColorTop, float (aTileXY.y) / uWinSizeY);\n"
314 "\n"
315 "#else\n"
316 "\n"
317 " return mix (uBackColorBot, uBackColorTop, vPixel.y);\n"
318 "\n"
319 "#endif\n"
320 "}\n"
321 "\n"
322 "/////////////////////////////////////////////////////////////////////////////////////////\n"
323 "// Functions for compute ray-object intersection\n"
324 "\n"
b27ab03d 325 "//=======================================================================\n"
326 "// function : sampleUniformDisk\n"
327 "// purpose :\n"
328 "//=======================================================================\n"
329 "vec2 sampleUniformDisk ()\n"
330 "{\n"
331 " vec2 aPoint;\n"
332 "\n"
333 " float aKsi1 = 2.f * RandFloat () - 1.f;\n"
334 " float aKsi2 = 2.f * RandFloat () - 1.f;\n"
335 "\n"
336 " if (aKsi1 > -aKsi2)\n"
337 " {\n"
338 " if (aKsi1 > aKsi2)\n"
339 " aPoint = vec2 (aKsi1, (M_PI / 4.f) * (0.f + aKsi2 / aKsi1));\n"
340 " else\n"
341 " aPoint = vec2 (aKsi2, (M_PI / 4.f) * (2.f - aKsi1 / aKsi2));\n"
342 " }\n"
343 " else\n"
344 " {\n"
345 " if (aKsi1 < aKsi2)\n"
346 " aPoint = vec2 (-aKsi1, (M_PI / 4.f) * (4.f + aKsi2 / aKsi1));\n"
347 " else\n"
348 " aPoint = vec2 (-aKsi2, (M_PI / 4.f) * (6.f - aKsi1 / aKsi2));\n"
349 " }\n"
350 "\n"
351 " return vec2 (sin (aPoint.y), cos (aPoint.y)) * aPoint.x;\n"
352 "}\n"
353 "\n"
ee5befae 354 "// =======================================================================\n"
355 "// function : GenerateRay\n"
356 "// purpose :\n"
357 "// =======================================================================\n"
358 "SRay GenerateRay (in vec2 thePixel)\n"
359 "{\n"
b27ab03d 360 "#ifndef DEPTH_OF_FIELD\n"
361 "\n"
ee5befae 362 " vec3 aP0 = mix (uOriginLB, uOriginRB, thePixel.x);\n"
363 " vec3 aP1 = mix (uOriginLT, uOriginRT, thePixel.x);\n"
364 "\n"
365 " vec3 aD0 = mix (uDirectLB, uDirectRB, thePixel.x);\n"
366 " vec3 aD1 = mix (uDirectLT, uDirectRT, thePixel.x);\n"
367 "\n"
368 " vec3 aDirection = normalize (mix (aD0, aD1, thePixel.y));\n"
369 "\n"
370 " return SRay (mix (aP0, aP1, thePixel.y), aDirection);\n"
b27ab03d 371 "\n"
372 "#else\n"
373 "\n"
374 " vec2 aPixel = uEyeSize * (thePixel - vec2 (0.5f)) * 2.f;\n"
375 "\n"
376 " vec2 aAperturePnt = sampleUniformDisk () * uApertureRadius;\n"
377 "\n"
378 " vec3 aLocalDir = normalize (vec3 (\n"
379 " aPixel * uFocalPlaneDist - aAperturePnt, uFocalPlaneDist));\n"
380 "\n"
381 " vec3 aOrigin = uEyeOrig +\n"
382 " uEyeSide * aAperturePnt.x +\n"
383 " uEyeVert * aAperturePnt.y;\n"
384 "\n"
385 " vec3 aDirect = uEyeView * aLocalDir.z +\n"
386 " uEyeSide * aLocalDir.x +\n"
387 " uEyeVert * aLocalDir.y;\n"
388 "\n"
389 " return SRay (aOrigin, aDirect);\n"
390 "\n"
391 "#endif\n"
ee5befae 392 "}\n"
393 "\n"
394 "// =======================================================================\n"
395 "// function : IntersectSphere\n"
396 "// purpose : Computes ray-sphere intersection\n"
397 "// =======================================================================\n"
398 "float IntersectSphere (in SRay theRay, in float theRadius)\n"
399 "{\n"
400 " float aDdotD = dot (theRay.Direct, theRay.Direct);\n"
401 " float aDdotO = dot (theRay.Direct, theRay.Origin);\n"
402 " float aOdotO = dot (theRay.Origin, theRay.Origin);\n"
403 "\n"
404 " float aD = aDdotO * aDdotO - aDdotD * (aOdotO - theRadius * theRadius);\n"
405 "\n"
406 " if (aD > 0.0f)\n"
407 " {\n"
408 " float aTime = (sqrt (aD) - aDdotO) * (1.0f / aDdotD);\n"
409 " \n"
410 " return aTime > 0.0f ? aTime : MAXFLOAT;\n"
411 " }\n"
412 "\n"
413 " return MAXFLOAT;\n"
414 "}\n"
415 "\n"
416 "// =======================================================================\n"
417 "// function : IntersectTriangle\n"
418 "// purpose : Computes ray-triangle intersection (branchless version)\n"
419 "// =======================================================================\n"
420 "void IntersectTriangle (in SRay theRay,\n"
421 " in vec3 thePnt0,\n"
422 " in vec3 thePnt1,\n"
423 " in vec3 thePnt2,\n"
424 " out vec3 theUVT,\n"
425 " out vec3 theNorm)\n"
426 "{\n"
427 " vec3 aToTrg = thePnt0 - theRay.Origin;\n"
428 "\n"
429 " vec3 aEdge0 = thePnt1 - thePnt0;\n"
430 " vec3 aEdge1 = thePnt0 - thePnt2;\n"
431 "\n"
432 " theNorm = cross (aEdge1, aEdge0);\n"
433 "\n"
434 " vec3 theVect = cross (theRay.Direct, aToTrg);\n"
435 "\n"
436 " theUVT = vec3 (dot (theNorm, aToTrg),\n"
437 " dot (theVect, aEdge1),\n"
438 " dot (theVect, aEdge0)) * (1.f / dot (theNorm, theRay.Direct));\n"
439 "\n"
440 " theUVT.x = any (lessThan (theUVT, ZERO)) || (theUVT.y + theUVT.z) > 1.f ? MAXFLOAT : theUVT.x;\n"
441 "}\n"
442 "\n"
443 "#define EMPTY_ROOT ivec4(0)\n"
444 "\n"
445 "//! Utility structure containing information about\n"
446 "//! currently traversing sub-tree of scene's BVH.\n"
447 "struct SSubTree\n"
448 "{\n"
449 " //! Transformed ray.\n"
450 " SRay TrsfRay;\n"
451 "\n"
452 " //! Inversed ray direction.\n"
453 " vec3 Inverse;\n"
454 "\n"
455 " //! Parameters of sub-root node.\n"
456 " ivec4 SubData;\n"
457 "};\n"
458 "\n"
05aa616d 459 "#define MATERIAL_AMBN(index) (19 * index + 0)\n"
460 "#define MATERIAL_DIFF(index) (19 * index + 1)\n"
461 "#define MATERIAL_SPEC(index) (19 * index + 2)\n"
462 "#define MATERIAL_EMIS(index) (19 * index + 3)\n"
463 "#define MATERIAL_REFL(index) (19 * index + 4)\n"
464 "#define MATERIAL_REFR(index) (19 * index + 5)\n"
465 "#define MATERIAL_TRAN(index) (19 * index + 6)\n"
466 "#define MATERIAL_TRS1(index) (19 * index + 7)\n"
467 "#define MATERIAL_TRS2(index) (19 * index + 8)\n"
468 "#define MATERIAL_TRS3(index) (19 * index + 9)\n"
ee5befae 469 "\n"
470 "#define TRS_OFFSET(treelet) treelet.SubData.x\n"
471 "#define BVH_OFFSET(treelet) treelet.SubData.y\n"
472 "#define VRT_OFFSET(treelet) treelet.SubData.z\n"
473 "#define TRG_OFFSET(treelet) treelet.SubData.w\n"
474 "\n"
475 "//! Identifies the absence of intersection.\n"
78607702 476 "#define INVALID_HIT ivec4 (-1)\n"
ee5befae 477 "\n"
478 "//! Global stack shared between traversal functions.\n"
479 "int Stack[STACK_SIZE];\n"
480 "\n"
481 "// =======================================================================\n"
482 "// function : pop\n"
483 "// purpose :\n"
484 "// =======================================================================\n"
485 "int pop (inout int theHead)\n"
486 "{\n"
487 " int aData = Stack[theHead];\n"
488 "\n"
489 " int aMask = aData >> 26;\n"
490 " int aNode = aMask & 0x3;\n"
491 "\n"
492 " aMask >>= 2;\n"
493 "\n"
494 " if ((aMask & 0x3) == aNode)\n"
495 " {\n"
496 " --theHead;\n"
497 " }\n"
498 " else\n"
499 " {\n"
500 " aMask |= (aMask << 2) & 0x30;\n"
501 "\n"
502 " Stack[theHead] = (aData & 0x03FFFFFF) | (aMask << 26);\n"
503 " }\n"
504 "\n"
505 " return (aData & 0x03FFFFFF) + aNode;\n"
506 "}\n"
507 "\n"
508 "// =======================================================================\n"
509 "// function : SceneNearestHit\n"
510 "// purpose : Finds intersection with nearest scene triangle\n"
511 "// =======================================================================\n"
78607702 512 "STriangle SceneNearestHit (in SRay theRay, in vec3 theInverse, inout SIntersect theHit, out int theTrsfId)\n"
ee5befae 513 "{\n"
78607702 514 " STriangle aTriangle = STriangle (INVALID_HIT, vec3[](vec3(0.0), vec3(0.0), vec3(0.0)));\n"
ee5befae 515 "\n"
516 " int aNode = 0; // node to traverse\n"
517 " int aHead = -1; // pointer of stack\n"
518 " int aStop = -1; // BVH level switch\n"
519 "\n"
520 " SSubTree aSubTree = SSubTree (theRay, theInverse, EMPTY_ROOT);\n"
521 "\n"
522 " for (bool toContinue = true; toContinue; /* none */)\n"
523 " {\n"
524 " ivec4 aData = texelFetch (uSceneNodeInfoTexture, aNode);\n"
525 "\n"
526 " if (aData.x == 0) // if inner node\n"
527 " {\n"
528 " aData.y += BVH_OFFSET (aSubTree);\n"
529 "\n"
530 " vec4 aHitTimes = vec4 (MAXFLOAT,\n"
531 " MAXFLOAT,\n"
532 " MAXFLOAT,\n"
533 " MAXFLOAT);\n"
534 "\n"
535 " vec3 aRayOriginInverse = -aSubTree.TrsfRay.Origin * aSubTree.Inverse;\n"
536 "\n"
537 " vec3 aNodeMin0 = texelFetch (uSceneMinPointTexture, aData.y + 0).xyz * aSubTree.Inverse + aRayOriginInverse;\n"
538 " vec3 aNodeMin1 = texelFetch (uSceneMinPointTexture, aData.y + 1).xyz * aSubTree.Inverse + aRayOriginInverse;\n"
539 " vec3 aNodeMin2 = texelFetch (uSceneMinPointTexture, aData.y + min (2, aData.z)).xyz * aSubTree.Inverse + aRayOriginInverse;\n"
540 " vec3 aNodeMin3 = texelFetch (uSceneMinPointTexture, aData.y + min (3, aData.z)).xyz * aSubTree.Inverse + aRayOriginInverse;\n"
541 " vec3 aNodeMax0 = texelFetch (uSceneMaxPointTexture, aData.y + 0).xyz * aSubTree.Inverse + aRayOriginInverse;\n"
542 " vec3 aNodeMax1 = texelFetch (uSceneMaxPointTexture, aData.y + 1).xyz * aSubTree.Inverse + aRayOriginInverse;\n"
543 " vec3 aNodeMax2 = texelFetch (uSceneMaxPointTexture, aData.y + min (2, aData.z)).xyz * aSubTree.Inverse + aRayOriginInverse;\n"
544 " vec3 aNodeMax3 = texelFetch (uSceneMaxPointTexture, aData.y + min (3, aData.z)).xyz * aSubTree.Inverse + aRayOriginInverse;\n"
545 "\n"
546 " vec3 aTimeMax = max (aNodeMin0, aNodeMax0);\n"
547 " vec3 aTimeMin = min (aNodeMin0, aNodeMax0);\n"
548 "\n"
549 " float aTimeLeave = min (aTimeMax.x, min (aTimeMax.y, aTimeMax.z));\n"
550 " float aTimeEnter = max (aTimeMin.x, max (aTimeMin.y, aTimeMin.z));\n"
551 "\n"
06e06389 552 " aHitTimes.x = (aTimeEnter <= aTimeLeave && aTimeEnter <= theHit.Time && aTimeLeave >= 0.f) ? aTimeEnter : MAXFLOAT;\n"
ee5befae 553 "\n"
554 " aTimeMax = max (aNodeMin1, aNodeMax1);\n"
555 " aTimeMin = min (aNodeMin1, aNodeMax1);\n"
556 "\n"
557 " aTimeLeave = min (aTimeMax.x, min (aTimeMax.y, aTimeMax.z));\n"
558 " aTimeEnter = max (aTimeMin.x, max (aTimeMin.y, aTimeMin.z));\n"
559 "\n"
06e06389 560 " aHitTimes.y = (aTimeEnter <= aTimeLeave && aTimeEnter <= theHit.Time && aTimeLeave >= 0.f) ? aTimeEnter : MAXFLOAT;\n"
ee5befae 561 "\n"
562 " aTimeMax = max (aNodeMin2, aNodeMax2);\n"
563 " aTimeMin = min (aNodeMin2, aNodeMax2);\n"
564 "\n"
565 " aTimeLeave = min (aTimeMax.x, min (aTimeMax.y, aTimeMax.z));\n"
566 " aTimeEnter = max (aTimeMin.x, max (aTimeMin.y, aTimeMin.z));\n"
567 "\n"
06e06389 568 " aHitTimes.z = (aTimeEnter <= aTimeLeave && aTimeEnter <= theHit.Time && aTimeLeave >= 0.f && aData.z > 1) ? aTimeEnter : MAXFLOAT;\n"
ee5befae 569 "\n"
570 " aTimeMax = max (aNodeMin3, aNodeMax3);\n"
571 " aTimeMin = min (aNodeMin3, aNodeMax3);\n"
572 "\n"
573 " aTimeLeave = min (aTimeMax.x, min (aTimeMax.y, aTimeMax.z));\n"
574 " aTimeEnter = max (aTimeMin.x, max (aTimeMin.y, aTimeMin.z));\n"
575 "\n"
06e06389 576 " aHitTimes.w = (aTimeEnter <= aTimeLeave && aTimeEnter <= theHit.Time && aTimeLeave >= 0.f && aData.z > 2) ? aTimeEnter : MAXFLOAT;\n"
ee5befae 577 "\n"
578 " ivec4 aChildren = ivec4 (0, 1, 2, 3);\n"
579 "\n"
580 " aChildren.xy = aHitTimes.y < aHitTimes.x ? aChildren.yx : aChildren.xy;\n"
581 " aHitTimes.xy = aHitTimes.y < aHitTimes.x ? aHitTimes.yx : aHitTimes.xy;\n"
582 " aChildren.zw = aHitTimes.w < aHitTimes.z ? aChildren.wz : aChildren.zw;\n"
583 " aHitTimes.zw = aHitTimes.w < aHitTimes.z ? aHitTimes.wz : aHitTimes.zw;\n"
584 " aChildren.xz = aHitTimes.z < aHitTimes.x ? aChildren.zx : aChildren.xz;\n"
585 " aHitTimes.xz = aHitTimes.z < aHitTimes.x ? aHitTimes.zx : aHitTimes.xz;\n"
586 " aChildren.yw = aHitTimes.w < aHitTimes.y ? aChildren.wy : aChildren.yw;\n"
587 " aHitTimes.yw = aHitTimes.w < aHitTimes.y ? aHitTimes.wy : aHitTimes.yw;\n"
588 " aChildren.yz = aHitTimes.z < aHitTimes.y ? aChildren.zy : aChildren.yz;\n"
589 " aHitTimes.yz = aHitTimes.z < aHitTimes.y ? aHitTimes.zy : aHitTimes.yz;\n"
590 "\n"
591 " if (aHitTimes.x != MAXFLOAT)\n"
592 " {\n"
593 " int aHitMask = (aHitTimes.w != MAXFLOAT ? aChildren.w : aChildren.z) << 2\n"
594 " | (aHitTimes.z != MAXFLOAT ? aChildren.z : aChildren.y);\n"
595 "\n"
596 " if (aHitTimes.y != MAXFLOAT)\n"
597 " Stack[++aHead] = aData.y | (aHitMask << 2 | aChildren.y) << 26;\n"
598 "\n"
599 " aNode = aData.y + aChildren.x;\n"
600 " }\n"
601 " else\n"
602 " {\n"
603 " toContinue = (aHead >= 0);\n"
604 "\n"
605 " if (aHead == aStop) // go to top-level BVH\n"
606 " {\n"
607 " aStop = -1; aSubTree = SSubTree (theRay, theInverse, EMPTY_ROOT);\n"
608 " }\n"
609 "\n"
610 " if (aHead >= 0)\n"
611 " aNode = pop (aHead);\n"
612 " }\n"
613 " }\n"
614 " else if (aData.x < 0) // leaf node (contains triangles)\n"
615 " {\n"
616 " vec3 aNormal;\n"
617 " vec3 aTimeUV;\n"
618 "\n"
619 " for (int anIdx = aData.y; anIdx <= aData.z; ++anIdx)\n"
620 " {\n"
78607702 621 " ivec4 aTriIndex = texelFetch (uGeometryTriangTexture, anIdx + TRG_OFFSET (aSubTree));\n"
622 " vec3 aPoints[3];\n"
ee5befae 623 "\n"
78607702 624 " aPoints[0] = texelFetch (uGeometryVertexTexture, aTriIndex.x += VRT_OFFSET (aSubTree)).xyz;\n"
625 " aPoints[1] = texelFetch (uGeometryVertexTexture, aTriIndex.y += VRT_OFFSET (aSubTree)).xyz;\n"
626 " aPoints[2] = texelFetch (uGeometryVertexTexture, aTriIndex.z += VRT_OFFSET (aSubTree)).xyz;\n"
ee5befae 627 "\n"
78607702 628 " IntersectTriangle (aSubTree.TrsfRay, aPoints[0], aPoints[1], aPoints[2], aTimeUV, aNormal);\n"
ee5befae 629 "\n"
630 " if (aTimeUV.x < theHit.Time)\n"
631 " {\n"
78607702 632 " aTriangle.TriIndex = aTriIndex;\n"
633 " for (int i = 0; i < 3; ++i)\n"
634 " {\n"
635 " aTriangle.Points[i] = aPoints[i];\n"
636 " }\n"
ee5befae 637 "\n"
638 " theTrsfId = TRS_OFFSET (aSubTree);\n"
639 "\n"
640 " theHit = SIntersect (aTimeUV.x, aTimeUV.yz, aNormal);\n"
641 " }\n"
642 " }\n"
643 "\n"
644 " toContinue = (aHead >= 0);\n"
645 "\n"
646 " if (aHead == aStop) // go to top-level BVH\n"
647 " {\n"
648 " aStop = -1; aSubTree = SSubTree (theRay, theInverse, EMPTY_ROOT);\n"
649 " }\n"
650 "\n"
651 " if (aHead >= 0)\n"
652 " aNode = pop (aHead);\n"
653 " }\n"
654 " else if (aData.x > 0) // switch node\n"
655 " {\n"
656 " aSubTree.SubData = ivec4 (4 * aData.x - 4, aData.yzw); // store BVH sub-root\n"
657 "\n"
658 " vec4 aInvTransf0 = texelFetch (uSceneTransformTexture, TRS_OFFSET (aSubTree) + 0);\n"
659 " vec4 aInvTransf1 = texelFetch (uSceneTransformTexture, TRS_OFFSET (aSubTree) + 1);\n"
660 " vec4 aInvTransf2 = texelFetch (uSceneTransformTexture, TRS_OFFSET (aSubTree) + 2);\n"
661 " vec4 aInvTransf3 = texelFetch (uSceneTransformTexture, TRS_OFFSET (aSubTree) + 3);\n"
662 "\n"
663 " aSubTree.TrsfRay.Direct = MatrixColMultiplyDir (theRay.Direct,\n"
664 " aInvTransf0,\n"
665 " aInvTransf1,\n"
666 " aInvTransf2);\n"
667 "\n"
668 " aSubTree.Inverse = mix (-UNIT, UNIT, step (ZERO, aSubTree.TrsfRay.Direct)) /\n"
669 " max (abs (aSubTree.TrsfRay.Direct), SMALL);\n"
670 "\n"
671 " aSubTree.TrsfRay.Origin = MatrixColMultiplyPnt (theRay.Origin,\n"
672 " aInvTransf0,\n"
673 " aInvTransf1,\n"
674 " aInvTransf2,\n"
675 " aInvTransf3);\n"
676 "\n"
677 " aNode = BVH_OFFSET (aSubTree); // go to sub-root node\n"
678 "\n"
679 " aStop = aHead; // store current stack pointer\n"
680 " }\n"
681 " }\n"
682 "\n"
78607702 683 " return aTriangle;\n"
ee5befae 684 "}\n"
685 "\n"
686 "// =======================================================================\n"
687 "// function : SceneAnyHit\n"
688 "// purpose : Finds intersection with any scene triangle\n"
689 "// =======================================================================\n"
690 "float SceneAnyHit (in SRay theRay, in vec3 theInverse, in float theDistance)\n"
691 "{\n"
692 " float aFactor = 1.f;\n"
693 "\n"
694 " int aNode = 0; // node to traverse\n"
695 " int aHead = -1; // pointer of stack\n"
696 " int aStop = -1; // BVH level switch\n"
697 "\n"
698 " SSubTree aSubTree = SSubTree (theRay, theInverse, EMPTY_ROOT);\n"
699 "\n"
700 " for (bool toContinue = true; toContinue; /* none */)\n"
701 " {\n"
702 " ivec4 aData = texelFetch (uSceneNodeInfoTexture, aNode);\n"
703 "\n"
704 " if (aData.x == 0) // if inner node\n"
705 " {\n"
706 " aData.y += BVH_OFFSET (aSubTree);\n"
707 "\n"
708 " vec4 aHitTimes = vec4 (MAXFLOAT,\n"
709 " MAXFLOAT,\n"
710 " MAXFLOAT,\n"
711 " MAXFLOAT);\n"
712 "\n"
713 " vec3 aRayOriginInverse = -aSubTree.TrsfRay.Origin * aSubTree.Inverse;\n"
714 "\n"
715 " vec3 aNodeMin0 = texelFetch (uSceneMinPointTexture, aData.y + 0).xyz * aSubTree.Inverse + aRayOriginInverse;\n"
716 " vec3 aNodeMin1 = texelFetch (uSceneMinPointTexture, aData.y + 1).xyz * aSubTree.Inverse + aRayOriginInverse;\n"
717 " vec3 aNodeMin2 = texelFetch (uSceneMinPointTexture, aData.y + min (2, aData.z)).xyz * aSubTree.Inverse + aRayOriginInverse;\n"
718 " vec3 aNodeMin3 = texelFetch (uSceneMinPointTexture, aData.y + min (3, aData.z)).xyz * aSubTree.Inverse + aRayOriginInverse;\n"
719 " vec3 aNodeMax0 = texelFetch (uSceneMaxPointTexture, aData.y + 0).xyz * aSubTree.Inverse + aRayOriginInverse;\n"
720 " vec3 aNodeMax1 = texelFetch (uSceneMaxPointTexture, aData.y + 1).xyz * aSubTree.Inverse + aRayOriginInverse;\n"
721 " vec3 aNodeMax2 = texelFetch (uSceneMaxPointTexture, aData.y + min (2, aData.z)).xyz * aSubTree.Inverse + aRayOriginInverse;\n"
722 " vec3 aNodeMax3 = texelFetch (uSceneMaxPointTexture, aData.y + min (3, aData.z)).xyz * aSubTree.Inverse + aRayOriginInverse;\n"
723 "\n"
724 " vec3 aTimeMax = max (aNodeMin0, aNodeMax0);\n"
725 " vec3 aTimeMin = min (aNodeMin0, aNodeMax0);\n"
726 "\n"
727 " float aTimeLeave = min (aTimeMax.x, min (aTimeMax.y, aTimeMax.z));\n"
728 " float aTimeEnter = max (aTimeMin.x, max (aTimeMin.y, aTimeMin.z));\n"
729 "\n"
06e06389 730 " aHitTimes.x = (aTimeEnter <= aTimeLeave && aTimeEnter <= theDistance && aTimeLeave >= 0.f) ? aTimeEnter : MAXFLOAT;\n"
ee5befae 731 "\n"
732 " aTimeMax = max (aNodeMin1, aNodeMax1);\n"
733 " aTimeMin = min (aNodeMin1, aNodeMax1);\n"
734 "\n"
735 " aTimeLeave = min (aTimeMax.x, min (aTimeMax.y, aTimeMax.z));\n"
736 " aTimeEnter = max (aTimeMin.x, max (aTimeMin.y, aTimeMin.z));\n"
737 "\n"
06e06389 738 " aHitTimes.y = (aTimeEnter <= aTimeLeave && aTimeEnter <= theDistance && aTimeLeave >= 0.f) ? aTimeEnter : MAXFLOAT;\n"
ee5befae 739 "\n"
740 " aTimeMax = max (aNodeMin2, aNodeMax2);\n"
741 " aTimeMin = min (aNodeMin2, aNodeMax2);\n"
742 "\n"
743 " aTimeLeave = min (aTimeMax.x, min (aTimeMax.y, aTimeMax.z));\n"
744 " aTimeEnter = max (aTimeMin.x, max (aTimeMin.y, aTimeMin.z));\n"
745 "\n"
06e06389 746 " aHitTimes.z = (aTimeEnter <= aTimeLeave && aTimeEnter <= theDistance && aTimeLeave >= 0.f && aData.z > 1) ? aTimeEnter : MAXFLOAT;\n"
ee5befae 747 "\n"
748 " aTimeMax = max (aNodeMin3, aNodeMax3);\n"
749 " aTimeMin = min (aNodeMin3, aNodeMax3);\n"
750 "\n"
751 " aTimeLeave = min (aTimeMax.x, min (aTimeMax.y, aTimeMax.z));\n"
752 " aTimeEnter = max (aTimeMin.x, max (aTimeMin.y, aTimeMin.z));\n"
753 "\n"
06e06389 754 " aHitTimes.w = (aTimeEnter <= aTimeLeave && aTimeEnter <= theDistance && aTimeLeave >= 0.f && aData.z > 2) ? aTimeEnter : MAXFLOAT;\n"
ee5befae 755 "\n"
756 " ivec4 aChildren = ivec4 (0, 1, 2, 3);\n"
757 "\n"
758 " aChildren.xy = aHitTimes.y < aHitTimes.x ? aChildren.yx : aChildren.xy;\n"
759 " aHitTimes.xy = aHitTimes.y < aHitTimes.x ? aHitTimes.yx : aHitTimes.xy;\n"
760 " aChildren.zw = aHitTimes.w < aHitTimes.z ? aChildren.wz : aChildren.zw;\n"
761 " aHitTimes.zw = aHitTimes.w < aHitTimes.z ? aHitTimes.wz : aHitTimes.zw;\n"
762 " aChildren.xz = aHitTimes.z < aHitTimes.x ? aChildren.zx : aChildren.xz;\n"
763 " aHitTimes.xz = aHitTimes.z < aHitTimes.x ? aHitTimes.zx : aHitTimes.xz;\n"
764 " aChildren.yw = aHitTimes.w < aHitTimes.y ? aChildren.wy : aChildren.yw;\n"
765 " aHitTimes.yw = aHitTimes.w < aHitTimes.y ? aHitTimes.wy : aHitTimes.yw;\n"
766 " aChildren.yz = aHitTimes.z < aHitTimes.y ? aChildren.zy : aChildren.yz;\n"
767 " aHitTimes.yz = aHitTimes.z < aHitTimes.y ? aHitTimes.zy : aHitTimes.yz;\n"
768 "\n"
769 " if (aHitTimes.x != MAXFLOAT)\n"
770 " {\n"
771 " int aHitMask = (aHitTimes.w != MAXFLOAT ? aChildren.w : aChildren.z) << 2\n"
772 " | (aHitTimes.z != MAXFLOAT ? aChildren.z : aChildren.y);\n"
773 "\n"
774 " if (aHitTimes.y != MAXFLOAT)\n"
775 " Stack[++aHead] = aData.y | (aHitMask << 2 | aChildren.y) << 26;\n"
776 "\n"
777 " aNode = aData.y + aChildren.x;\n"
778 " }\n"
779 " else\n"
780 " {\n"
781 " toContinue = (aHead >= 0);\n"
782 "\n"
783 " if (aHead == aStop) // go to top-level BVH\n"
784 " {\n"
785 " aStop = -1; aSubTree = SSubTree (theRay, theInverse, EMPTY_ROOT);\n"
786 " }\n"
787 "\n"
788 " if (aHead >= 0)\n"
789 " aNode = pop (aHead);\n"
790 " }\n"
791 " }\n"
792 " else if (aData.x < 0) // leaf node\n"
793 " {\n"
794 " vec3 aNormal;\n"
795 " vec3 aTimeUV;\n"
796 "\n"
797 " for (int anIdx = aData.y; anIdx <= aData.z; ++anIdx)\n"
798 " {\n"
799 " ivec4 aTriangle = texelFetch (uGeometryTriangTexture, anIdx + TRG_OFFSET (aSubTree));\n"
800 "\n"
801 " vec3 aPoint0 = texelFetch (uGeometryVertexTexture, aTriangle.x += VRT_OFFSET (aSubTree)).xyz;\n"
802 " vec3 aPoint1 = texelFetch (uGeometryVertexTexture, aTriangle.y += VRT_OFFSET (aSubTree)).xyz;\n"
803 " vec3 aPoint2 = texelFetch (uGeometryVertexTexture, aTriangle.z += VRT_OFFSET (aSubTree)).xyz;\n"
804 "\n"
805 " IntersectTriangle (aSubTree.TrsfRay, aPoint0, aPoint1, aPoint2, aTimeUV, aNormal);\n"
806 "\n"
807 "#ifdef TRANSPARENT_SHADOWS\n"
808 " if (aTimeUV.x < theDistance)\n"
809 " {\n"
810 " aFactor *= 1.f - texelFetch (uRaytraceMaterialTexture, MATERIAL_TRAN (aTriangle.w)).x;\n"
811 " }\n"
812 "#else\n"
813 " if (aTimeUV.x < theDistance)\n"
814 " {\n"
815 " aFactor = 0.f;\n"
816 " }\n"
817 "#endif\n"
818 " }\n"
819 "\n"
820 " toContinue = (aHead >= 0) && (aFactor > 0.1f);\n"
821 "\n"
822 " if (aHead == aStop) // go to top-level BVH\n"
823 " {\n"
824 " aStop = -1; aSubTree = SSubTree (theRay, theInverse, EMPTY_ROOT);\n"
825 " }\n"
826 "\n"
827 " if (aHead >= 0)\n"
828 " aNode = pop (aHead);\n"
829 " }\n"
830 " else if (aData.x > 0) // switch node\n"
831 " {\n"
832 " aSubTree.SubData = ivec4 (4 * aData.x - 4, aData.yzw); // store BVH sub-root\n"
833 "\n"
834 " vec4 aInvTransf0 = texelFetch (uSceneTransformTexture, TRS_OFFSET (aSubTree) + 0);\n"
835 " vec4 aInvTransf1 = texelFetch (uSceneTransformTexture, TRS_OFFSET (aSubTree) + 1);\n"
836 " vec4 aInvTransf2 = texelFetch (uSceneTransformTexture, TRS_OFFSET (aSubTree) + 2);\n"
837 " vec4 aInvTransf3 = texelFetch (uSceneTransformTexture, TRS_OFFSET (aSubTree) + 3);\n"
838 "\n"
839 " aSubTree.TrsfRay.Direct = MatrixColMultiplyDir (theRay.Direct,\n"
840 " aInvTransf0,\n"
841 " aInvTransf1,\n"
842 " aInvTransf2);\n"
843 "\n"
844 " aSubTree.TrsfRay.Origin = MatrixColMultiplyPnt (theRay.Origin,\n"
845 " aInvTransf0,\n"
846 " aInvTransf1,\n"
847 " aInvTransf2,\n"
848 " aInvTransf3);\n"
849 "\n"
850 " aSubTree.Inverse = mix (-UNIT, UNIT, step (ZERO, aSubTree.TrsfRay.Direct)) / max (abs (aSubTree.TrsfRay.Direct), SMALL);\n"
851 "\n"
852 " aNode = BVH_OFFSET (aSubTree); // go to sub-root node\n"
853 "\n"
854 " aStop = aHead; // store current stack pointer\n"
855 " }\n"
856 " }\n"
857 "\n"
858 " return aFactor;\n"
859 "}\n"
860 "\n"
861 "#define PI 3.1415926f\n"
862 "\n"
863 "// =======================================================================\n"
864 "// function : Latlong\n"
865 "// purpose : Converts world direction to environment texture coordinates\n"
866 "// =======================================================================\n"
867 "vec2 Latlong (in vec3 thePoint, in float theRadius)\n"
868 "{\n"
869 " float aPsi = acos (-thePoint.z / theRadius);\n"
870 "\n"
871 " float aPhi = atan (thePoint.y, thePoint.x) + PI;\n"
872 "\n"
873 " return vec2 (aPhi * 0.1591549f,\n"
874 " aPsi * 0.3183098f);\n"
875 "}\n"
876 "\n"
89d855ba 877 "#ifdef BACKGROUND_CUBEMAP\n"
878 "//! Transform texture coordinates for cubemap lookup.\n"
879 "vec3 cubemapVectorTransform (in vec3 theVec, in float theRadius)\n"
880 "{\n"
881 " vec3 aVec = theVec.yzx;\n"
882 " aVec.y *= float(uYCoeff);\n"
883 " aVec.z *= float(uZCoeff);\n"
884 " return aVec;\n"
885 "}\n"
886 "#endif\n"
887 "\n"
ee5befae 888 "// =======================================================================\n"
889 "// function : SmoothNormal\n"
890 "// purpose : Interpolates normal across the triangle\n"
891 "// =======================================================================\n"
892 "vec3 SmoothNormal (in vec2 theUV, in ivec4 theTriangle)\n"
893 "{\n"
894 " vec3 aNormal0 = texelFetch (uGeometryNormalTexture, theTriangle.x).xyz;\n"
895 " vec3 aNormal1 = texelFetch (uGeometryNormalTexture, theTriangle.y).xyz;\n"
896 " vec3 aNormal2 = texelFetch (uGeometryNormalTexture, theTriangle.z).xyz;\n"
897 "\n"
898 " return normalize (aNormal1 * theUV.x +\n"
899 " aNormal2 * theUV.y +\n"
900 " aNormal0 * (1.0f - theUV.x - theUV.y));\n"
901 "}\n"
902 "\n"
903 "#define POLYGON_OFFSET_UNIT 0.f\n"
904 "#define POLYGON_OFFSET_FACTOR 1.f\n"
905 "#define POLYGON_OFFSET_SCALE 0.006f\n"
906 "\n"
907 "// =======================================================================\n"
908 "// function : PolygonOffset\n"
909 "// purpose : Computes OpenGL polygon offset\n"
910 "// =======================================================================\n"
911 "float PolygonOffset (in vec3 theNormal, in vec3 thePoint)\n"
912 "{\n"
913 " vec4 aProjectedNorm = vec4 (theNormal, -dot (theNormal, thePoint)) * uUnviewMat;\n"
914 "\n"
915 " float aPolygonOffset = POLYGON_OFFSET_UNIT;\n"
916 "\n"
917 " if (aProjectedNorm.z * aProjectedNorm.z > 1e-20f)\n"
918 " {\n"
919 " aProjectedNorm.xy *= 1.f / aProjectedNorm.z;\n"
920 "\n"
921 " aPolygonOffset += POLYGON_OFFSET_FACTOR * max (abs (aProjectedNorm.x),\n"
922 " abs (aProjectedNorm.y));\n"
923 " }\n"
924 "\n"
925 " return aPolygonOffset;\n"
926 "}\n"
927 "\n"
928 "// =======================================================================\n"
929 "// function : SmoothUV\n"
930 "// purpose : Interpolates UV coordinates across the triangle\n"
931 "// =======================================================================\n"
932 "#ifdef USE_TEXTURES\n"
78607702 933 "vec2 SmoothUV (in vec2 theUV, in ivec4 theTriangle, out vec2[3] theUVs)\n"
ee5befae 934 "{\n"
78607702 935 " theUVs[0] = texelFetch (uGeometryTexCrdTexture, theTriangle.x).st;\n"
936 " theUVs[1] = texelFetch (uGeometryTexCrdTexture, theTriangle.y).st;\n"
937 " theUVs[2] = texelFetch (uGeometryTexCrdTexture, theTriangle.z).st;\n"
ee5befae 938 "\n"
78607702 939 " return theUVs[1] * theUV.x +\n"
940 " theUVs[2] * theUV.y +\n"
941 " theUVs[0] * (1.0f - theUV.x - theUV.y);\n"
942 "}\n"
943 "\n"
944 "vec2 SmoothUV (in vec2 theUV, in ivec4 theTriangle)\n"
945 "{\n"
946 " vec2 aUVs[3];\n"
947 " return SmoothUV (theUV, theTriangle, aUVs);\n"
ee5befae 948 "}\n"
949 "#endif\n"
950 "\n"
951 "// =======================================================================\n"
952 "// function : FetchEnvironment\n"
953 "// purpose :\n"
954 "// =======================================================================\n"
89d855ba 955 "vec4 FetchEnvironment (in vec3 theTexCoord, in float theRadius, in bool theIsBackground)\n"
ee5befae 956 "{\n"
89d855ba 957 " if (uEnvMapEnabled == 0)\n"
958 " {\n"
959 "#ifdef PATH_TRACING\n"
960 " return theIsBackground ? vec4 (0.0, 0.0, 0.0, 1.0) : uGlobalAmbient;\n"
961 "#else\n"
962 " return vec4 (0.0, 0.0, 0.0, 1.0);\n"
963 "#endif\n"
964 " }\n"
965 "\n"
966 " vec4 anAmbScale = theIsBackground ? vec4(1.0) : uGlobalAmbient;\n"
967 " vec4 anEnvColor =\n"
968 "#ifdef BACKGROUND_CUBEMAP\n"
969 " textureLod (uEnvMapTexture, cubemapVectorTransform (theTexCoord, theRadius), 0.0);\n"
970 "#else\n"
971 " textureLod (uEnvMapTexture, Latlong (theTexCoord, theRadius), 0.0);\n"
972 "#endif\n"
973 " return anEnvColor * anAmbScale;\n"
ee5befae 974 "}\n"
975 "\n"
976 "// =======================================================================\n"
977 "// function : Refract\n"
978 "// purpose : Computes refraction ray (also handles TIR)\n"
979 "// =======================================================================\n"
980 "#ifndef PATH_TRACING\n"
981 "vec3 Refract (in vec3 theInput,\n"
982 " in vec3 theNormal,\n"
983 " in float theRefractIndex,\n"
984 " in float theInvRefractIndex)\n"
985 "{\n"
986 " float aNdotI = dot (theInput, theNormal);\n"
987 "\n"
988 " float anIndex = aNdotI < 0.0f\n"
989 " ? theInvRefractIndex\n"
990 " : theRefractIndex;\n"
991 "\n"
992 " float aSquare = anIndex * anIndex * (1.0f - aNdotI * aNdotI);\n"
993 "\n"
994 " if (aSquare > 1.0f)\n"
995 " {\n"
996 " return reflect (theInput, theNormal);\n"
997 " }\n"
998 "\n"
999 " float aNdotT = sqrt (1.0f - aSquare);\n"
1000 "\n"
1001 " return normalize (anIndex * theInput -\n"
1002 " (anIndex * aNdotI + (aNdotI < 0.0f ? aNdotT : -aNdotT)) * theNormal);\n"
1003 "}\n"
1004 "#endif\n"
1005 "\n"
1006 "#define MIN_SLOPE 0.0001f\n"
1007 "#define EPS_SCALE 8.0000f\n"
1008 "\n"
1009 "#define THRESHOLD vec3 (0.1f)\n"
1010 "\n"
1011 "#define INVALID_BOUNCES 1000\n"
1012 "\n"
1013 "#define LIGHT_POS(index) (2 * index + 1)\n"
1014 "#define LIGHT_PWR(index) (2 * index + 0)\n"
1015 "\n"
1016 "// =======================================================================\n"
1017 "// function : Radiance\n"
1018 "// purpose : Computes color along the given ray\n"
1019 "// =======================================================================\n"
1020 "#ifndef PATH_TRACING\n"
1021 "vec4 Radiance (in SRay theRay, in vec3 theInverse)\n"
1022 "{\n"
1023 " vec3 aResult = vec3 (0.0f);\n"
1024 " vec4 aWeight = vec4 (1.0f);\n"
1025 "\n"
1026 " int aTrsfId;\n"
1027 "\n"
1028 " float aRaytraceDepth = MAXFLOAT;\n"
832a6f44 1029 " float aRefractionIdx = 0.0;\n"
ee5befae 1030 "\n"
1031 " for (int aDepth = 0; aDepth < NB_BOUNCES; ++aDepth)\n"
1032 " {\n"
1033 " SIntersect aHit = SIntersect (MAXFLOAT, vec2 (ZERO), ZERO);\n"
1034 "\n"
78607702 1035 " ivec4 aTriIndex = SceneNearestHit (theRay, theInverse, aHit, aTrsfId).TriIndex;\n"
ee5befae 1036 "\n"
1037 " if (aTriIndex.x == -1)\n"
1038 " {\n"
1039 " vec4 aColor = vec4 (0.0);\n"
1040 "\n"
832a6f44 1041 " if (bool(uEnvMapForBack) || aWeight.w == 0.0 /* reflection */)\n"
ee5befae 1042 " {\n"
832a6f44 1043 " float aRadius = uSceneRadius;\n"
1044 " vec3 aTexCoord = vec3 (0.0);\n"
ee5befae 1045 "\n"
832a6f44 1046 " if (aDepth == 0 || (aRefractionIdx == 1.0 && aWeight.w != 0.0))\n"
1047 " {\n"
1048 " vec2 aPixel = uEyeSize * (vPixel - vec2 (0.5)) * 2.0;\n"
1049 " vec2 anAperturePnt = sampleUniformDisk() * uApertureRadius;\n"
1050 " vec3 aLocalDir = normalize (vec3 (aPixel * uFocalPlaneDist - anAperturePnt, uFocalPlaneDist));\n"
1051 " vec3 aDirect = uEyeView * aLocalDir.z +\n"
1052 " uEyeSide * aLocalDir.x +\n"
1053 " uEyeVert * aLocalDir.y;\n"
1054 " \n"
1055 " aTexCoord = aDirect * uSceneRadius;\n"
1056 " aRadius = length (aTexCoord);\n"
1057 " }\n"
1058 " else\n"
1059 " {\n"
1060 " float aTime = IntersectSphere (theRay, uSceneRadius);\n"
1061 " aTexCoord = theRay.Direct * aTime + theRay.Origin;\n"
1062 " }\n"
1063 "\n"
1064 " aColor = FetchEnvironment (aTexCoord, aRadius, aWeight.w != 0.0);\n"
ee5befae 1065 " }\n"
1066 " else\n"
1067 " {\n"
1068 " aColor = BackgroundColor();\n"
1069 " }\n"
1070 "\n"
1071 " aResult += aWeight.xyz * aColor.xyz; aWeight.w *= aColor.w;\n"
1072 "\n"
1073 " break; // terminate path\n"
1074 " }\n"
1075 "\n"
1076 " vec3 aInvTransf0 = texelFetch (uSceneTransformTexture, aTrsfId + 0).xyz;\n"
1077 " vec3 aInvTransf1 = texelFetch (uSceneTransformTexture, aTrsfId + 1).xyz;\n"
1078 " vec3 aInvTransf2 = texelFetch (uSceneTransformTexture, aTrsfId + 2).xyz;\n"
1079 "\n"
1080 " aHit.Normal = normalize (vec3 (dot (aInvTransf0, aHit.Normal),\n"
1081 " dot (aInvTransf1, aHit.Normal),\n"
1082 " dot (aInvTransf2, aHit.Normal)));\n"
1083 "\n"
1084 " theRay.Origin += theRay.Direct * aHit.Time; // intersection point\n"
1085 "\n"
1086 " // Evaluate depth on first hit\n"
1087 " if (aDepth == 0)\n"
1088 " {\n"
1089 " vec4 aNDCPoint = uViewMat * vec4 (theRay.Origin, 1.f);\n"
1090 "\n"
1091 " float aPolygonOffset = PolygonOffset (aHit.Normal, theRay.Origin);\n"
1092 " aRaytraceDepth = (aNDCPoint.z / aNDCPoint.w + aPolygonOffset * POLYGON_OFFSET_SCALE) * 0.5f + 0.5f;\n"
1093 " }\n"
1094 "\n"
1095 " vec3 aNormal = SmoothNormal (aHit.UV, aTriIndex);\n"
1096 "\n"
1097 " aNormal = normalize (vec3 (dot (aInvTransf0, aNormal),\n"
1098 " dot (aInvTransf1, aNormal),\n"
1099 " dot (aInvTransf2, aNormal)));\n"
1100 "\n"
1101 " vec3 aAmbient = texelFetch (\n"
1102 " uRaytraceMaterialTexture, MATERIAL_AMBN (aTriIndex.w)).rgb;\n"
1103 " vec4 aDiffuse = texelFetch (\n"
1104 " uRaytraceMaterialTexture, MATERIAL_DIFF (aTriIndex.w));\n"
1105 " vec4 aSpecular = texelFetch (\n"
1106 " uRaytraceMaterialTexture, MATERIAL_SPEC (aTriIndex.w));\n"
1107 " vec4 aOpacity = texelFetch (\n"
1108 " uRaytraceMaterialTexture, MATERIAL_TRAN (aTriIndex.w));\n"
1109 "\n"
1110 "#ifdef USE_TEXTURES\n"
1111 " if (aDiffuse.w >= 0.f)\n"
1112 " {\n"
1113 " vec4 aTexCoord = vec4 (SmoothUV (aHit.UV, aTriIndex), 0.f, 1.f);\n"
1114 "\n"
1115 " vec4 aTrsfRow1 = texelFetch (\n"
1116 " uRaytraceMaterialTexture, MATERIAL_TRS1 (aTriIndex.w));\n"
1117 " vec4 aTrsfRow2 = texelFetch (\n"
1118 " uRaytraceMaterialTexture, MATERIAL_TRS2 (aTriIndex.w));\n"
1119 "\n"
1120 " aTexCoord.st = vec2 (dot (aTrsfRow1, aTexCoord),\n"
1121 " dot (aTrsfRow2, aTexCoord));\n"
1122 "\n"
f411f94f 1123 " vec4 aTexColor = textureLod (\n"
1124 " sampler2D (uTextureSamplers[int(aDiffuse.w)]), aTexCoord.st, 0.f);\n"
ee5befae 1125 "\n"
f411f94f 1126 " aDiffuse.rgb *= aTexColor.rgb;\n"
1127 " aAmbient.rgb *= aTexColor.rgb;\n"
1128 "\n"
1129 " // keep refractive index untouched (Z component)\n"
1130 " aOpacity.xy = vec2 (aTexColor.w * aOpacity.x, 1.0f - aTexColor.w * aOpacity.x);\n"
ee5befae 1131 " }\n"
1132 "#endif\n"
1133 "\n"
1134 " vec3 aEmission = texelFetch (\n"
1135 " uRaytraceMaterialTexture, MATERIAL_EMIS (aTriIndex.w)).rgb;\n"
1136 "\n"
1137 " float aGeomFactor = dot (aNormal, theRay.Direct);\n"
1138 "\n"
1139 " aResult.xyz += aWeight.xyz * aOpacity.x * (\n"
1140 " uGlobalAmbient.xyz * aAmbient * max (abs (aGeomFactor), 0.5f) + aEmission);\n"
1141 "\n"
1142 " vec3 aSidedNormal = mix (aNormal, -aNormal, step (0.0f, aGeomFactor));\n"
1143 "\n"
1144 " for (int aLightIdx = 0; aLightIdx < uLightCount; ++aLightIdx)\n"
1145 " {\n"
1146 " vec4 aLight = texelFetch (\n"
1147 " uRaytraceLightSrcTexture, LIGHT_POS (aLightIdx));\n"
1148 "\n"
1149 " float aDistance = MAXFLOAT;\n"
1150 "\n"
1151 " if (aLight.w != 0.0f) // point light source\n"
1152 " {\n"
1153 " aDistance = length (aLight.xyz -= theRay.Origin);\n"
1154 "\n"
1155 " aLight.xyz *= 1.0f / aDistance;\n"
1156 " }\n"
1157 "\n"
1158 " float aLdotN = dot (aLight.xyz, aSidedNormal);\n"
1159 "\n"
1160 " if (aLdotN > 0.0f) // first check if light source is important\n"
1161 " {\n"
1162 " float aVisibility = 1.0f;\n"
1163 "\n"
1164 " if (bool(uShadowsEnabled))\n"
1165 " {\n"
1166 " SRay aShadow = SRay (theRay.Origin, aLight.xyz);\n"
1167 "\n"
1168 " aShadow.Origin += uSceneEpsilon * (aLight.xyz +\n"
1169 " mix (-aHit.Normal, aHit.Normal, step (0.0f, dot (aHit.Normal, aLight.xyz))));\n"
1170 "\n"
1171 " vec3 aInverse = 1.0f / max (abs (aLight.xyz), SMALL);\n"
1172 "\n"
1173 " aVisibility = SceneAnyHit (\n"
1174 " aShadow, mix (-aInverse, aInverse, step (ZERO, aLight.xyz)), aDistance);\n"
1175 " }\n"
1176 "\n"
1177 " if (aVisibility > 0.0f)\n"
1178 " {\n"
6e728f3b 1179 " vec3 aIntensity = min (UNIT, vec3 (texelFetch (\n"
1180 " uRaytraceLightSrcTexture, LIGHT_PWR (aLightIdx))));\n"
ee5befae 1181 "\n"
1182 " float aRdotV = dot (reflect (aLight.xyz, aSidedNormal), theRay.Direct);\n"
1183 "\n"
1184 " aResult.xyz += aWeight.xyz * (aOpacity.x * aVisibility) * aIntensity *\n"
1185 " (aDiffuse.xyz * aLdotN + aSpecular.xyz * pow (max (0.f, aRdotV), aSpecular.w));\n"
1186 " }\n"
1187 " }\n"
1188 " }\n"
1189 "\n"
1190 " if (aOpacity.x != 1.0f)\n"
1191 " {\n"
1192 " aWeight *= aOpacity.y;\n"
832a6f44 1193 " aRefractionIdx = aOpacity.z;\n"
ee5befae 1194 "\n"
1195 " if (aOpacity.z != 1.0f)\n"
1196 " {\n"
1197 " theRay.Direct = Refract (theRay.Direct, aNormal, aOpacity.z, aOpacity.w);\n"
1198 " }\n"
1199 " }\n"
1200 " else\n"
1201 " {\n"
1202 " aWeight *= bool(uReflectEnabled) ?\n"
1203 " texelFetch (uRaytraceMaterialTexture, MATERIAL_REFL (aTriIndex.w)) : vec4 (0.0f);\n"
1204 "\n"
1205 " vec3 aReflect = reflect (theRay.Direct, aNormal);\n"
1206 "\n"
1207 " if (dot (aReflect, aHit.Normal) * dot (theRay.Direct, aHit.Normal) > 0.0f)\n"
1208 " {\n"
1209 " aReflect = reflect (theRay.Direct, aHit.Normal);\n"
1210 " }\n"
1211 "\n"
1212 " theRay.Direct = aReflect;\n"
1213 " }\n"
1214 "\n"
1215 " if (all (lessThanEqual (aWeight.xyz, THRESHOLD)))\n"
1216 " {\n"
1217 " aDepth = INVALID_BOUNCES;\n"
1218 " }\n"
1219 " else if (aOpacity.x == 1.0f || aOpacity.z != 1.0f) // if no simple transparency\n"
1220 " {\n"
1221 " theRay.Origin += aHit.Normal * mix (\n"
1222 " -uSceneEpsilon, uSceneEpsilon, step (0.0f, dot (aHit.Normal, theRay.Direct)));\n"
1223 "\n"
1224 " theInverse = 1.0f / max (abs (theRay.Direct), SMALL);\n"
1225 "\n"
1226 " theInverse = mix (-theInverse, theInverse, step (ZERO, theRay.Direct));\n"
1227 " }\n"
1228 "\n"
1229 " theRay.Origin += theRay.Direct * uSceneEpsilon;\n"
1230 " }\n"
1231 "\n"
1232 " gl_FragDepth = aRaytraceDepth;\n"
1233 "\n"
1234 " return vec4 (aResult.x,\n"
1235 " aResult.y,\n"
1236 " aResult.z,\n"
1237 " aWeight.w);\n"
1238 "}\n"
1239 "#endif\n";