occt-gltf-addon-linux-x64 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (214) hide show
  1. package/LICENSE_LGPL_21.txt +502 -0
  2. package/OCCT_LGPL_EXCEPTION.txt +10 -0
  3. package/README.md +2 -2
  4. package/index.js +63 -1
  5. package/lib/libTKBO.so.8.0.0 +0 -0
  6. package/lib/libTKBRep.so.8.0.0 +0 -0
  7. package/lib/libTKBin.so.8.0.0 +0 -0
  8. package/lib/libTKBinL.so.8.0.0 +0 -0
  9. package/lib/libTKBinTObj.so.8.0.0 +0 -0
  10. package/lib/libTKBinXCAF.so.8.0.0 +0 -0
  11. package/lib/libTKBool.so.8.0.0 +0 -0
  12. package/lib/libTKCAF.so.8.0.0 +0 -0
  13. package/lib/libTKCDF.so.8.0.0 +0 -0
  14. package/lib/libTKDE.so.8.0.0 +0 -0
  15. package/lib/libTKDECascade.so.8.0.0 +0 -0
  16. package/lib/libTKDEIGES.so.8.0.0 +0 -0
  17. package/lib/libTKDEOBJ.so.8.0.0 +0 -0
  18. package/lib/libTKDEPLY.so.8.0.0 +0 -0
  19. package/lib/libTKDESTEP.so.8.0.0 +0 -0
  20. package/lib/libTKDESTL.so.8.0.0 +0 -0
  21. package/lib/libTKDEVRML.so.8.0.0 +0 -0
  22. package/lib/libTKExpress.so.8.0.0 +0 -0
  23. package/lib/libTKFeat.so.8.0.0 +0 -0
  24. package/lib/libTKFillet.so.8.0.0 +0 -0
  25. package/lib/libTKG2d.so.8.0.0 +0 -0
  26. package/lib/libTKG3d.so.8.0.0 +0 -0
  27. package/lib/libTKGeomAlgo.so.8.0.0 +0 -0
  28. package/lib/libTKGeomBase.so.8.0.0 +0 -0
  29. package/lib/libTKHLR.so.8.0.0 +0 -0
  30. package/lib/libTKHelix.so.8.0.0 +0 -0
  31. package/lib/libTKLCAF.so.8.0.0 +0 -0
  32. package/lib/libTKMath.so.8.0.0 +0 -0
  33. package/lib/libTKMesh.so.8.0.0 +0 -0
  34. package/lib/libTKOffset.so.8.0.0 +0 -0
  35. package/lib/libTKPrim.so.8.0.0 +0 -0
  36. package/lib/libTKRWMesh.so.8.0.0 +0 -0
  37. package/lib/libTKService.so.8.0.0 +0 -0
  38. package/lib/libTKShHealing.so.8.0.0 +0 -0
  39. package/lib/libTKStd.so.8.0.0 +0 -0
  40. package/lib/libTKStdL.so.8.0.0 +0 -0
  41. package/lib/libTKTObj.so.8.0.0 +0 -0
  42. package/lib/libTKTopAlgo.so.8.0.0 +0 -0
  43. package/lib/libTKV3d.so.8.0.0 +0 -0
  44. package/lib/libTKVCAF.so.8.0.0 +0 -0
  45. package/lib/libTKXCAF.so.8.0.0 +0 -0
  46. package/lib/libTKXMesh.so.8.0.0 +0 -0
  47. package/lib/libTKXSBase.so.8.0.0 +0 -0
  48. package/lib/libTKXml.so.8.0.0 +0 -0
  49. package/lib/libTKXmlL.so.8.0.0 +0 -0
  50. package/lib/libTKXmlTObj.so.8.0.0 +0 -0
  51. package/lib/libTKXmlXCAF.so.8.0.0 +0 -0
  52. package/lib/libTKernel.so.8.0.0 +0 -0
  53. package/lib/libdraco.so.1 +0 -0
  54. package/lib/libtbb.so.2 +0 -0
  55. package/lib/libtbbmalloc.so.2 +0 -0
  56. package/lib/libtbbmalloc_proxy.so.2 +0 -0
  57. package/occt_gltf_addon.node +0 -0
  58. package/package.json +6 -2
  59. package/resources/BOPAlgo/BOPAlgo.msg +129 -0
  60. package/resources/BOPAlgo/FILES +1 -0
  61. package/resources/DrawResources/CURVES.tcl +38 -0
  62. package/resources/DrawResources/CheckCommands.tcl +1206 -0
  63. package/resources/DrawResources/DrawDefault +130 -0
  64. package/resources/DrawResources/DrawPlugin +64 -0
  65. package/resources/DrawResources/DrawTK.tcl +623 -0
  66. package/resources/DrawResources/FILES +16 -0
  67. package/resources/DrawResources/Geometry.tcl +96 -0
  68. package/resources/DrawResources/InitEnvironment.tcl +50 -0
  69. package/resources/DrawResources/Move.tcl +85 -0
  70. package/resources/DrawResources/OCC_logo.png +0 -0
  71. package/resources/DrawResources/PROFIL.tcl +726 -0
  72. package/resources/DrawResources/SCAN.tcl +192 -0
  73. package/resources/DrawResources/SURFACES.tcl +35 -0
  74. package/resources/DrawResources/StandardCommands.tcl +451 -0
  75. package/resources/DrawResources/StandardViews.tcl +284 -0
  76. package/resources/DrawResources/TKTopTest.tcl +27 -0
  77. package/resources/DrawResources/TestCommands.tcl +2969 -0
  78. package/resources/DrawResources/Vector.tcl +402 -0
  79. package/resources/DrawResources/dfb_attribns.gif +0 -0
  80. package/resources/DrawResources/dfb_attribute.gif +0 -0
  81. package/resources/DrawResources/dfb_folder.gif +0 -0
  82. package/resources/DrawResources/dftree.tcl +381 -0
  83. package/resources/DrawResources/lamp.ico +0 -0
  84. package/resources/SHMessage/FILES +2 -0
  85. package/resources/SHMessage/SHAPE.fr +267 -0
  86. package/resources/SHMessage/SHAPE.us +267 -0
  87. package/resources/Shaders/Declarations.glsl +276 -0
  88. package/resources/Shaders/DeclarationsImpl.glsl +121 -0
  89. package/resources/Shaders/Display.fs +157 -0
  90. package/resources/Shaders/FILES +27 -0
  91. package/resources/Shaders/LightShadow.glsl +48 -0
  92. package/resources/Shaders/PBRCookTorrance.glsl +20 -0
  93. package/resources/Shaders/PBRDirectionalLight.glsl +20 -0
  94. package/resources/Shaders/PBRDistribution.glsl +9 -0
  95. package/resources/Shaders/PBREnvBaking.fs +226 -0
  96. package/resources/Shaders/PBREnvBaking.vs +55 -0
  97. package/resources/Shaders/PBRFresnel.glsl +36 -0
  98. package/resources/Shaders/PBRGeometry.glsl +13 -0
  99. package/resources/Shaders/PBRIllumination.glsl +28 -0
  100. package/resources/Shaders/PBRPointLight.glsl +27 -0
  101. package/resources/Shaders/PBRSpotLight.glsl +45 -0
  102. package/resources/Shaders/PathtraceBase.fs +993 -0
  103. package/resources/Shaders/PhongDirectionalLight.glsl +29 -0
  104. package/resources/Shaders/PhongPointLight.glsl +36 -0
  105. package/resources/Shaders/PhongShading.fs +191 -0
  106. package/resources/Shaders/PhongShading.vs +43 -0
  107. package/resources/Shaders/PhongSpotLight.glsl +52 -0
  108. package/resources/Shaders/PointLightAttenuation.glsl +35 -0
  109. package/resources/Shaders/RaytraceBase.fs +1236 -0
  110. package/resources/Shaders/RaytraceBase.vs +12 -0
  111. package/resources/Shaders/RaytraceRender.fs +134 -0
  112. package/resources/Shaders/RaytraceSmooth.fs +80 -0
  113. package/resources/Shaders/SkydomBackground.fs +300 -0
  114. package/resources/Shaders/TangentSpaceNormal.glsl +17 -0
  115. package/resources/StdResource/FILES +6 -0
  116. package/resources/StdResource/MigrationSheet.txt +21 -0
  117. package/resources/StdResource/Plugin +52 -0
  118. package/resources/StdResource/Standard +25 -0
  119. package/resources/StdResource/StandardLite +22 -0
  120. package/resources/StdResource/TObj +17 -0
  121. package/resources/StdResource/XCAF +50 -0
  122. package/resources/TObj/FILES +1 -0
  123. package/resources/TObj/TObj.msg +85 -0
  124. package/resources/Textures/1d_elevation.rgb +0 -0
  125. package/resources/Textures/2d_MatraDatavision.rgb +0 -0
  126. package/resources/Textures/2d_alienskin.rgb +0 -0
  127. package/resources/Textures/2d_aluminum.rgb +0 -0
  128. package/resources/Textures/2d_blue_rock.rgb +0 -0
  129. package/resources/Textures/2d_bluewhite_paper.rgb +0 -0
  130. package/resources/Textures/2d_brushed.rgb +0 -0
  131. package/resources/Textures/2d_bubbles.rgb +0 -0
  132. package/resources/Textures/2d_bumps.rgb +0 -0
  133. package/resources/Textures/2d_cast.rgb +0 -0
  134. package/resources/Textures/2d_chess.rgba +0 -0
  135. package/resources/Textures/2d_chipbd.rgb +0 -0
  136. package/resources/Textures/2d_clouds.rgb +0 -0
  137. package/resources/Textures/2d_flesh.rgb +0 -0
  138. package/resources/Textures/2d_floor.rgb +0 -0
  139. package/resources/Textures/2d_galvnisd.rgb +0 -0
  140. package/resources/Textures/2d_grass.rgb +0 -0
  141. package/resources/Textures/2d_knurl.rgb +0 -0
  142. package/resources/Textures/2d_maple.rgb +0 -0
  143. package/resources/Textures/2d_marble.rgb +0 -0
  144. package/resources/Textures/2d_mottled.rgb +0 -0
  145. package/resources/Textures/2d_rain.rgb +0 -0
  146. package/resources/Textures/2d_rock.rgb +0 -0
  147. package/resources/Textures/FILES +31 -0
  148. package/resources/Textures/env_clouds.rgb +0 -0
  149. package/resources/Textures/env_cv.rgb +0 -0
  150. package/resources/Textures/env_lines.rgb +0 -0
  151. package/resources/Textures/env_medit.rgb +0 -0
  152. package/resources/Textures/env_pearl.rgb +0 -0
  153. package/resources/Textures/env_road.rgb +0 -0
  154. package/resources/Textures/env_sky1.rgb +0 -0
  155. package/resources/Textures/env_sky2.rgb +0 -0
  156. package/resources/UnitsAPI/CurrentUnits +74 -0
  157. package/resources/UnitsAPI/FILES +4 -0
  158. package/resources/UnitsAPI/MDTVBaseUnits +70 -0
  159. package/resources/UnitsAPI/MDTVCurrentUnits +74 -0
  160. package/resources/UnitsAPI/Units.dat +481 -0
  161. package/resources/XRResources/FILES +10 -0
  162. package/resources/XRResources/occtvr_actions.json +225 -0
  163. package/resources/XRResources/occtvr_bindings_generic.json +87 -0
  164. package/resources/XRResources/occtvr_bindings_holographic_hmd.json +18 -0
  165. package/resources/XRResources/occtvr_bindings_index_hmd.json +18 -0
  166. package/resources/XRResources/occtvr_bindings_rift.json +18 -0
  167. package/resources/XRResources/occtvr_bindings_touch.json +160 -0
  168. package/resources/XRResources/occtvr_bindings_vive.json +18 -0
  169. package/resources/XRResources/occtvr_bindings_vive_controller.json +139 -0
  170. package/resources/XRResources/occtvr_bindings_vive_cosmos.json +18 -0
  171. package/resources/XRResources/occtvr_bindings_vive_pro.json +18 -0
  172. package/resources/XSMessage/FILES +2 -0
  173. package/resources/XSMessage/XSTEP.fr +1026 -0
  174. package/resources/XSMessage/XSTEP.us +1023 -0
  175. package/resources/XSTEPResource/FILES +2 -0
  176. package/resources/XSTEPResource/IGES +65 -0
  177. package/resources/XSTEPResource/STEP +68 -0
  178. package/resources/XmlOcafResource/FILES +11 -0
  179. package/resources/XmlOcafResource/XmlOcaf.xsd +131 -0
  180. package/resources/XmlOcafResource/XmlOcaf_SmallTypes.xsd +217 -0
  181. package/resources/XmlOcafResource/XmlOcaf_TDF.xsd +33 -0
  182. package/resources/XmlOcafResource/XmlOcaf_TDataStd.xsd +230 -0
  183. package/resources/XmlOcafResource/XmlOcaf_TDataStd_Name.xsd +37 -0
  184. package/resources/XmlOcafResource/XmlOcaf_TDocStd.xsd +37 -0
  185. package/resources/XmlOcafResource/XmlOcaf_TFunction.xsd +38 -0
  186. package/resources/XmlOcafResource/XmlOcaf_TNaming.xsd +128 -0
  187. package/resources/XmlOcafResource/XmlOcaf_TNaming_NamedShape.xsd +97 -0
  188. package/resources/XmlOcafResource/XmlOcaf_TPrsStd.xsd +42 -0
  189. package/resources/XmlOcafResource/XmlXcaf.xsd +109 -0
  190. package/resources/samples/tcl/ANC101.tcl +282 -0
  191. package/resources/samples/tcl/DataExchangeDemo.tcl +85 -0
  192. package/resources/samples/tcl/MBBGehauseRohteil.tcl +268 -0
  193. package/resources/samples/tcl/ModelingDemo.tcl +120 -0
  194. package/resources/samples/tcl/Penrose.tcl +87 -0
  195. package/resources/samples/tcl/Readme.txt +4 -0
  196. package/resources/samples/tcl/VisualizationDemo.tcl +162 -0
  197. package/resources/samples/tcl/bottle.tcl +115 -0
  198. package/resources/samples/tcl/cad.tcl +63 -0
  199. package/resources/samples/tcl/cpu.tcl +327 -0
  200. package/resources/samples/tcl/cutter.tcl +91 -0
  201. package/resources/samples/tcl/dimensions.tcl +83 -0
  202. package/resources/samples/tcl/drill.tcl +147 -0
  203. package/resources/samples/tcl/logo2019.tcl +89 -0
  204. package/resources/samples/tcl/markers.tcl +76 -0
  205. package/resources/samples/tcl/materials.tcl +75 -0
  206. package/resources/samples/tcl/pathtrace_ball.tcl +79 -0
  207. package/resources/samples/tcl/pathtrace_cube.tcl +85 -0
  208. package/resources/samples/tcl/pathtrace_materials.tcl +229 -0
  209. package/resources/samples/tcl/pencil.tcl +64 -0
  210. package/resources/samples/tcl/raytrace.tcl +44 -0
  211. package/resources/samples/tcl/snowflake.tcl +161 -0
  212. package/resources/samples/tcl/spheres.tcl +148 -0
  213. package/resources/samples/tcl/vis_pbr_spheres.tcl +94 -0
  214. package/resources/samples/tcl/xde.tcl +47 -0
