three-gpu-pathtracer 0.0.14 → 0.0.16

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 (76) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +1004 -981
  3. package/build/index.module.js +7413 -6902
  4. package/build/index.module.js.map +1 -1
  5. package/build/index.umd.cjs +7446 -6933
  6. package/build/index.umd.cjs.map +1 -1
  7. package/package.json +73 -73
  8. package/src/core/DynamicPathTracingSceneGenerator.js +119 -119
  9. package/src/core/MaterialReducer.js +256 -256
  10. package/src/core/PathTracingRenderer.js +346 -346
  11. package/src/core/PathTracingSceneGenerator.js +69 -69
  12. package/src/core/QuiltPathTracingRenderer.js +223 -223
  13. package/src/detectors/CompatibilityDetector.js +38 -0
  14. package/src/detectors/MaterialCompileDetector.js +50 -0
  15. package/src/detectors/PrecisionDetector.js +85 -0
  16. package/src/detectors/PrecisionMaterial.js +160 -0
  17. package/src/index.js +40 -36
  18. package/src/materials/MaterialBase.js +56 -56
  19. package/src/materials/debug/GraphMaterial.js +243 -243
  20. package/src/materials/fullscreen/AlphaDisplayMaterial.js +50 -48
  21. package/src/materials/fullscreen/BlendMaterial.js +67 -67
  22. package/src/materials/fullscreen/DenoiseMaterial.js +142 -142
  23. package/src/materials/fullscreen/GradientMapMaterial.js +82 -0
  24. package/src/materials/pathtracing/LambertPathTracingMaterial.js +296 -296
  25. package/src/materials/pathtracing/PhysicalPathTracingMaterial.js +118 -196
  26. package/src/materials/pathtracing/glsl/attenuateHit.glsl.js +177 -179
  27. package/src/materials/pathtracing/glsl/cameraUtils.glsl.js +84 -81
  28. package/src/materials/pathtracing/glsl/directLightContribution.glsl.js +93 -0
  29. package/src/materials/pathtracing/glsl/getSurfaceRecord.glsl.js +323 -317
  30. package/src/materials/pathtracing/glsl/renderStructs.glsl.js +50 -0
  31. package/src/materials/pathtracing/glsl/traceScene.glsl.js +52 -54
  32. package/src/materials/surface/AmbientOcclusionMaterial.js +207 -207
  33. package/src/materials/surface/FogVolumeMaterial.js +23 -23
  34. package/src/objects/EquirectCamera.js +13 -13
  35. package/src/objects/PhysicalCamera.js +42 -28
  36. package/src/objects/PhysicalSpotLight.js +25 -14
  37. package/src/objects/ShapedAreaLight.js +22 -12
  38. package/src/shader/bsdf/bsdfSampling.glsl.js +499 -490
  39. package/src/shader/bsdf/fog.glsl.js +22 -23
  40. package/src/shader/bsdf/ggx.glsl.js +102 -102
  41. package/src/shader/bsdf/iridescence.glsl.js +135 -135
  42. package/src/shader/bsdf/sheen.glsl.js +98 -98
  43. package/src/shader/common/arraySamplerTexelFetch.glsl.js +25 -25
  44. package/src/shader/common/bvhAnyHit.glsl.js +76 -76
  45. package/src/shader/common/fresnel.glsl.js +98 -98
  46. package/src/shader/common/intersectShapes.glsl.js +62 -62
  47. package/src/shader/common/math.glsl.js +81 -81
  48. package/src/shader/common/utils.glsl.js +116 -116
  49. package/src/shader/rand/pcg.glsl.js +57 -57
  50. package/src/shader/rand/sobol.glsl.js +256 -256
  51. package/src/shader/sampling/equirectSampling.glsl.js +62 -62
  52. package/src/shader/sampling/lightSampling.glsl.js +223 -223
  53. package/src/shader/sampling/shapeSampling.glsl.js +86 -86
  54. package/src/shader/structs/cameraStruct.glsl.js +13 -13
  55. package/src/shader/structs/equirectStruct.glsl.js +13 -14
  56. package/src/shader/structs/fogMaterialBvh.glsl.js +62 -62
  57. package/src/shader/structs/lightsStruct.glsl.js +78 -78
  58. package/src/shader/structs/materialStruct.glsl.js +207 -207
  59. package/src/textures/GradientEquirectTexture.js +35 -35
  60. package/src/textures/ProceduralEquirectTexture.js +75 -75
  61. package/src/uniforms/AttributesTextureArray.js +35 -35
  62. package/src/uniforms/EquirectHdrInfoUniform.js +269 -277
  63. package/src/uniforms/FloatAttributeTextureArray.js +169 -169
  64. package/src/uniforms/IESProfilesTexture.js +100 -100
  65. package/src/uniforms/LightsInfoUniformStruct.js +212 -212
  66. package/src/uniforms/MaterialsTexture.js +503 -503
  67. package/src/uniforms/PhysicalCameraUniform.js +36 -36
  68. package/src/uniforms/RenderTarget2DArray.js +97 -97
  69. package/src/uniforms/utils.js +30 -30
  70. package/src/utils/BlurredEnvMapGenerator.js +116 -116
  71. package/src/utils/GeometryPreparationUtils.js +214 -214
  72. package/src/utils/IESLoader.js +325 -325
  73. package/src/utils/SobolNumberMapGenerator.js +80 -80
  74. package/src/utils/UVUnwrapper.js +101 -101
  75. package/src/utils/macroify.js +9 -9
  76. package/src/workers/PathTracingSceneWorker.js +42 -42
