942d9f64e5174fa08c1e144b3cd63f39c01896d9
[occt.git] / src / Shaders / Shaders_RaytraceBase_fs.pxx
1 // This file has been automatically generated from resource file src/Shaders/RaytraceBase.fs
2
3 static const char Shaders_RaytraceBase_fs[] =
4   "#ifdef ADAPTIVE_SAMPLING\n"
5   "  #extension GL_ARB_shader_image_load_store : require\n"
6   "#endif\n"
7   "#ifdef ADAPTIVE_SAMPLING_ATOMIC\n"
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"
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"
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"
98   "//! Enables/disables environment map lighting.\n"
99   "uniform int uEnvMapEnabled;\n"
100   "//! Enables/disables environment map background.\n"
101   "uniform int uEnvMapForBack;\n"
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"
115   "  volatile restrict layout(r32f) uniform image2D  uRenderImage;\n"
116   "\n"
117   "#ifdef ADAPTIVE_SAMPLING_ATOMIC\n"
118   "  //! OpenGL image storing offsets of sampled pixels blocks.\n"
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"
124   "\n"
125   "  //! Screen space tile size.\n"
126   "  uniform ivec2 uTileSize;\n"
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"
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"
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"
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"
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"
198   "#define M_PI   3.141592653f\n"
199   "#define M_2_PI 6.283185307f\n"
200   "#define M_PI_2 1.570796327f\n"
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"
305   "#ifdef ADAPTIVE_SAMPLING_ATOMIC\n"
306   "\n"
307   "  ivec2 aFragCoord = ivec2 (gl_FragCoord.xy);\n"
308   "\n"
309   "  ivec2 aTileXY = imageLoad (uOffsetImage, aFragCoord / uTileSize).xy * uTileSize;\n"
310   "\n"
311   "  aTileXY.y += aFragCoord.y % min (uWinSizeY - aTileXY.y, uTileSize.y);\n"
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"
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"
354   "// =======================================================================\n"
355   "// function : GenerateRay\n"
356   "// purpose  :\n"
357   "// =======================================================================\n"
358   "SRay GenerateRay (in vec2 thePixel)\n"
359   "{\n"
360   "#ifndef DEPTH_OF_FIELD\n"
361   "\n"
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"
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"
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"
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"
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"
476   "#define INVALID_HIT ivec4 (-1)\n"
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"
512   "STriangle SceneNearestHit (in SRay theRay, in vec3 theInverse, inout SIntersect theHit, out int theTrsfId)\n"
513   "{\n"
514   "  STriangle aTriangle = STriangle (INVALID_HIT, vec3[](vec3(0.0), vec3(0.0), vec3(0.0)));\n"
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"
552   "      aHitTimes.x = (aTimeEnter <= aTimeLeave && aTimeEnter <= theHit.Time && aTimeLeave >= 0.f) ? aTimeEnter : MAXFLOAT;\n"
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"
560   "      aHitTimes.y = (aTimeEnter <= aTimeLeave && aTimeEnter <= theHit.Time && aTimeLeave >= 0.f) ? aTimeEnter : MAXFLOAT;\n"
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"
568   "      aHitTimes.z = (aTimeEnter <= aTimeLeave && aTimeEnter <= theHit.Time && aTimeLeave >= 0.f && aData.z > 1) ? aTimeEnter : MAXFLOAT;\n"
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"
576   "      aHitTimes.w = (aTimeEnter <= aTimeLeave && aTimeEnter <= theHit.Time && aTimeLeave >= 0.f && aData.z > 2) ? aTimeEnter : MAXFLOAT;\n"
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"
621   "        ivec4 aTriIndex = texelFetch (uGeometryTriangTexture, anIdx + TRG_OFFSET (aSubTree));\n"
622   "        vec3 aPoints[3];\n"
623   "\n"
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"
627   "\n"
628   "        IntersectTriangle (aSubTree.TrsfRay, aPoints[0], aPoints[1], aPoints[2], aTimeUV, aNormal);\n"
629   "\n"
630   "        if (aTimeUV.x < theHit.Time)\n"
631   "        {\n"
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"
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"
683   "  return aTriangle;\n"
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"
730   "      aHitTimes.x = (aTimeEnter <= aTimeLeave && aTimeEnter <= theDistance && aTimeLeave >= 0.f) ? aTimeEnter : MAXFLOAT;\n"
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"
738   "      aHitTimes.y = (aTimeEnter <= aTimeLeave && aTimeEnter <= theDistance && aTimeLeave >= 0.f) ? aTimeEnter : MAXFLOAT;\n"
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"
746   "      aHitTimes.z = (aTimeEnter <= aTimeLeave && aTimeEnter <= theDistance && aTimeLeave >= 0.f && aData.z > 1) ? aTimeEnter : MAXFLOAT;\n"
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"
754   "      aHitTimes.w = (aTimeEnter <= aTimeLeave && aTimeEnter <= theDistance && aTimeLeave >= 0.f && aData.z > 2) ? aTimeEnter : MAXFLOAT;\n"
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"
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"
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"
933   "vec2 SmoothUV (in vec2 theUV, in ivec4 theTriangle, out vec2[3] theUVs)\n"
934   "{\n"
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"
938   "\n"
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"
948   "}\n"
949   "#endif\n"
950   "\n"
951   "// =======================================================================\n"
952   "// function : FetchEnvironment\n"
953   "// purpose  :\n"
954   "// =======================================================================\n"
955   "vec4 FetchEnvironment (in vec3 theTexCoord, in float theRadius, in bool theIsBackground)\n"
956   "{\n"
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"
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"
1029   "  float aRefractionIdx = 0.0;\n"
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"
1035   "    ivec4 aTriIndex = SceneNearestHit (theRay, theInverse, aHit, aTrsfId).TriIndex;\n"
1036   "\n"
1037   "    if (aTriIndex.x == -1)\n"
1038   "    {\n"
1039   "      vec4 aColor = vec4 (0.0);\n"
1040   "\n"
1041   "      if (bool(uEnvMapForBack) || aWeight.w == 0.0 /* reflection */)\n"
1042   "      {\n"
1043   "        float aRadius = uSceneRadius;\n"
1044   "        vec3 aTexCoord = vec3 (0.0);\n"
1045   "\n"
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"
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"
1123   "      vec4 aTexColor = textureLod (\n"
1124   "        sampler2D (uTextureSamplers[int(aDiffuse.w)]), aTexCoord.st, 0.f);\n"
1125   "\n"
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"
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"
1179   "          vec3 aIntensity = min (UNIT, vec3 (texelFetch (\n"
1180   "            uRaytraceLightSrcTexture, LIGHT_PWR (aLightIdx))));\n"
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"
1193   "      aRefractionIdx = aOpacity.z;\n"
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";