@@ -0,0 +1,993 @@
1
+ #ifdef _MSC_VER
2
+ #define PATH_TRACING // just for editing in MS VS
3
+
4
+ #define in
5
+ #define out
6
+ #define inout
7
+
8
+ typedef struct { float x; float y; } vec2;
9
+ typedef struct { float x; float y; float z; } vec3;
10
+ typedef struct { float x; float y; float z; float w; } vec4;
11
+ #endif
12
+
13
+ #ifdef PATH_TRACING
14
+
15
+ ///////////////////////////////////////////////////////////////////////////////////////
16
+ // Specific data types
17
+
18
+ //! Describes local space at the hit point (visualization space).
19
+ struct SLocalSpace
20
+ {
21
+ //! Local X axis.
22
+ vec3 AxisX;
23
+
24
+ //! Local Y axis.
25
+ vec3 AxisY;
26
+
27
+ //! Local Z axis.
28
+ vec3 AxisZ;
29
+ };
30
+
31
+ //! Describes material properties (BSDF).
32
+ struct SBSDF
33
+ {
34
+ //! Weight of coat specular/glossy BRDF.
35
+ vec4 Kc;
36
+
37
+ //! Weight of base diffuse BRDF + base color texture index in W.
38
+ vec4 Kd;
39
+
40
+ //! Weight of base specular/glossy BRDF.
41
+ vec4 Ks;
42
+
43
+ //! Weight of base specular/glossy BTDF + metallic-roughness texture index in W.
44
+ vec4 Kt;
45
+
46
+ //! Fresnel coefficients of coat layer.
47
+ vec3 FresnelCoat;
48
+
49
+ //! Fresnel coefficients of base layer + normal map texture index in W.
50
+ vec4 FresnelBase;
51
+ };
52
+
53
+ ///////////////////////////////////////////////////////////////////////////////////////
54
+ // Support subroutines
55
+
56
+ //=======================================================================
57
+ // function : buildLocalSpace
58
+ // purpose : Generates local space for the given normal
59
+ //=======================================================================
60
+ SLocalSpace buildLocalSpace (in vec3 theNormal)
61
+ {
62
+ vec3 anAxisX = vec3 (theNormal.z, 0.f, -theNormal.x);
63
+ vec3 anAxisY = vec3 (0.f, -theNormal.z, theNormal.y);
64
+
65
+ float aSqrLenX = dot (anAxisX, anAxisX);
66
+ float aSqrLenY = dot (anAxisY, anAxisY);
67
+
68
+ if (aSqrLenX > aSqrLenY)
69
+ {
70
+ anAxisX *= inversesqrt (aSqrLenX);
71
+ anAxisY = cross (anAxisX, theNormal);
72
+ }
73
+ else
74
+ {
75
+ anAxisY *= inversesqrt (aSqrLenY);
76
+ anAxisX = cross (anAxisY, theNormal);
77
+ }
78
+
79
+ return SLocalSpace (anAxisX, anAxisY, theNormal);
80
+ }
81
+
82
+ //=======================================================================
83
+ // function : toLocalSpace
84
+ // purpose : Transforms the vector to local space from world space
85
+ //=======================================================================
86
+ vec3 toLocalSpace (in vec3 theVector, in SLocalSpace theSpace)
87
+ {
88
+ return vec3 (dot (theVector, theSpace.AxisX),
89
+ dot (theVector, theSpace.AxisY),
90
+ dot (theVector, theSpace.AxisZ));
91
+ }
92
+
93
+ //=======================================================================
94
+ // function : fromLocalSpace
95
+ // purpose : Transforms the vector from local space to world space
96
+ //=======================================================================
97
+ vec3 fromLocalSpace (in vec3 theVector, in SLocalSpace theSpace)
98
+ {
99
+ return theVector.x * theSpace.AxisX +
100
+ theVector.y * theSpace.AxisY +
101
+ theVector.z * theSpace.AxisZ;
102
+ }
103
+
104
+ //=======================================================================
105
+ // function : convolve
106
+ // purpose : Performs a linear convolution of the vector components
107
+ //=======================================================================
108
+ float convolve (in vec3 theVector, in vec3 theFactor)
109
+ {
110
+ return dot (theVector, theFactor) * (1.f / max (theFactor.x + theFactor.y + theFactor.z, 1e-15f));
111
+ }
112
+
113
+ //=======================================================================
114
+ // function : fresnelSchlick
115
+ // purpose : Computes the Fresnel reflection formula using
116
+ // Schlick's approximation.
117
+ //=======================================================================
118
+ vec3 fresnelSchlick (in float theCosI, in vec3 theSpecularColor)
119
+ {
120
+ return theSpecularColor + (UNIT - theSpecularColor) * pow (1.f - theCosI, 5.f);
121
+ }
122
+
123
+ //=======================================================================
124
+ // function : fresnelDielectric
125
+ // purpose : Computes the Fresnel reflection formula for dielectric in
126
+ // case of circularly polarized light (Based on PBRT code).
127
+ //=======================================================================
128
+ float fresnelDielectric (in float theCosI,
129
+ in float theCosT,
130
+ in float theEtaI,
131
+ in float theEtaT)
132
+ {
133
+ float aParl = (theEtaT * theCosI - theEtaI * theCosT) /
134
+ (theEtaT * theCosI + theEtaI * theCosT);
135
+
136
+ float aPerp = (theEtaI * theCosI - theEtaT * theCosT) /
137
+ (theEtaI * theCosI + theEtaT * theCosT);
138
+
139
+ return (aParl * aParl + aPerp * aPerp) * 0.5f;
140
+ }
141
+
142
+ #define ENVIRONMENT_IOR 1.f
143
+
144
+ //=======================================================================
145
+ // function : fresnelDielectric
146
+ // purpose : Computes the Fresnel reflection formula for dielectric in
147
+ // case of circularly polarized light (based on PBRT code)
148
+ //=======================================================================
149
+ float fresnelDielectric (in float theCosI, in float theIndex)
150
+ {
151
+ float aFresnel = 1.f;
152
+
153
+ float anEtaI = theCosI > 0.f ? 1.f : theIndex;
154
+ float anEtaT = theCosI > 0.f ? theIndex : 1.f;
155
+
156
+ float aSinT2 = (anEtaI * anEtaI) / (anEtaT * anEtaT) * (1.f - theCosI * theCosI);
157
+
158
+ if (aSinT2 < 1.f)
159
+ {
160
+ aFresnel = fresnelDielectric (abs (theCosI), sqrt (1.f - aSinT2), anEtaI, anEtaT);
161
+ }
162
+
163
+ return aFresnel;
164
+ }
165
+
166
+ //=======================================================================
167
+ // function : fresnelConductor
168
+ // purpose : Computes the Fresnel reflection formula for conductor in case
169
+ // of circularly polarized light (based on PBRT source code)
170
+ //=======================================================================
171
+ float fresnelConductor (in float theCosI, in float theEta, in float theK)
172
+ {
173
+ float aTmp = 2.f * theEta * theCosI;
174
+
175
+ float aTmp1 = theEta * theEta + theK * theK;
176
+
177
+ float aSPerp = (aTmp1 - aTmp + theCosI * theCosI) /
178
+ (aTmp1 + aTmp + theCosI * theCosI);
179
+
180
+ float aTmp2 = aTmp1 * theCosI * theCosI;
181
+
182
+ float aSParl = (aTmp2 - aTmp + 1.f) /
183
+ (aTmp2 + aTmp + 1.f);
184
+
185
+ return (aSPerp + aSParl) * 0.5f;
186
+ }
187
+
188
+ #define FRESNEL_SCHLICK -0.5f
189
+ #define FRESNEL_CONSTANT -1.5f
190
+ #define FRESNEL_CONDUCTOR -2.5f
191
+ #define FRESNEL_DIELECTRIC -3.5f
192
+
193
+ //=======================================================================
194
+ // function : fresnelMedia
195
+ // purpose : Computes the Fresnel reflection formula for general medium
196
+ // in case of circularly polarized light.
197
+ //=======================================================================
198
+ vec3 fresnelMedia (in float theCosI, in vec3 theFresnel)
199
+ {
200
+ vec3 aFresnel;
201
+
202
+ if (theFresnel.x > FRESNEL_SCHLICK)
203
+ {
204
+ aFresnel = fresnelSchlick (abs (theCosI), theFresnel);
205
+ }
206
+ else if (theFresnel.x > FRESNEL_CONSTANT)
207
+ {
208
+ aFresnel = vec3 (theFresnel.z);
209
+ }
210
+ else if (theFresnel.x > FRESNEL_CONDUCTOR)
211
+ {
212
+ aFresnel = vec3 (fresnelConductor (abs (theCosI), theFresnel.y, theFresnel.z));
213
+ }
214
+ else
215
+ {
216
+ aFresnel = vec3 (fresnelDielectric (theCosI, theFresnel.y));
217
+ }
218
+
219
+ return aFresnel;
220
+ }
221
+
222
+ //=======================================================================
223
+ // function : transmitted
224
+ // purpose : Computes transmitted direction in tangent space
225
+ // (in case of TIR returned result is undefined!)
226
+ //=======================================================================
227
+ void transmitted (in float theIndex, in vec3 theIncident, out vec3 theTransmit)
228
+ {
229
+ // Compute relative index of refraction
230
+ float anEta = (theIncident.z > 0.f) ? 1.f / theIndex : theIndex;
231
+
232
+ // Handle total internal reflection (TIR)
233
+ float aSinT2 = anEta * anEta * (1.f - theIncident.z * theIncident.z);
234
+
235
+ // Compute direction of transmitted ray
236
+ float aCosT = sqrt (1.f - min (aSinT2, 1.f)) * sign (-theIncident.z);
237
+
238
+ theTransmit = normalize (vec3 (-anEta * theIncident.x,
239
+ -anEta * theIncident.y,
240
+ aCosT));
241
+ }
242
+
243
+ //////////////////////////////////////////////////////////////////////////////////////////////
244
+ // Handlers and samplers for materials
245
+ //////////////////////////////////////////////////////////////////////////////////////////////
246
+
247
+ //=======================================================================
248
+ // function : EvalLambertianReflection
249
+ // purpose : Evaluates Lambertian BRDF, with cos(N, PSI)
250
+ //=======================================================================
251
+ float EvalLambertianReflection (in vec3 theWi, in vec3 theWo)
252
+ {
253
+ return (theWi.z <= 0.f || theWo.z <= 0.f) ? 0.f : theWi.z * (1.f / M_PI);
254
+ }
255
+
256
+ #define FLT_EPSILON 1.0e-5f
257
+
258
+ //=======================================================================
259
+ // function : SmithG1
260
+ // purpose :
261
+ //=======================================================================
262
+ float SmithG1 (in vec3 theDirection, in vec3 theM, in float theRoughness)
263
+ {
264
+ float aResult = 0.f;
265
+
266
+ if (dot (theDirection, theM) * theDirection.z > 0.f)
267
+ {
268
+ float aTanThetaM = sqrt (1.f - theDirection.z * theDirection.z) / theDirection.z;
269
+
270
+ if (aTanThetaM == 0.f)
271
+ {
272
+ aResult = 1.f;
273
+ }
274
+ else
275
+ {
276
+ float aVal = 1.f / (theRoughness * aTanThetaM);
277
+
278
+ // Use rational approximation to shadowing-masking function (from Mitsuba)
279
+ aResult = (3.535f + 2.181f * aVal) / (1.f / aVal + 2.276f + 2.577f * aVal);
280
+ }
281
+ }
282
+
283
+ return min (aResult, 1.f);
284
+ }
285
+
286
+ //=======================================================================
287
+ // function : EvalBlinnReflection
288
+ // purpose : Evaluates Blinn glossy BRDF, with cos(N, PSI)
289
+ //=======================================================================
290
+ vec3 EvalBlinnReflection (in vec3 theWi, in vec3 theWo, in vec3 theFresnel, in float theRoughness)
291
+ {
292
+ // calculate the reflection half-vec
293
+ vec3 aH = normalize (theWi + theWo);
294
+
295
+ // roughness value -> Blinn exponent
296
+ float aPower = max (2.f / (theRoughness * theRoughness) - 2.f, 0.f);
297
+
298
+ // calculate microfacet distribution
299
+ float aD = (aPower + 2.f) * (1.f / M_2_PI) * pow (aH.z, aPower);
300
+
301
+ // calculate shadow-masking function
302
+ float aG = SmithG1 (theWo, aH, theRoughness) *
303
+ SmithG1 (theWi, aH, theRoughness);
304
+
305
+ // return total amount of reflection
306
+ return (theWi.z <= 0.f || theWo.z <= 0.f) ? ZERO :
307
+ aD * aG / (4.f * theWo.z) * fresnelMedia (dot (theWo, aH), theFresnel);
308
+ }
309
+
310
+ //=======================================================================
311
+ // function : EvalBsdfLayered
312
+ // purpose : Evaluates BSDF for specified material, with cos(N, PSI)
313
+ //=======================================================================
314
+ vec3 EvalBsdfLayered (in SBSDF theBSDF, in vec3 theWi, in vec3 theWo)
315
+ {
316
+ #ifdef TWO_SIDED_BXDF
317
+ theWi.z *= sign (theWi.z);
318
+ theWo.z *= sign (theWo.z);
319
+ #endif
320
+
321
+ vec3 aBxDF = theBSDF.Kd.rgb * EvalLambertianReflection (theWi, theWo);
322
+
323
+ if (theBSDF.Ks.w > FLT_EPSILON)
324
+ {
325
+ aBxDF += theBSDF.Ks.rgb * EvalBlinnReflection (theWi, theWo, theBSDF.FresnelBase.rgb, theBSDF.Ks.w);
326
+ }
327
+
328
+ aBxDF *= UNIT - fresnelMedia (theWo.z, theBSDF.FresnelCoat);
329
+
330
+ if (theBSDF.Kc.w > FLT_EPSILON)
331
+ {
332
+ aBxDF += theBSDF.Kc.rgb * EvalBlinnReflection (theWi, theWo, theBSDF.FresnelCoat, theBSDF.Kc.w);
333
+ }
334
+
335
+ return aBxDF;
336
+ }
337
+
338
+ //=======================================================================
339
+ // function : SampleLambertianReflection
340
+ // purpose : Samples Lambertian BRDF, W = BRDF * cos(N, PSI) / PDF(PSI)
341
+ //=======================================================================
342
+ vec3 SampleLambertianReflection (in vec3 theWo, out vec3 theWi, inout float thePDF)
343
+ {
344
+ float aKsi1 = RandFloat();
345
+ float aKsi2 = RandFloat();
346
+
347
+ theWi = vec3 (cos (M_2_PI * aKsi1),
348
+ sin (M_2_PI * aKsi1),
349
+ sqrt (1.f - aKsi2));
350
+
351
+ theWi.xy *= sqrt (aKsi2);
352
+
353
+ #ifdef TWO_SIDED_BXDF
354
+ theWi.z *= sign (theWo.z);
355
+ #endif
356
+
357
+ thePDF *= theWi.z * (1.f / M_PI);
358
+
359
+ #ifdef TWO_SIDED_BXDF
360
+ return UNIT;
361
+ #else
362
+ return UNIT * step (0.f, theWo.z);
363
+ #endif
364
+ }
365
+
366
+ //=======================================================================
367
+ // function : SampleGlossyBlinnReflection
368
+ // purpose : Samples Blinn BRDF, W = BRDF * cos(N, PSI) / PDF(PSI)
369
+ // The BRDF is a product of three main terms, D, G, and F,
370
+ // which is then divided by two cosine terms. Here we perform
371
+ // importance sample the D part of the Blinn model; trying to
372
+ // develop a sampling procedure that accounted for all of the
373
+ // terms would be complex, and it is the D term that accounts
374
+ // for most of the variation.
375
+ //=======================================================================
376
+ vec3 SampleGlossyBlinnReflection (in vec3 theWo, out vec3 theWi, in vec3 theFresnel, in float theRoughness, inout float thePDF)
377
+ {
378
+ float aKsi1 = RandFloat();
379
+ float aKsi2 = RandFloat();
380
+
381
+ // roughness value --> Blinn exponent
382
+ float aPower = max (2.f / (theRoughness * theRoughness) - 2.f, 0.f);
383
+
384
+ // normal from microface distribution
385
+ float aCosThetaM = pow (aKsi1, 1.f / (aPower + 2.f));
386
+
387
+ vec3 aM = vec3 (cos (M_2_PI * aKsi2),
388
+ sin (M_2_PI * aKsi2),
389
+ aCosThetaM);
390
+
391
+ aM.xy *= sqrt (1.f - aCosThetaM * aCosThetaM);
392
+
393
+ // calculate PDF of sampled direction
394
+ thePDF *= (aPower + 2.f) * (1.f / M_2_PI) * pow (aCosThetaM, aPower + 1.f);
395
+
396
+ #ifdef TWO_SIDED_BXDF
397
+ bool toFlip = theWo.z < 0.f;
398
+
399
+ if (toFlip)
400
+ theWo.z = -theWo.z;
401
+ #endif
402
+
403
+ float aCosDelta = dot (theWo, aM);
404
+
405
+ // pick input based on half direction
406
+ theWi = -theWo + 2.f * aCosDelta * aM;
407
+
408
+ if (theWi.z <= 0.f || theWo.z <= 0.f)
409
+ {
410
+ return ZERO;
411
+ }
412
+
413
+ // Jacobian of half-direction mapping
414
+ thePDF /= 4.f * aCosDelta;
415
+
416
+ // compute shadow-masking coefficient
417
+ float aG = SmithG1 (theWo, aM, theRoughness) *
418
+ SmithG1 (theWi, aM, theRoughness);
419
+
420
+ #ifdef TWO_SIDED_BXDF
421
+ if (toFlip)
422
+ theWi.z = -theWi.z;
423
+ #endif
424
+
425
+ return (aG * aCosDelta) / (theWo.z * aM.z) * fresnelMedia (aCosDelta, theFresnel);
426
+ }
427
+
428
+ //=======================================================================
429
+ // function : BsdfPdfLayered
430
+ // purpose : Calculates BSDF of sampling input knowing output
431
+ //=======================================================================
432
+ float BsdfPdfLayered (in SBSDF theBSDF, in vec3 theWo, in vec3 theWi, in vec3 theWeight)
433
+ {
434
+ float aPDF = 0.f; // PDF of sampling input direction
435
+
436
+ // We choose whether the light is reflected or transmitted
437
+ // by the coating layer according to the Fresnel equations
438
+ vec3 aCoatF = fresnelMedia (theWo.z, theBSDF.FresnelCoat);
439
+
440
+ // Coat BRDF is scaled by its Fresnel reflectance term. For
441
+ // reasons of simplicity we scale base BxDFs only by coat's
442
+ // Fresnel transmittance term
443
+ vec3 aCoatT = UNIT - aCoatF;
444
+
445
+ float aPc = dot (theBSDF.Kc.rgb * aCoatF, theWeight);
446
+ float aPd = dot (theBSDF.Kd.rgb * aCoatT, theWeight);
447
+ float aPs = dot (theBSDF.Ks.rgb * aCoatT, theWeight);
448
+ float aPt = dot (theBSDF.Kt.rgb * aCoatT, theWeight);
449
+
450
+ if (theWi.z * theWo.z > 0.f)
451
+ {
452
+ vec3 aH = normalize (theWi + theWo);
453
+
454
+ aPDF = aPd * abs (theWi.z / M_PI);
455
+
456
+ if (theBSDF.Kc.w > FLT_EPSILON)
457
+ {
458
+ float aPower = max (2.f / (theBSDF.Kc.w * theBSDF.Kc.w) - 2.f, 0.f); // roughness --> exponent
459
+
460
+ aPDF += aPc * (aPower + 2.f) * (0.25f / M_2_PI) * pow (abs (aH.z), aPower + 1.f) / dot (theWi, aH);
461
+ }
462
+
463
+ if (theBSDF.Ks.w > FLT_EPSILON)
464
+ {
465
+ float aPower = max (2.f / (theBSDF.Ks.w * theBSDF.Ks.w) - 2.f, 0.f); // roughness --> exponent
466
+
467
+ aPDF += aPs * (aPower + 2.f) * (0.25f / M_2_PI) * pow (abs (aH.z), aPower + 1.f) / dot (theWi, aH);
468
+ }
469
+ }
470
+
471
+ return aPDF / (aPc + aPd + aPs + aPt);
472
+ }
473
+
474
+ //! Tool macro to handle sampling of particular BxDF
475
+ #define PICK_BXDF_LAYER(p, k) aPDF = p / aTotalR; theWeight *= k / aPDF;
476
+
477
+ //=======================================================================
478
+ // function : SampleBsdfLayered
479
+ // purpose : Samples specified composite material (BSDF)
480
+ //=======================================================================
481
+ float SampleBsdfLayered (in SBSDF theBSDF, in vec3 theWo, out vec3 theWi, inout vec3 theWeight, inout bool theInside)
482
+ {
483
+ // NOTE: OCCT uses two-layer material model. We have base diffuse, glossy, or transmissive
484
+ // layer, covered by one glossy/specular coat. In the current model, the layers themselves
485
+ // have no thickness; they can simply reflect light or transmits it to the layer under it.
486
+ // We use actual BRDF model only for direct reflection by the coat layer. For transmission
487
+ // through this layer, we approximate it as a flat specular surface.
488
+
489
+ float aPDF = 0.f; // PDF of sampled direction
490
+
491
+ // We choose whether the light is reflected or transmitted
492
+ // by the coating layer according to the Fresnel equations
493
+ vec3 aCoatF = fresnelMedia (theWo.z, theBSDF.FresnelCoat);
494
+
495
+ // Coat BRDF is scaled by its Fresnel term. According to
496
+ // Wilkie-Weidlich layered BSDF model, transmission term
497
+ // for light passing through the coat at direction I and
498
+ // leaving it in O is T = ( 1 - F (O) ) x ( 1 - F (I) ).
499
+ // For reasons of simplicity, we discard the second term
500
+ // and scale base BxDFs only by the first term.
501
+ vec3 aCoatT = UNIT - aCoatF;
502
+
503
+ float aPc = dot (theBSDF.Kc.rgb * aCoatF, theWeight);
504
+ float aPd = dot (theBSDF.Kd.rgb * aCoatT, theWeight);
505
+ float aPs = dot (theBSDF.Ks.rgb * aCoatT, theWeight);
506
+ float aPt = dot (theBSDF.Kt.rgb * aCoatT, theWeight);
507
+
508
+ // Calculate total reflection probability
509
+ float aTotalR = (aPc + aPd) + (aPs + aPt);
510
+
511
+ // Generate random variable to select BxDF
512
+ float aKsi = aTotalR * RandFloat();
513
+
514
+ if (aKsi < aPc) // REFLECTION FROM COAT
515
+ {
516
+ PICK_BXDF_LAYER (aPc, theBSDF.Kc.rgb)
517
+
518
+ if (theBSDF.Kc.w < FLT_EPSILON)
519
+ {
520
+ theWeight *= aCoatF;
521
+
522
+ theWi = vec3 (-theWo.x,
523
+ -theWo.y,
524
+ theWo.z);
525
+ }
526
+ else
527
+ {
528
+ theWeight *= SampleGlossyBlinnReflection (theWo, theWi, theBSDF.FresnelCoat, theBSDF.Kc.w, aPDF);
529
+ }
530
+
531
+ aPDF = mix (aPDF, MAXFLOAT, theBSDF.Kc.w < FLT_EPSILON);
532
+ }
533
+ else if (aKsi < aTotalR) // REFLECTION FROM BASE
534
+ {
535
+ theWeight *= aCoatT;
536
+
537
+ if (aKsi < aPc + aPd) // diffuse BRDF
538
+ {
539
+ PICK_BXDF_LAYER (aPd, theBSDF.Kd.rgb)
540
+
541
+ theWeight *= SampleLambertianReflection (theWo, theWi, aPDF);
542
+ }
543
+ else if (aKsi < (aPc + aPd) + aPs) // specular/glossy BRDF
544
+ {
545
+ PICK_BXDF_LAYER (aPs, theBSDF.Ks.rgb)
546
+
547
+ if (theBSDF.Ks.w < FLT_EPSILON)
548
+ {
549
+ theWeight *= fresnelMedia (theWo.z, theBSDF.FresnelBase.rgb);
550
+
551
+ theWi = vec3 (-theWo.x,
552
+ -theWo.y,
553
+ theWo.z);
554
+ }
555
+ else
556
+ {
557
+ theWeight *= SampleGlossyBlinnReflection (theWo, theWi, theBSDF.FresnelBase.rgb, theBSDF.Ks.w, aPDF);
558
+ }
559
+
560
+ aPDF = mix (aPDF, MAXFLOAT, theBSDF.Ks.w < FLT_EPSILON);
561
+ }
562
+ else // specular transmission
563
+ {
564
+ PICK_BXDF_LAYER (aPt, theBSDF.Kt.rgb)
565
+
566
+ // refracted direction should exist if we are here
567
+ transmitted (theBSDF.FresnelCoat.y, theWo, theWi);
568
+
569
+ theInside = !theInside; aPDF = MAXFLOAT;
570
+ }
571
+ }
572
+
573
+ // path termination for extra small weights
574
+ theWeight = mix (ZERO, theWeight, step (FLT_EPSILON, aTotalR));
575
+
576
+ return aPDF;
577
+ }
578
+
579
+ //////////////////////////////////////////////////////////////////////////////////////////////
580
+ // Handlers and samplers for light sources
581
+ //////////////////////////////////////////////////////////////////////////////////////////////
582
+
583
+ //=======================================================================
584
+ // function : SampleLight
585
+ // purpose : General sampling function for directional and point lights
586
+ //=======================================================================
587
+ vec3 SampleLight (in vec3 theToLight, inout float theDistance, in bool isInfinite, in float theSmoothness, inout float thePDF)
588
+ {
589
+ SLocalSpace aSpace = buildLocalSpace (theToLight * (1.f / theDistance));
590
+
591
+ // for point lights smoothness defines radius
592
+ float aCosMax = isInfinite ? theSmoothness :
593
+ inversesqrt (1.f + theSmoothness * theSmoothness / (theDistance * theDistance));
594
+
595
+ float aKsi1 = RandFloat();
596
+ float aKsi2 = RandFloat();
597
+
598
+ float aTmp = 1.f - aKsi2 * (1.f - aCosMax);
599
+
600
+ vec3 anInput = vec3 (cos (M_2_PI * aKsi1),
601
+ sin (M_2_PI * aKsi1),
602
+ aTmp);
603
+
604
+ anInput.xy *= sqrt (1.f - aTmp * aTmp);
605
+
606
+ thePDF = (aCosMax < 1.f) ? (thePDF / M_2_PI) / (1.f - aCosMax) : MAXFLOAT;
607
+
608
+ return normalize (fromLocalSpace (anInput, aSpace));
609
+ }
610
+
611
+ //=======================================================================
612
+ // function : HandlePointLight
613
+ // purpose :
614
+ //=======================================================================
615
+ float HandlePointLight (in vec3 theInput, in vec3 theToLight, in float theRadius, in float theDistance, inout float thePDF)
616
+ {
617
+ float aCosMax = inversesqrt (1.f + theRadius * theRadius / (theDistance * theDistance));
618
+
619
+ float aVisibility = step (aCosMax, dot (theInput, theToLight));
620
+
621
+ thePDF *= step (-1.f, -aCosMax) * aVisibility * (1.f / M_2_PI) / (1.f - aCosMax);
622
+
623
+ return aVisibility;
624
+ }
625
+
626
+ //=======================================================================
627
+ // function : HandleDistantLight
628
+ // purpose :
629
+ //=======================================================================
630
+ float HandleDistantLight (in vec3 theInput, in vec3 theToLight, in float theCosMax, inout float thePDF)
631
+ {
632
+ float aVisibility = step (theCosMax, dot (theInput, theToLight));
633
+
634
+ thePDF *= step (-1.f, -theCosMax) * aVisibility * (1.f / M_2_PI) / (1.f - theCosMax);
635
+
636
+ return aVisibility;
637
+ }
638
+
639
+ // =======================================================================
640
+ // function: IntersectLight
641
+ // purpose : Checks intersections with light sources
642
+ // =======================================================================
643
+ vec3 IntersectLight (in SRay theRay, in int theDepth, in float theHitDistance, out float thePDF)
644
+ {
645
+ vec3 aTotalRadiance = ZERO;
646
+ thePDF = 0.f; // PDF of sampling light sources
647
+ for (int aLightIdx = 0; aLightIdx < uLightCount; ++aLightIdx)
648
+ {
649
+ vec4 aLight = texelFetch (uRaytraceLightSrcTexture, LIGHT_POS (aLightIdx));
650
+ vec4 aParam = texelFetch (uRaytraceLightSrcTexture, LIGHT_PWR (aLightIdx));
651
+
652
+ // W component: 0 for infinite light and 1 for point light
653
+ aLight.xyz -= mix (ZERO, theRay.Origin, aLight.w);
654
+ float aPDF = 1.0 / float(uLightCount);
655
+ if (aLight.w != 0.f) // point light source
656
+ {
657
+ float aCenterDst = length (aLight.xyz);
658
+ if (aCenterDst < theHitDistance)
659
+ {
660
+ float aVisibility = HandlePointLight (
661
+ theRay.Direct, normalize (aLight.xyz), aParam.w /* radius */, aCenterDst, aPDF);
662
+
663
+ if (aVisibility > 0.f)
664
+ {
665
+ theHitDistance = aCenterDst;
666
+ aTotalRadiance = aParam.rgb;
667
+
668
+ thePDF = aPDF;
669
+ }
670
+ }
671
+ }
672
+ else if (theHitDistance == MAXFLOAT) // directional light source
673
+ {
674
+ aTotalRadiance += aParam.rgb * HandleDistantLight (
675
+ theRay.Direct, aLight.xyz, aParam.w /* angle cosine */, aPDF);
676
+
677
+ thePDF += aPDF;
678
+ }
679
+ }
680
+
681
+ if (thePDF == 0.f && theHitDistance == MAXFLOAT) // light source not found
682
+ {
683
+ if (theDepth + uEnvMapForBack == 0) // view ray and map is hidden
684
+ {
685
+ aTotalRadiance = BackgroundColor().rgb;
686
+ }
687
+ else
688
+ {
689
+ #ifdef BACKGROUND_CUBEMAP
690
+ if (theDepth == 0)
691
+ {
692
+ vec2 aPixel = uEyeSize * (vPixel - vec2 (0.5)) * 2.0;
693
+ vec2 anAperturePnt = sampleUniformDisk() * uApertureRadius;
694
+ vec3 aLocalDir = normalize (vec3 (aPixel * uFocalPlaneDist - anAperturePnt, uFocalPlaneDist));
695
+ vec3 aDirect = uEyeView * aLocalDir.z +
696
+ uEyeSide * aLocalDir.x +
697
+ uEyeVert * aLocalDir.y;
698
+ aTotalRadiance = FetchEnvironment (aDirect, 1.0, true).rgb;
699
+ }
700
+ else
701
+ {
702
+ aTotalRadiance = FetchEnvironment (theRay.Direct, 1.0, false).rgb;
703
+ }
704
+ #else
705
+ aTotalRadiance = FetchEnvironment (theRay.Direct, 1.0, theDepth == 0).rgb;
706
+ #endif
707
+ }
708
+ #ifdef THE_SHIFT_sRGB
709
+ aTotalRadiance = pow (aTotalRadiance, vec3 (2.f));
710
+ #endif
711
+ }
712
+
713
+ return aTotalRadiance;
714
+ }
715
+
716
+ #define MIN_THROUGHPUT vec3 (1.0e-3f)
717
+ #define MIN_CONTRIBUTION vec3 (1.0e-2f)
718
+
719
+ #define MATERIAL_KC(index) (19 * index + 11)
720
+ #define MATERIAL_KD(index) (19 * index + 12)
721
+ #define MATERIAL_KS(index) (19 * index + 13)
722
+ #define MATERIAL_KT(index) (19 * index + 14)
723
+ #define MATERIAL_LE(index) (19 * index + 15)
724
+ #define MATERIAL_FRESNEL_COAT(index) (19 * index + 16)
725
+ #define MATERIAL_FRESNEL_BASE(index) (19 * index + 17)
726
+ #define MATERIAL_ABSORPT_BASE(index) (19 * index + 18)
727
+
728
+ //! Enables experimental Russian roulette sampling path termination.
729
+ //! In most cases, it provides faster image convergence with minimal
730
+ //! bias, so it is enabled by default.
731
+ #define RUSSIAN_ROULETTE
732
+
733
+ //! Frame step to increase number of bounces. This mode is used
734
+ //! for interaction with the model, when path length is limited
735
+ //! for the first samples, and gradually increasing when camera
736
+ //! is stabilizing.
737
+ #ifdef ADAPTIVE_SAMPLING
738
+ #define FRAME_STEP 4
739
+ #else
740
+ #define FRAME_STEP 5
741
+ #endif
742
+
743
+ //=======================================================================
744
+ // function : IsNotZero
745
+ // purpose : Checks whether BSDF reflects direct light
746
+ //=======================================================================
747
+ bool IsNotZero (in SBSDF theBSDF, in vec3 theThroughput)
748
+ {
749
+ vec3 aGlossy = theBSDF.Kc.rgb * step (FLT_EPSILON, theBSDF.Kc.w) +
750
+ theBSDF.Ks.rgb * step (FLT_EPSILON, theBSDF.Ks.w);
751
+
752
+ return convolve (theBSDF.Kd.rgb + aGlossy, theThroughput) > FLT_EPSILON;
753
+ }
754
+
755
+ //=======================================================================
756
+ // function : NormalAdaptation
757
+ // purpose : Adapt smooth normal (which may be different from geometry normal) in order to avoid black areas in render
758
+ //=======================================================================
759
+ bool NormalAdaptation (in vec3 theView, in vec3 theGeometryNormal, inout vec3 theSmoothNormal)
760
+ {
761
+ float aMinCos = dot(theView, theGeometryNormal);
762
+ aMinCos = 0.5 * (sqrt(1.0 - aMinCos) + sqrt(1.0 + aMinCos));
763
+ float aCos = dot(theGeometryNormal, theSmoothNormal);
764
+ if (aCos < aMinCos)
765
+ {
766
+ theSmoothNormal = aMinCos * theGeometryNormal + normalize(theSmoothNormal - aCos * theGeometryNormal) * sqrt(1.0 - aMinCos * aMinCos);
767
+ return true;
768
+ }
769
+ return false;
770
+ }
771
+
772
+ //=======================================================================
773
+ // function : PathTrace
774
+ // purpose : Calculates radiance along the given ray
775
+ //=======================================================================
776
+ vec4 PathTrace (in SRay theRay, in vec3 theInverse, in int theNbSamples)
777
+ {
778
+ float aRaytraceDepth = MAXFLOAT;
779
+
780
+ vec3 aRadiance = ZERO;
781
+ vec3 aThroughput = UNIT;
782
+
783
+ int aTransfID = 0; // ID of object transformation
784
+ bool aInMedium = false; // is the ray inside an object
785
+
786
+ float aExpPDF = 1.f;
787
+ float aImpPDF = 1.f;
788
+
789
+ for (int aDepth = 0; aDepth < NB_BOUNCES; ++aDepth)
790
+ {
791
+ SIntersect aHit = SIntersect (MAXFLOAT, vec2 (ZERO), ZERO);
792
+
793
+ STriangle aTriangle = SceneNearestHit (theRay, theInverse, aHit, aTransfID);
794
+
795
+ // check implicit path
796
+ vec3 aLe = IntersectLight (theRay, aDepth, aHit.Time, aExpPDF);
797
+
798
+ if (any (greaterThan (aLe, ZERO)) || aTriangle.TriIndex.x == -1)
799
+ {
800
+ float aMIS = (aDepth == 0 || aImpPDF == MAXFLOAT) ? 1.f :
801
+ aImpPDF * aImpPDF / (aExpPDF * aExpPDF + aImpPDF * aImpPDF);
802
+
803
+ aRadiance += aThroughput * aLe * aMIS; break; // terminate path
804
+ }
805
+
806
+ vec3 aInvTransf0 = texelFetch (uSceneTransformTexture, aTransfID + 0).xyz;
807
+ vec3 aInvTransf1 = texelFetch (uSceneTransformTexture, aTransfID + 1).xyz;
808
+ vec3 aInvTransf2 = texelFetch (uSceneTransformTexture, aTransfID + 2).xyz;
809
+
810
+ // compute geometrical normal
811
+ aHit.Normal = normalize (vec3 (dot (aInvTransf0, aHit.Normal),
812
+ dot (aInvTransf1, aHit.Normal),
813
+ dot (aInvTransf2, aHit.Normal)));
814
+
815
+ theRay.Origin += theRay.Direct * aHit.Time; // get new intersection point
816
+
817
+ // evaluate depth on first hit
818
+ if (aDepth == 0)
819
+ {
820
+ vec4 aNDCPoint = uViewMat * vec4 (theRay.Origin, 1.f);
821
+
822
+ float aPolygonOffset = PolygonOffset (aHit.Normal, theRay.Origin);
823
+ #ifdef THE_ZERO_TO_ONE_DEPTH
824
+ aRaytraceDepth = (aNDCPoint.z / aNDCPoint.w + aPolygonOffset * POLYGON_OFFSET_SCALE);
825
+ #else
826
+ aRaytraceDepth = (aNDCPoint.z / aNDCPoint.w + aPolygonOffset * POLYGON_OFFSET_SCALE) * 0.5f + 0.5f;
827
+ #endif
828
+ }
829
+
830
+ SBSDF aBSDF;
831
+
832
+ // fetch BxDF weights
833
+ aBSDF.Kc = texelFetch (uRaytraceMaterialTexture, MATERIAL_KC (aTriangle.TriIndex.w));
834
+ aBSDF.Kd = texelFetch (uRaytraceMaterialTexture, MATERIAL_KD (aTriangle.TriIndex.w));
835
+ aBSDF.Ks = texelFetch (uRaytraceMaterialTexture, MATERIAL_KS (aTriangle.TriIndex.w));
836
+ aBSDF.Kt = texelFetch (uRaytraceMaterialTexture, MATERIAL_KT (aTriangle.TriIndex.w));
837
+
838
+ // fetch Fresnel reflectance for both layers
839
+ aBSDF.FresnelCoat = texelFetch (uRaytraceMaterialTexture, MATERIAL_FRESNEL_COAT (aTriangle.TriIndex.w)).xyz;
840
+ aBSDF.FresnelBase = texelFetch (uRaytraceMaterialTexture, MATERIAL_FRESNEL_BASE (aTriangle.TriIndex.w));
841
+
842
+ vec4 anLE = texelFetch (uRaytraceMaterialTexture, MATERIAL_LE (aTriangle.TriIndex.w));
843
+
844
+ // compute smooth normal (in parallel with fetch)
845
+ vec3 aNormal = SmoothNormal (aHit.UV, aTriangle.TriIndex);
846
+ aNormal = normalize (vec3 (dot (aInvTransf0, aNormal),
847
+ dot (aInvTransf1, aNormal),
848
+ dot (aInvTransf2, aNormal)));
849
+
850
+ #ifdef USE_TEXTURES
851
+ if (aBSDF.Kd.w >= 0.0 || aBSDF.Kt.w >= 0.0 || aBSDF.FresnelBase.w >=0.0 || anLE.w >= 0.0)
852
+ {
853
+ vec2 aUVs[3];
854
+ vec4 aTexCoord = vec4 (SmoothUV (aHit.UV, aTriangle.TriIndex, aUVs), 0.f, 1.f);
855
+ vec4 aTrsfRow1 = texelFetch (uRaytraceMaterialTexture, MATERIAL_TRS1 (aTriangle.TriIndex.w));
856
+ vec4 aTrsfRow2 = texelFetch (uRaytraceMaterialTexture, MATERIAL_TRS2 (aTriangle.TriIndex.w));
857
+ aTexCoord.st = vec2 (dot (aTrsfRow1, aTexCoord),
858
+ dot (aTrsfRow2, aTexCoord));
859
+
860
+ if (anLE.w >= 0.0)
861
+ {
862
+ anLE.rgb *= textureLod (sampler2D (uTextureSamplers[int (anLE.w)]), aTexCoord.st, 0.0).rgb;
863
+ }
864
+ if (aBSDF.Kt.w >= 0.0)
865
+ {
866
+ vec2 aTexMetRough = textureLod (sampler2D (uTextureSamplers[int (aBSDF.Kt.w)]), aTexCoord.st, 0.0).bg;
867
+ float aPbrMetal = aTexMetRough.x;
868
+ float aPbrRough2 = aTexMetRough.y * aTexMetRough.y;
869
+ aBSDF.Ks.a *= aPbrRough2;
870
+ // when using metal-roughness texture, global metalness of material (encoded in FresnelBase) is expected to be 1.0 so that Kd will be 0.0
871
+ aBSDF.Kd.rgb = aBSDF.FresnelBase.rgb * (1.0 - aPbrMetal);
872
+ aBSDF.FresnelBase.rgb *= aPbrMetal;
873
+ }
874
+ if (aBSDF.Kd.w >= 0.0)
875
+ {
876
+ vec4 aTexColor = textureLod (sampler2D (uTextureSamplers[int (aBSDF.Kd.w)]), aTexCoord.st, 0.0);
877
+ vec3 aDiff = aTexColor.rgb * aTexColor.a;
878
+ aBSDF.Kd.rgb *= aDiff;
879
+ aBSDF.FresnelBase.rgb *= aDiff;
880
+ if (aTexColor.a != 1.0)
881
+ {
882
+ // mix transparency BTDF with texture alpha-channel
883
+ aBSDF.Ks.rgb *= aTexColor.a;
884
+ aBSDF.Kt.rgb = (UNIT - aTexColor.aaa) + aTexColor.a * aBSDF.Kt.rgb;
885
+ }
886
+ }
887
+ #ifndef IGNORE_NORMAL_MAP
888
+ if (aBSDF.FresnelBase.w >= 0.0)
889
+ {
890
+ for (int i = 0 ; i < 3; ++i)
891
+ {
892
+ aUVs[i] = vec2 (dot (aTrsfRow1, vec4(aUVs[i], 0.0, 1.0)),
893
+ dot (aTrsfRow2, vec4(aUVs[i], 0.0, 1.0)));
894
+ }
895
+ vec3 aMapNormalValue = textureLod (sampler2D (uTextureSamplers[int (aBSDF.FresnelBase.w)]), aTexCoord.st, 0.0).xyz;
896
+ mat2 aDeltaUVMatrix = mat2 (aUVs[1] - aUVs[0], aUVs[1] - aUVs[2]);
897
+ mat2x3 aDeltaVectorMatrix = mat2x3 (aTriangle.Points[1] - aTriangle.Points[0], aTriangle.Points[1] - aTriangle.Points[2]);
898
+ aNormal = TangentSpaceNormal (aDeltaUVMatrix, aDeltaVectorMatrix, aMapNormalValue, aNormal, true);
899
+ }
900
+ #endif
901
+ }
902
+ #endif
903
+ NormalAdaptation (-theRay.Direct, aHit.Normal, aNormal);
904
+ aHit.Normal = aNormal;
905
+ SLocalSpace aSpace = buildLocalSpace (aNormal);
906
+
907
+ if (uLightCount > 0 && IsNotZero (aBSDF, aThroughput))
908
+ {
909
+ aExpPDF = 1.0 / float(uLightCount);
910
+
911
+ int aLightIdx = min (int (floor (RandFloat() * float(uLightCount))), uLightCount - 1);
912
+
913
+ vec4 aLight = texelFetch (uRaytraceLightSrcTexture, LIGHT_POS (aLightIdx));
914
+ vec4 aParam = texelFetch (uRaytraceLightSrcTexture, LIGHT_PWR (aLightIdx));
915
+
916
+ // 'w' component is 0 for infinite light and 1 for point light
917
+ aLight.xyz -= mix (ZERO, theRay.Origin, aLight.w);
918
+
919
+ float aDistance = length (aLight.xyz);
920
+
921
+ aLight.xyz = SampleLight (aLight.xyz, aDistance,
922
+ aLight.w == 0.f /* is infinite */, aParam.w /* max cos or radius */, aExpPDF);
923
+
924
+ aImpPDF = BsdfPdfLayered (aBSDF,
925
+ toLocalSpace (-theRay.Direct, aSpace), toLocalSpace (aLight.xyz, aSpace), aThroughput);
926
+
927
+ // MIS weight including division by explicit PDF
928
+ float aMIS = (aExpPDF == MAXFLOAT) ? 1.f : aExpPDF / (aExpPDF * aExpPDF + aImpPDF * aImpPDF);
929
+
930
+ vec3 aContrib = aMIS * aParam.rgb /* Le */ * EvalBsdfLayered (
931
+ aBSDF, toLocalSpace (aLight.xyz, aSpace), toLocalSpace (-theRay.Direct, aSpace));
932
+
933
+ if (any (greaterThan (aContrib, MIN_CONTRIBUTION))) // check if light source is important
934
+ {
935
+ SRay aShadow = SRay (theRay.Origin + aLight.xyz * uSceneEpsilon, aLight.xyz);
936
+
937
+ aShadow.Origin += aHit.Normal * mix (
938
+ -uSceneEpsilon, uSceneEpsilon, step (0.f, dot (aHit.Normal, aLight.xyz)));
939
+
940
+ float aVisibility = SceneAnyHit (aShadow,
941
+ InverseDirection (aLight.xyz), aLight.w == 0.f ? MAXFLOAT : aDistance);
942
+
943
+ aRadiance += aVisibility * (aThroughput * aContrib);
944
+ }
945
+ }
946
+
947
+ // account for self-emission
948
+ aRadiance += aThroughput * anLE.rgb;
949
+
950
+ if (aInMedium) // handle attenuation
951
+ {
952
+ vec4 aScattering = texelFetch (uRaytraceMaterialTexture, MATERIAL_ABSORPT_BASE (aTriangle.TriIndex.w));
953
+
954
+ aThroughput *= exp (-aHit.Time * aScattering.w * (UNIT - aScattering.rgb));
955
+ }
956
+
957
+ vec3 anInput = UNIT; // sampled input direction
958
+
959
+ aImpPDF = SampleBsdfLayered (aBSDF,
960
+ toLocalSpace (-theRay.Direct, aSpace), anInput, aThroughput, aInMedium);
961
+
962
+ float aSurvive = float (any (greaterThan (aThroughput, MIN_THROUGHPUT)));
963
+
964
+ #ifdef RUSSIAN_ROULETTE
965
+ aSurvive = aDepth < 3 ? aSurvive : min (dot (LUMA, aThroughput), 0.95f);
966
+ #endif
967
+
968
+ // here, we additionally increase path length for non-diffuse bounces
969
+ if (RandFloat() > aSurvive
970
+ || all (lessThan (aThroughput, MIN_THROUGHPUT))
971
+ || aDepth >= (theNbSamples / FRAME_STEP + int(step (1.0 / M_PI, aImpPDF))))
972
+ {
973
+ aDepth = INVALID_BOUNCES; // terminate path
974
+ }
975
+
976
+ #ifdef RUSSIAN_ROULETTE
977
+ aThroughput /= aSurvive;
978
+ #endif
979
+
980
+ anInput = normalize (fromLocalSpace (anInput, aSpace));
981
+
982
+ theRay = SRay (theRay.Origin + anInput * uSceneEpsilon +
983
+ aHit.Normal * mix (-uSceneEpsilon, uSceneEpsilon, step (0.f, dot (aHit.Normal, anInput))), anInput);
984
+
985
+ theInverse = InverseDirection (anInput);
986
+ }
987
+
988
+ gl_FragDepth = aRaytraceDepth;
989
+
990
+ return vec4 (aRadiance, aRaytraceDepth);
991
+ }
992
+
993
+ #endif