@@ -1,98 +1,98 @@
1
- export const sheenGLSL = /* glsl */`
2
-
3
- // See equation (2) in http://www.aconty.com/pdf/s2017_pbs_imageworks_sheen.pdf
4
- float velvetD( float cosThetaH, float roughness ) {
5
-
6
- float alpha = max( roughness, 0.07 );
7
- alpha = alpha * alpha;
8
-
9
- float invAlpha = 1.0 / alpha;
10
-
11
- float sqrCosThetaH = cosThetaH * cosThetaH;
12
- float sinThetaH = max( 1.0 - sqrCosThetaH, 0.001 );
13
-
14
- return ( 2.0 + invAlpha ) * pow( sinThetaH, 0.5 * invAlpha ) / ( 2.0 * PI );
15
-
16
- }
17
-
18
- float velvetParamsInterpolate( int i, float oneMinusAlphaSquared ) {
19
-
20
- const float p0[5] = float[5]( 25.3245, 3.32435, 0.16801, -1.27393, -4.85967 );
21
- const float p1[5] = float[5]( 21.5473, 3.82987, 0.19823, -1.97760, -4.32054 );
22
-
23
- return mix( p1[i], p0[i], oneMinusAlphaSquared );
24
-
25
- }
26
-
27
- float velvetL( float x, float alpha ) {
28
-
29
- float oneMinusAlpha = 1.0 - alpha;
30
- float oneMinusAlphaSquared = oneMinusAlpha * oneMinusAlpha;
31
-
32
- float a = velvetParamsInterpolate( 0, oneMinusAlphaSquared );
33
- float b = velvetParamsInterpolate( 1, oneMinusAlphaSquared );
34
- float c = velvetParamsInterpolate( 2, oneMinusAlphaSquared );
35
- float d = velvetParamsInterpolate( 3, oneMinusAlphaSquared );
36
- float e = velvetParamsInterpolate( 4, oneMinusAlphaSquared );
37
-
38
- return a / ( 1.0 + b * pow( abs( x ), c ) ) + d * x + e;
39
-
40
- }
41
-
42
- // See equation (3) in http://www.aconty.com/pdf/s2017_pbs_imageworks_sheen.pdf
43
- float velvetLambda( float cosTheta, float alpha ) {
44
-
45
- return abs( cosTheta ) < 0.5 ? exp( velvetL( cosTheta, alpha ) ) : exp( 2.0 * velvetL( 0.5, alpha ) - velvetL( 1.0 - cosTheta, alpha ) );
46
-
47
- }
48
-
49
- // See Section 3, Shadowing Term, in http://www.aconty.com/pdf/s2017_pbs_imageworks_sheen.pdf
50
- float velvetG( float cosThetaO, float cosThetaI, float roughness ) {
51
-
52
- float alpha = max( roughness, 0.07 );
53
- alpha = alpha * alpha;
54
-
55
- return 1.0 / ( 1.0 + velvetLambda( cosThetaO, alpha ) + velvetLambda( cosThetaI, alpha ) );
56
-
57
- }
58
-
59
- float directionalAlbedoSheen( float cosTheta, float alpha ) {
60
-
61
- cosTheta = saturate( cosTheta );
62
-
63
- float c = 1.0 - cosTheta;
64
- float c3 = c * c * c;
65
-
66
- return 0.65584461 * c3 + 1.0 / ( 4.16526551 + exp( -7.97291361 * sqrt( alpha ) + 6.33516894 ) );
67
-
68
- }
69
-
70
- float sheenAlbedoScaling( vec3 wo, vec3 wi, SurfaceRecord surf ) {
71
-
72
- float alpha = max( surf.sheenRoughness, 0.07 );
73
- alpha = alpha * alpha;
74
-
75
- float maxSheenColor = max( max( surf.sheenColor.r, surf.sheenColor.g ), surf.sheenColor.b );
76
-
77
- float eWo = directionalAlbedoSheen( saturateCos( wo.z ), alpha );
78
- float eWi = directionalAlbedoSheen( saturateCos( wi.z ), alpha );
79
-
80
- return min( 1.0 - maxSheenColor * eWo, 1.0 - maxSheenColor * eWi );
81
-
82
- }
83
-
84
- // See Section 5, Layering, in http://www.aconty.com/pdf/s2017_pbs_imageworks_sheen.pdf
85
- float sheenAlbedoScaling( vec3 wo, SurfaceRecord surf ) {
86
-
87
- float alpha = max( surf.sheenRoughness, 0.07 );
88
- alpha = alpha * alpha;
89
-
90
- float maxSheenColor = max( max( surf.sheenColor.r, surf.sheenColor.g ), surf.sheenColor.b );
91
-
92
- float eWo = directionalAlbedoSheen( saturateCos( wo.z ), alpha );
93
-
94
- return 1.0 - maxSheenColor * eWo;
95
-
96
- }
97
-
98
- `;
1
+ export const sheenGLSL = /* glsl */`
2
+
3
+ // See equation (2) in http://www.aconty.com/pdf/s2017_pbs_imageworks_sheen.pdf
4
+ float velvetD( float cosThetaH, float roughness ) {
5
+
6
+ float alpha = max( roughness, 0.07 );
7
+ alpha = alpha * alpha;
8
+
9
+ float invAlpha = 1.0 / alpha;
10
+
11
+ float sqrCosThetaH = cosThetaH * cosThetaH;
12
+ float sinThetaH = max( 1.0 - sqrCosThetaH, 0.001 );
13
+
14
+ return ( 2.0 + invAlpha ) * pow( sinThetaH, 0.5 * invAlpha ) / ( 2.0 * PI );
15
+
16
+ }
17
+
18
+ float velvetParamsInterpolate( int i, float oneMinusAlphaSquared ) {
19
+
20
+ const float p0[5] = float[5]( 25.3245, 3.32435, 0.16801, -1.27393, -4.85967 );
21
+ const float p1[5] = float[5]( 21.5473, 3.82987, 0.19823, -1.97760, -4.32054 );
22
+
23
+ return mix( p1[i], p0[i], oneMinusAlphaSquared );
24
+
25
+ }
26
+
27
+ float velvetL( float x, float alpha ) {
28
+
29
+ float oneMinusAlpha = 1.0 - alpha;
30
+ float oneMinusAlphaSquared = oneMinusAlpha * oneMinusAlpha;
31
+
32
+ float a = velvetParamsInterpolate( 0, oneMinusAlphaSquared );
33
+ float b = velvetParamsInterpolate( 1, oneMinusAlphaSquared );
34
+ float c = velvetParamsInterpolate( 2, oneMinusAlphaSquared );
35
+ float d = velvetParamsInterpolate( 3, oneMinusAlphaSquared );
36
+ float e = velvetParamsInterpolate( 4, oneMinusAlphaSquared );
37
+
38
+ return a / ( 1.0 + b * pow( abs( x ), c ) ) + d * x + e;
39
+
40
+ }
41
+
42
+ // See equation (3) in http://www.aconty.com/pdf/s2017_pbs_imageworks_sheen.pdf
43
+ float velvetLambda( float cosTheta, float alpha ) {
44
+
45
+ return abs( cosTheta ) < 0.5 ? exp( velvetL( cosTheta, alpha ) ) : exp( 2.0 * velvetL( 0.5, alpha ) - velvetL( 1.0 - cosTheta, alpha ) );
46
+
47
+ }
48
+
49
+ // See Section 3, Shadowing Term, in http://www.aconty.com/pdf/s2017_pbs_imageworks_sheen.pdf
50
+ float velvetG( float cosThetaO, float cosThetaI, float roughness ) {
51
+
52
+ float alpha = max( roughness, 0.07 );
53
+ alpha = alpha * alpha;
54
+
55
+ return 1.0 / ( 1.0 + velvetLambda( cosThetaO, alpha ) + velvetLambda( cosThetaI, alpha ) );
56
+
57
+ }
58
+
59
+ float directionalAlbedoSheen( float cosTheta, float alpha ) {
60
+
61
+ cosTheta = saturate( cosTheta );
62
+
63
+ float c = 1.0 - cosTheta;
64
+ float c3 = c * c * c;
65
+
66
+ return 0.65584461 * c3 + 1.0 / ( 4.16526551 + exp( -7.97291361 * sqrt( alpha ) + 6.33516894 ) );
67
+
68
+ }
69
+
70
+ float sheenAlbedoScaling( vec3 wo, vec3 wi, SurfaceRecord surf ) {
71
+
72
+ float alpha = max( surf.sheenRoughness, 0.07 );
73
+ alpha = alpha * alpha;
74
+
75
+ float maxSheenColor = max( max( surf.sheenColor.r, surf.sheenColor.g ), surf.sheenColor.b );
76
+
77
+ float eWo = directionalAlbedoSheen( saturateCos( wo.z ), alpha );
78
+ float eWi = directionalAlbedoSheen( saturateCos( wi.z ), alpha );
79
+
80
+ return min( 1.0 - maxSheenColor * eWo, 1.0 - maxSheenColor * eWi );
81
+
82
+ }
83
+
84
+ // See Section 5, Layering, in http://www.aconty.com/pdf/s2017_pbs_imageworks_sheen.pdf
85
+ float sheenAlbedoScaling( vec3 wo, SurfaceRecord surf ) {
86
+
87
+ float alpha = max( surf.sheenRoughness, 0.07 );
88
+ alpha = alpha * alpha;
89
+
90
+ float maxSheenColor = max( max( surf.sheenColor.r, surf.sheenColor.g ), surf.sheenColor.b );
91
+
92
+ float eWo = directionalAlbedoSheen( saturateCos( wo.z ), alpha );
93
+
94
+ return 1.0 - maxSheenColor * eWo;
95
+
96
+ }
97
+
98
+ `;
@@ -1,25 +1,25 @@
1
-
2
- export const arraySamplerTexelFetchGLSL = /*glsl */`
3
-
4
- // add texel fetch functions for texture arrays
5
- vec4 texelFetch1D( sampler2DArray tex, int layer, uint index ) {
6
-
7
- uint width = uint( textureSize( tex, 0 ).x );
8
- uvec2 uv;
9
- uv.x = index % width;
10
- uv.y = index / width;
11
-
12
- return texelFetch( tex, ivec3( uv, layer ), 0 );
13
-
14
- }
15
-
16
- vec4 textureSampleBarycoord( sampler2DArray tex, int layer, vec3 barycoord, uvec3 faceIndices ) {
17
-
18
- return
19
- barycoord.x * texelFetch1D( tex, layer, faceIndices.x ) +
20
- barycoord.y * texelFetch1D( tex, layer, faceIndices.y ) +
21
- barycoord.z * texelFetch1D( tex, layer, faceIndices.z );
22
-
23
- }
24
-
25
- `;
1
+
2
+ export const arraySamplerTexelFetchGLSL = /*glsl */`
3
+
4
+ // add texel fetch functions for texture arrays
5
+ vec4 texelFetch1D( sampler2DArray tex, int layer, uint index ) {
6
+
7
+ uint width = uint( textureSize( tex, 0 ).x );
8
+ uvec2 uv;
9
+ uv.x = index % width;
10
+ uv.y = index / width;
11
+
12
+ return texelFetch( tex, ivec3( uv, layer ), 0 );
13
+
14
+ }
15
+
16
+ vec4 textureSampleBarycoord( sampler2DArray tex, int layer, vec3 barycoord, uvec3 faceIndices ) {
17
+
18
+ return
19
+ barycoord.x * texelFetch1D( tex, layer, faceIndices.x ) +
20
+ barycoord.y * texelFetch1D( tex, layer, faceIndices.y ) +
21
+ barycoord.z * texelFetch1D( tex, layer, faceIndices.z );
22
+
23
+ }
24
+
25
+ `;
@@ -1,76 +1,76 @@
1
- export const bvhAnyHitGLSL = /* glsl */`
2
-
3
- bool bvhIntersectAnyHit(
4
- BVH bvh, vec3 rayOrigin, vec3 rayDirection,
5
-
6
- // output variables
7
- out float side, out float dist
8
- ) {
9
-
10
- uvec4 faceIndices;
11
- vec3 faceNormal;
12
- vec3 barycoord;
13
-
14
- // stack needs to be twice as long as the deepest tree we expect because
15
- // we push both the left and right child onto the stack every traversal
16
- int ptr = 0;
17
- uint stack[ 60 ];
18
- stack[ 0 ] = 0u;
19
-
20
- float triangleDistance = 1e20;
21
- while ( ptr > - 1 && ptr < 60 ) {
22
-
23
- uint currNodeIndex = stack[ ptr ];
24
- ptr --;
25
-
26
- // check if we intersect the current bounds
27
- float boundsHitDistance = intersectsBVHNodeBounds( rayOrigin, rayDirection, bvh, currNodeIndex );
28
- if ( boundsHitDistance == INFINITY ) {
29
-
30
- continue;
31
-
32
- }
33
-
34
- uvec2 boundsInfo = uTexelFetch1D( bvh.bvhContents, currNodeIndex ).xy;
35
- bool isLeaf = bool( boundsInfo.x & 0xffff0000u );
36
-
37
- if ( isLeaf ) {
38
-
39
- uint count = boundsInfo.x & 0x0000ffffu;
40
- uint offset = boundsInfo.y;
41
-
42
- bool found = intersectTriangles(
43
- bvh, rayOrigin, rayDirection, offset, count, triangleDistance,
44
- faceIndices, faceNormal, barycoord, side, dist
45
- );
46
-
47
- if ( found ) {
48
-
49
- return true;
50
-
51
- }
52
-
53
- } else {
54
-
55
- uint leftIndex = currNodeIndex + 1u;
56
- uint splitAxis = boundsInfo.x & 0x0000ffffu;
57
- uint rightIndex = boundsInfo.y;
58
-
59
- // set c2 in the stack so we traverse it later. We need to keep track of a pointer in
60
- // the stack while we traverse. The second pointer added is the one that will be
61
- // traversed first
62
- ptr ++;
63
- stack[ ptr ] = leftIndex;
64
-
65
- ptr ++;
66
- stack[ ptr ] = rightIndex;
67
-
68
- }
69
-
70
- }
71
-
72
- return false;
73
-
74
- }
75
-
76
- `;
1
+ export const bvhAnyHitGLSL = /* glsl */`
2
+
3
+ bool bvhIntersectAnyHit(
4
+ BVH bvh, vec3 rayOrigin, vec3 rayDirection,
5
+
6
+ // output variables
7
+ out float side, out float dist
8
+ ) {
9
+
10
+ uvec4 faceIndices;
11
+ vec3 faceNormal;
12
+ vec3 barycoord;
13
+
14
+ // stack needs to be twice as long as the deepest tree we expect because
15
+ // we push both the left and right child onto the stack every traversal
16
+ int ptr = 0;
17
+ uint stack[ 60 ];
18
+ stack[ 0 ] = 0u;
19
+
20
+ float triangleDistance = 1e20;
21
+ while ( ptr > - 1 && ptr < 60 ) {
22
+
23
+ uint currNodeIndex = stack[ ptr ];
24
+ ptr --;
25
+
26
+ // check if we intersect the current bounds
27
+ float boundsHitDistance = intersectsBVHNodeBounds( rayOrigin, rayDirection, bvh, currNodeIndex );
28
+ if ( boundsHitDistance == INFINITY ) {
29
+
30
+ continue;
31
+
32
+ }
33
+
34
+ uvec2 boundsInfo = uTexelFetch1D( bvh.bvhContents, currNodeIndex ).xy;
35
+ bool isLeaf = bool( boundsInfo.x & 0xffff0000u );
36
+
37
+ if ( isLeaf ) {
38
+
39
+ uint count = boundsInfo.x & 0x0000ffffu;
40
+ uint offset = boundsInfo.y;
41
+
42
+ bool found = intersectTriangles(
43
+ bvh, rayOrigin, rayDirection, offset, count, triangleDistance,
44
+ faceIndices, faceNormal, barycoord, side, dist
45
+ );
46
+
47
+ if ( found ) {
48
+
49
+ return true;
50
+
51
+ }
52
+
53
+ } else {
54
+
55
+ uint leftIndex = currNodeIndex + 1u;
56
+ uint splitAxis = boundsInfo.x & 0x0000ffffu;
57
+ uint rightIndex = boundsInfo.y;
58
+
59
+ // set c2 in the stack so we traverse it later. We need to keep track of a pointer in
60
+ // the stack while we traverse. The second pointer added is the one that will be
61
+ // traversed first
62
+ ptr ++;
63
+ stack[ ptr ] = leftIndex;
64
+
65
+ ptr ++;
66
+ stack[ ptr ] = rightIndex;
67
+
68
+ }
69
+
70
+ }
71
+
72
+ return false;
73
+
74
+ }
75
+
76
+ `;
@@ -1,98 +1,98 @@
1
- export const fresnelGLSL = /* glsl */`
2
-
3
- bool totalInternalReflection( float cosTheta, float eta ) {
4
-
5
- float sinTheta = sqrt( 1.0 - cosTheta * cosTheta );
6
- return eta * sinTheta > 1.0;
7
-
8
- }
9
-
10
- // https://google.github.io/filament/Filament.md.html#materialsystem/diffusebrdf
11
- float schlickFresnel( float cosine, float f0 ) {
12
-
13
- return f0 + ( 1.0 - f0 ) * pow( 1.0 - cosine, 5.0 );
14
-
15
- }
16
-
17
- vec3 schlickFresnel( float cosine, vec3 f0 ) {
18
-
19
- return f0 + ( 1.0 - f0 ) * pow( 1.0 - cosine, 5.0 );
20
-
21
- }
22
-
23
- vec3 schlickFresnel( float cosine, vec3 f0, vec3 f90 ) {
24
-
25
- return f0 + ( f90 - f0 ) * pow( 1.0 - cosine, 5.0 );
26
-
27
- }
28
-
29
- float dielectricFresnel( float cosThetaI, float eta ) {
30
-
31
- // https://schuttejoe.github.io/post/disneybsdf/
32
- float ni = eta;
33
- float nt = 1.0;
34
-
35
- // Check for total internal reflection
36
- float sinThetaISq = 1.0f - cosThetaI * cosThetaI;
37
- float sinThetaTSq = eta * eta * sinThetaISq;
38
- if( sinThetaTSq >= 1.0 ) {
39
-
40
- return 1.0;
41
-
42
- }
43
-
44
- float sinThetaT = sqrt( sinThetaTSq );
45
-
46
- float cosThetaT = sqrt( max( 0.0, 1.0f - sinThetaT * sinThetaT ) );
47
- float rParallel = ( ( nt * cosThetaI ) - ( ni * cosThetaT ) ) / ( ( nt * cosThetaI ) + ( ni * cosThetaT ) );
48
- float rPerpendicular = ( ( ni * cosThetaI ) - ( nt * cosThetaT ) ) / ( ( ni * cosThetaI ) + ( nt * cosThetaT ) );
49
- return ( rParallel * rParallel + rPerpendicular * rPerpendicular ) / 2.0;
50
-
51
- }
52
-
53
- // https://raytracing.github.io/books/RayTracingInOneWeekend.html#dielectrics/schlickapproximation
54
- float iorRatioToF0( float eta ) {
55
-
56
- return pow( ( 1.0 - eta ) / ( 1.0 + eta ), 2.0 );
57
-
58
- }
59
-
60
- vec3 evaluateFresnel( float cosTheta, float eta, vec3 f0, vec3 f90 ) {
61
-
62
- if ( totalInternalReflection( cosTheta, eta ) ) {
63
-
64
- return f90;
65
-
66
- }
67
-
68
- return schlickFresnel( cosTheta, f0, f90 );
69
-
70
- }
71
-
72
- float evaluateFresnelWeight( float cosTheta, float eta, float f0 ) {
73
-
74
- if ( totalInternalReflection( cosTheta, eta ) ) {
75
-
76
- return 1.0;
77
-
78
- }
79
-
80
- return schlickFresnel( cosTheta, f0 );
81
-
82
- }
83
-
84
- /*
85
- // https://schuttejoe.github.io/post/disneybsdf/
86
- float disneyFresnel( vec3 wo, vec3 wi, vec3 wh, float f0, float eta, float metalness ) {
87
-
88
- float dotHV = dot( wo, wh );
89
- float dotHL = dot( wi, wh );
90
-
91
- float dielectricFresnel = dielectricFresnel( abs( dotHV ), eta );
92
- float metallicFresnel = schlickFresnel( dotHL, f0 );
93
-
94
- return mix( dielectricFresnel, metallicFresnel, metalness );
95
-
96
- }
97
- */
98
- `;
1
+ export const fresnelGLSL = /* glsl */`
2
+
3
+ bool totalInternalReflection( float cosTheta, float eta ) {
4
+
5
+ float sinTheta = sqrt( 1.0 - cosTheta * cosTheta );
6
+ return eta * sinTheta > 1.0;
7
+
8
+ }
9
+
10
+ // https://google.github.io/filament/Filament.md.html#materialsystem/diffusebrdf
11
+ float schlickFresnel( float cosine, float f0 ) {
12
+
13
+ return f0 + ( 1.0 - f0 ) * pow( 1.0 - cosine, 5.0 );
14
+
15
+ }
16
+
17
+ vec3 schlickFresnel( float cosine, vec3 f0 ) {
18
+
19
+ return f0 + ( 1.0 - f0 ) * pow( 1.0 - cosine, 5.0 );
20
+
21
+ }
22
+
23
+ vec3 schlickFresnel( float cosine, vec3 f0, vec3 f90 ) {
24
+
25
+ return f0 + ( f90 - f0 ) * pow( 1.0 - cosine, 5.0 );
26
+
27
+ }
28
+
29
+ float dielectricFresnel( float cosThetaI, float eta ) {
30
+
31
+ // https://schuttejoe.github.io/post/disneybsdf/
32
+ float ni = eta;
33
+ float nt = 1.0;
34
+
35
+ // Check for total internal reflection
36
+ float sinThetaISq = 1.0f - cosThetaI * cosThetaI;
37
+ float sinThetaTSq = eta * eta * sinThetaISq;
38
+ if( sinThetaTSq >= 1.0 ) {
39
+
40
+ return 1.0;
41
+
42
+ }
43
+
44
+ float sinThetaT = sqrt( sinThetaTSq );
45
+
46
+ float cosThetaT = sqrt( max( 0.0, 1.0f - sinThetaT * sinThetaT ) );
47
+ float rParallel = ( ( nt * cosThetaI ) - ( ni * cosThetaT ) ) / ( ( nt * cosThetaI ) + ( ni * cosThetaT ) );
48
+ float rPerpendicular = ( ( ni * cosThetaI ) - ( nt * cosThetaT ) ) / ( ( ni * cosThetaI ) + ( nt * cosThetaT ) );
49
+ return ( rParallel * rParallel + rPerpendicular * rPerpendicular ) / 2.0;
50
+
51
+ }
52
+
53
+ // https://raytracing.github.io/books/RayTracingInOneWeekend.html#dielectrics/schlickapproximation
54
+ float iorRatioToF0( float eta ) {
55
+
56
+ return pow( ( 1.0 - eta ) / ( 1.0 + eta ), 2.0 );
57
+
58
+ }
59
+
60
+ vec3 evaluateFresnel( float cosTheta, float eta, vec3 f0, vec3 f90 ) {
61
+
62
+ if ( totalInternalReflection( cosTheta, eta ) ) {
63
+
64
+ return f90;
65
+
66
+ }
67
+
68
+ return schlickFresnel( cosTheta, f0, f90 );
69
+
70
+ }
71
+
72
+ float evaluateFresnelWeight( float cosTheta, float eta, float f0 ) {
73
+
74
+ if ( totalInternalReflection( cosTheta, eta ) ) {
75
+
76
+ return 1.0;
77
+
78
+ }
79
+
80
+ return schlickFresnel( cosTheta, f0 );
81
+
82
+ }
83
+
84
+ /*
85
+ // https://schuttejoe.github.io/post/disneybsdf/
86
+ float disneyFresnel( vec3 wo, vec3 wi, vec3 wh, float f0, float eta, float metalness ) {
87
+
88
+ float dotHV = dot( wo, wh );
89
+ float dotHL = dot( wi, wh );
90
+
91
+ float dielectricFresnel = dielectricFresnel( abs( dotHV ), eta );
92
+ float metallicFresnel = schlickFresnel( dotHL, f0 );
93
+
94
+ return mix( dielectricFresnel, metallicFresnel, metalness );
95
+
96
+ }
97
+ */
98
+ `;