@meimu/mutracer 0.1.4 → 0.1.5

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 (67) hide show
  1. package/dist/assets/bvh.worker.js +1 -1
  2. package/dist/mutracer.umd.js +1425 -1421
  3. package/docs/api.md +2 -1
  4. package/docs/materials.md +17 -26
  5. package/docs/threejs.md +5 -5
  6. package/docs/viewer.md +36 -3
  7. package/lib/oidn.d.ts +1 -1
  8. package/lib/oidnBundledWeights.cdn.d.ts +2 -2
  9. package/lib/renderer/WGPUFullQuadPass.js +3 -3
  10. package/lib/renderer/WGPUJNLMDenoiser.js +35 -35
  11. package/lib/renderer/WGPURayTraceOutput.js +4 -4
  12. package/lib/renderer/WGPURayTracePass.js +5 -3
  13. package/lib/renderer/WGPURayTracePass.js.map +1 -1
  14. package/lib/renderer/WGPURenderingPipeline.js +7 -7
  15. package/lib/renderer/WebGLJNLMDenoiser.js +36 -36
  16. package/lib/renderer/WebGLRayTracePass.js +1 -0
  17. package/lib/renderer/WebGLRayTracePass.js.map +1 -1
  18. package/lib/renderer/glsl/chunks/cameraRay.glsl.js +8 -8
  19. package/lib/renderer/glsl/chunks/envMap.glsl.js +26 -26
  20. package/lib/renderer/glsl/chunks/intersect.glsl.js +141 -139
  21. package/lib/renderer/glsl/chunks/intersect.glsl.js.map +1 -1
  22. package/lib/renderer/glsl/chunks/materialBuffer.glsl.js +56 -55
  23. package/lib/renderer/glsl/chunks/materialBuffer.glsl.js.map +1 -1
  24. package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js +144 -144
  25. package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js.map +1 -1
  26. package/lib/renderer/glsl/chunks/random.glsl.js +1 -1
  27. package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js +14 -14
  28. package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js.map +1 -1
  29. package/lib/renderer/glsl/chunks/sampleLight.glsl.js +19 -19
  30. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js +46 -46
  31. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js.map +1 -1
  32. package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js +6 -6
  33. package/lib/renderer/glsl/chunks/sampling.glsl.js +33 -33
  34. package/lib/renderer/glsl/chunks/sobol.glsl.js +7 -7
  35. package/lib/renderer/glsl/chunks/uvProjection.glsl.js +1 -1
  36. package/lib/renderer/glsl/depthQuery.frag.js +2 -2
  37. package/lib/renderer/glsl/rayTrace.frag.js +67 -67
  38. package/lib/renderer/glsl/shadowCatcher.frag.js +3 -3
  39. package/lib/renderer/glsl/webglPipeline.frag.js +26 -26
  40. package/lib/renderer/scratchSampling.js +16 -16
  41. package/lib/renderer/wgsl/chunks/envMap.wgsl.js +14 -14
  42. package/lib/renderer/wgsl/chunks/intersect.wgsl.js +178 -178
  43. package/lib/renderer/wgsl/chunks/intersect.wgsl.js.map +1 -1
  44. package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js +3 -3
  45. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js +24 -23
  46. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js.map +1 -1
  47. package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js +160 -160
  48. package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js +12 -12
  49. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js +5 -5
  50. package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js +44 -44
  51. package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js +69 -69
  52. package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js +3 -3
  53. package/lib/renderer/wgsl/chunks/sampling.wgsl.js +33 -33
  54. package/lib/renderer/wgsl/chunks/sobol.wgsl.js +7 -7
  55. package/lib/renderer/wgsl/chunks/uvProjection.wgsl.js +1 -1
  56. package/lib/renderer/wgsl/compose.frag.wgsl.js +54 -54
  57. package/lib/renderer/wgsl/customDenoise.wgsl.js +6 -6
  58. package/lib/renderer/wgsl/depthQuery.wgsl.js +2 -2
  59. package/lib/renderer/wgsl/offlineAdaptive.compute.js +5 -5
  60. package/lib/renderer/wgsl/rayTrace.compute.js +103 -103
  61. package/lib/scene/OpenPBRMaterial.d.ts +1 -1
  62. package/lib/scene/OpenPBRMaterial.js +1 -1
  63. package/lib/scene/OpenPBRMaterial.js.map +1 -1
  64. package/lib/version.d.ts +1 -1
  65. package/lib/version.js +1 -1
  66. package/lib/version.js.map +1 -1
  67. package/package.json +1 -1
@@ -2,24 +2,24 @@
2
2
  // http://www.pbr-book.org/3ed-2018/Light_Transport_I_Surface_Reflection/Direct_Lighting.html#EstimatingtheDirectLightingIntegral
3
3
  import { glsl } from '../../shader.js';
4
4
  export default glsl `
5
- vec3 mU(ad si, J mat, ag prepared, inout Path aa, vec3 ffnormal, bool gE) {
6
- float mD = 1.0;
7
- vec3 ln = vec3(fo(cw(LIGHT_POSITION)), dz(cw(LIGHT_SELECT)));
5
+ vec3 mT(ad si, J mat, ag prepared, inout Path aa, vec3 ffnormal, bool gF) {
6
+ float mC = 1.0;
7
+ vec3 ln = vec3(fp(cw(LIGHT_POSITION)), dz(cw(LIGHT_SELECT)));
8
8
 
9
9
  LightSampleRec lightSample;
10
10
  sampleLight(si.position, ln, lightSample, false);
11
11
  lightSample.emission = ai(lightSample.emission, bf);
12
12
 
13
13
  vec3 lightDir = lightSample.direction;
14
- vec3 oT = -aa.ray.d;
14
+ vec3 oS = -aa.ray.d;
15
15
  float fg = lightSample.pdf;
16
16
 
17
17
 
18
18
 
19
19
 
20
20
  float cosThetaL = dot(ffnormal, lightDir);
21
- #ifdef NUM_COAT_NORMAL_MAPS
22
- if (gE && mat.coatNormalEnabled) { cosThetaL = dot(mat.geometricNormal, lightDir); }
21
+ #ifdef USE_COAT_NORMAL_FRAMES
22
+ if (gF && mat.coatNormalEnabled) { cosThetaL = dot(mat.geometricNormal, lightDir); }
23
23
  #endif
24
24
 
25
25
  if (fg <= 0.0 || max(max(lightSample.emission.x, lightSample.emission.y), lightSample.emission.z) <= 0.0) {
@@ -28,7 +28,7 @@ return vec3(0.0);
28
28
 
29
29
  float scatteringPdf = 0.0;
30
30
  vec3 f = vec3(0.0);
31
- if (gE) {
31
+ if (gF) {
32
32
  if (cosThetaL <= 0.0 && mat.transmissionWeight <= 0.0 && mat.subsurfaceWeight <= 0.0) {
33
33
  return vec3(0.0);
34
34
  }
@@ -36,7 +36,7 @@ f = bI(prepared, lightDir, scatteringPdf);
36
36
  }
37
37
  else {
38
38
  scatteringPdf = bD(
39
- dot(oT, lightDir),
39
+ dot(oS, lightDir),
40
40
  si.mediumAnisotropy
41
41
  );
42
42
  f = vec3(scatteringPdf);
@@ -46,36 +46,36 @@ if (scatteringPdf <= 0.0 || max(max(f.x, f.y), f.z) <= 0.0) {
46
46
  return vec3(0.0);
47
47
  }
48
48
 
49
- Ray mA;
49
+ Ray mz;
50
50
  vec3 hi = si.position + EPS * lightDir;
51
- if (gE) {
51
+ if (gF) {
52
52
  const float bZ = 0.1;
53
53
  float dr = dot(si.normal, lightDir);
54
- #ifdef NUM_COAT_NORMAL_MAPS
54
+ #ifdef USE_COAT_NORMAL_FRAMES
55
55
  if (mat.coatNormalEnabled) { dr = dot(si.faceNormal, lightDir); }
56
56
  #endif
57
57
  vec3 geometricNormal = dr < 0.0 ? -si.faceNormal : si.faceNormal;
58
58
  dr = abs(dr);
59
59
  float hS = dot(geometricNormal, lightDir);
60
- float oC = dr < bZ
60
+ float oB = dr < bZ
61
61
  ? clamp(
62
62
  2.0 - (hS + dr) / bZ,
63
63
  0.0,
64
64
  1.0
65
65
  )
66
66
  : clamp(1.0 - hS / bZ, 0.0, 1.0);
67
- hi += si.shadowOffset * oC;
67
+ hi += si.shadowOffset * oB;
68
68
  }
69
- iC(mA, hi, lightDir);
70
- if (ex(mA, lightSample.dist - EPS, si.triangleIndex)) {
69
+ iC(mz, hi, lightDir);
70
+ if (ex(mz, lightSample.dist - EPS, si.triangleIndex)) {
71
71
  return vec3(0.0);
72
72
  }
73
73
 
74
74
  #ifdef USE_ENVMAP
75
75
 
76
76
 
77
- if (gE && cosThetaL < 0.0 && ln.z < envLightSelectionPmf) {
78
- vec4 background = cx(mA.o, lightDir);
77
+ if (gF && cosThetaL < 0.0 && ln.z < envLightSelectionPmf) {
78
+ vec4 background = cx(mz.o, lightDir);
79
79
  lightSample.emission = ai(background.rgb * background.a, bf);
80
80
  }
81
81
  #endif
@@ -90,8 +90,8 @@ return fa > 0.0
90
90
  : vec3(0.0);
91
91
  }
92
92
 
93
- #ifdef NUM_COAT_NORMAL_MAPS
94
- vec3 fE(vec3 pG, vec3 tq, vec3 view) {
93
+ #ifdef USE_COAT_NORMAL_FRAMES
94
+ vec3 fF(vec3 pG, vec3 tq, vec3 view) {
95
95
  bool qY = dot(tq, view) >= 0.0;
96
96
  vec3 uo = qY ? tq : -tq;
97
97
  vec3 qX = qY ? pG : -pG;
@@ -99,11 +99,11 @@ if (dot(pG, tq) <= 0.0 || dot(qX, view) <= 1e-6) { return uo; }
99
99
  return qX;
100
100
  }
101
101
  #endif
102
- void mc(inout ad si, J mat, inout Path aa) {
103
- vec3 ur = vec3(fo(cw(BSDF_DIRECTION)), dz(cw(BSDF_LOBE)));
104
- #ifdef NUM_COAT_NORMAL_MAPS
102
+ void mb(inout ad si, J mat, inout Path aa) {
103
+ vec3 ur = vec3(fp(cw(BSDF_DIRECTION)), dz(cw(BSDF_LOBE)));
104
+ #ifdef USE_COAT_NORMAL_FRAMES
105
105
  vec3 bC = si.faceNormal;
106
- vec3 mF = si.normal;
106
+ vec3 mE = si.normal;
107
107
  #endif
108
108
  float rN = -dot(si.faceNormal, aa.ray.d);
109
109
  float sG = -dot(si.normal, aa.ray.d);
@@ -128,15 +128,15 @@ mat.inside = ndv <= 0.0 && !mat.thinWalled;
128
128
 
129
129
  mat.relativeIor = ndv > 0.0 ? (1.0 / mat.specularIor) : mat.specularIor;
130
130
  vec3 ffnormal = ndv >= 0.0 ? normal : -normal;
131
- #ifdef NUM_COAT_NORMAL_MAPS
131
+ #ifdef USE_COAT_NORMAL_FRAMES
132
132
  if (mat.coatNormalEnabled) {
133
133
  vec3 view = -aa.ray.d;
134
- float ga = dot(bC, view);
135
- mat.geometricNormal = ga >= 0.0 ? bC : -bC;
136
- ffnormal = fE(mF, bC, view);
137
- mat.coatNormal = fE(si.coatNormal, bC, view);
138
- mat.inside = ga <= 0.0 && !mat.thinWalled;
139
- mat.relativeIor = (ga > 0.0 || mat.thinWalled) ? 1.0 / mat.specularIor : mat.specularIor;
134
+ float gb = dot(bC, view);
135
+ mat.geometricNormal = gb >= 0.0 ? bC : -bC;
136
+ ffnormal = fF(mE, bC, view);
137
+ mat.coatNormal = fF(si.coatNormal, bC, view);
138
+ mat.inside = gb <= 0.0 && !mat.thinWalled;
139
+ mat.relativeIor = (gb > 0.0 || mat.thinWalled) ? 1.0 / mat.specularIor : mat.specularIor;
140
140
  }
141
141
  #endif
142
142
 
@@ -151,7 +151,7 @@ ag prepared;
151
151
  #ifdef HAS_MEDIUM
152
152
  int mediumType = si.mediumType;
153
153
  float d = distance(si.position, aa.ray.o);
154
- vec3 nv = aa.ray.o;
154
+ vec3 nu = aa.ray.o;
155
155
  vec3 extinction = si.mediumExtinction;
156
156
  vec3 scattering = min(si.mediumScattering, extinction);
157
157
  float sC = max(max(extinction.x, extinction.y), extinction.z);
@@ -160,32 +160,32 @@ if (mediumType > 0 && sC > 0.0) {
160
160
 
161
161
 
162
162
 
163
- int nk = min(int(dz(cw(MEDIUM_CHANNEL)) * 3.0), 2);
164
- float fD = extinction[nk];
165
- float ih = fD > 0.0
166
- ? min(-log(max(dz(cw(MEDIUM_DISTANCE)), 1e-7)) / fD, d)
163
+ int nj = min(int(dz(cw(MEDIUM_CHANNEL)) * 3.0), 2);
164
+ float fE = extinction[nj];
165
+ float ih = fE > 0.0
166
+ ? min(-log(max(dz(cw(MEDIUM_DISTANCE)), 1e-7)) / fE, d)
167
167
  : d;
168
168
  bl = ih < d;
169
169
  vec3 ew = exp(-extinction * ih);
170
- vec3 oa = bl
170
+ vec3 nZ = bl
171
171
  ? extinction * ew
172
172
  : ew;
173
- float nL = max(
174
- (oa.x + oa.y + oa.z) / 3.0,
173
+ float nK = max(
174
+ (nZ.x + nZ.y + nZ.z) / 3.0,
175
175
  1e-8
176
176
  );
177
177
  if (bl) {
178
- aa.beta *= ew * scattering / nL;
178
+ aa.beta *= ew * scattering / nK;
179
179
 
180
- aa.ray.o = nv + ih * aa.ray.d;
180
+ aa.ray.o = nu + ih * aa.ray.d;
181
181
  si.position = aa.ray.o;
182
- aa.li += mU(si, mat, prepared, aa, ffnormal, false) * aa.beta;
182
+ aa.li += mT(si, mat, prepared, aa, ffnormal, false) * aa.beta;
183
183
 
184
184
 
185
- cG = fp(
185
+ cG = fq(
186
186
  -aa.ray.d,
187
187
  si.mediumAnisotropy,
188
- fo(cw(PHASE_DIRECTION))
188
+ fp(cw(PHASE_DIRECTION))
189
189
  );
190
190
  scatteringPdf = bD(
191
191
  dot(cG, -aa.ray.d),
@@ -193,7 +193,7 @@ si.mediumAnisotropy
193
193
  );
194
194
  }
195
195
  else {
196
- aa.beta *= ew / nL;
196
+ aa.beta *= ew / nK;
197
197
  }
198
198
  }
199
199
  #endif
@@ -214,7 +214,7 @@ mat.directionBitangent = si.directionBitangent;
214
214
  mat.geometryTangent = si.geometryTangent;
215
215
  mat.geometryBitangent = si.geometryBitangent;
216
216
  prepared = eH(pS, mat, -aa.ray.d, ffnormal);
217
- aa.li += mU(si, mat, prepared, aa, ffnormal, true) * aa.beta;
217
+ aa.li += mT(si, mat, prepared, aa, ffnormal, true) * aa.beta;
218
218
 
219
219
  bool isNextRefraction;
220
220
  vec3 f = dv(
@@ -244,7 +244,7 @@ aa.isNextRefraction = isNextRefraction;
244
244
 
245
245
 
246
246
  aa.ray.o = si.position + EPS * cG;
247
- #ifdef NUM_COAT_NORMAL_MAPS
247
+ #ifdef USE_COAT_NORMAL_FRAMES
248
248
  if (mat.coatNormalEnabled) { aa.ray.o = si.position + EPS * (dot(bC, cG) >= 0.0 ? bC : -bC); }
249
249
  #endif
250
250
  }
@@ -1 +1 @@
1
- {"version":3,"file":"sampleMaterial.glsl.js","sourceRoot":"","sources":["../../../../src/renderer/glsl/chunks/sampleMaterial.glsl.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,iIAAiI;AAEjI,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,eAAe,IAAI,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkRlB,CAAC","sourcesContent":["// Estimate the direct lighting integral using multiple importance sampling\n// http://www.pbr-book.org/3ed-2018/Light_Transport_I_Surface_Reflection/Direct_Lighting.html#EstimatingtheDirectLightingIntegral\n\nimport { glsl } from '../../shader.js';\nexport default glsl`\nvec3 DirectLight(SurfaceInteraction si, OpenPbrResolvedMaterial mat, OpenPbrPreparedBsdf prepared, inout Path path, vec3 ffnormal, bool isSurface) {\n float occluded = 1.0;\n vec3 lightRnd = vec3(sample2D(bounceDim(LIGHT_POSITION)), sample1D(bounceDim(LIGHT_SELECT)));\n\n LightSampleRec lightSample;\n sampleLight(si.position, lightRnd, lightSample, false);\n lightSample.emission = sampling_spectral_rgb_filter(lightSample.emission, pathWavelength);\n\n vec3 lightDir = lightSample.direction;\n vec3 viewDir = -path.ray.d;\n float lightPdf = lightSample.pdf;\n // Opaque surfaces are rendered two-sided by the core renderer. Use the\n // face-forward shading normal here as well, otherwise the early-out rejects\n // every direct-light sample seen from the back of a triangle (for example\n // the inside of an imported room wall).\n float cosThetaL = dot(ffnormal, lightDir);\n#ifdef NUM_COAT_NORMAL_MAPS\n if (isSurface && mat.coatNormalEnabled) { cosThetaL = dot(mat.geometricNormal, lightDir); }\n#endif\n\n if (lightPdf <= 0.0 || max(max(lightSample.emission.x, lightSample.emission.y), lightSample.emission.z) <= 0.0) {\n return vec3(0.0);\n }\n\n float scatteringPdf = 0.0;\n vec3 f = vec3(0.0);\n if (isSurface) {\n if (cosThetaL <= 0.0 && mat.transmissionWeight <= 0.0 && mat.subsurfaceWeight <= 0.0) {\n return vec3(0.0);\n }\n f = openpbr_eval_prepared(prepared, lightDir, scatteringPdf);\n }\n else {\n scatteringPdf = sampling_henyey_greenstein_phase(\n dot(viewDir, lightDir),\n si.mediumAnisotropy\n );\n f = vec3(scatteringPdf);\n }\n\n if (scatteringPdf <= 0.0 || max(max(f.x, f.y), f.z) <= 0.0) {\n return vec3(0.0);\n }\n\n Ray lightRay;\n vec3 shadowOrigin = si.position + EPS * lightDir;\n if (isSurface) {\n const float shadowTerminatorCutoff = 0.1;\n float normalLight = dot(si.normal, lightDir);\n#ifdef NUM_COAT_NORMAL_MAPS\n if (mat.coatNormalEnabled) { normalLight = dot(si.faceNormal, lightDir); }\n#endif\n vec3 geometricNormal = normalLight < 0.0 ? -si.faceNormal : si.faceNormal;\n normalLight = abs(normalLight);\n float geometricLight = dot(geometricNormal, lightDir);\n float offsetAmount = normalLight < shadowTerminatorCutoff\n ? clamp(\n 2.0 - (geometricLight + normalLight) / shadowTerminatorCutoff,\n 0.0,\n 1.0\n )\n : clamp(1.0 - geometricLight / shadowTerminatorCutoff, 0.0, 1.0);\n shadowOrigin += si.shadowOffset * offsetAmount;\n }\n initRay(lightRay, shadowOrigin, lightDir);\n if (intersectSceneShadow(lightRay, lightSample.dist - EPS, si.triangleIndex)) {\n return vec3(0.0);\n }\n\n#ifdef USE_ENVMAP\n // Match the endpoint used by a BSDF-sampled surface transmission, including\n // a separately displayed or grounded background and its coverage.\n if (isSurface && cosThetaL < 0.0 && lightRnd.z < envLightSelectionPmf) {\n vec4 background = sampleBackgroundFromRay(lightRay.o, lightDir);\n lightSample.emission = sampling_spectral_rgb_filter(background.rgb * background.a, pathWavelength);\n }\n#endif\n\n // Delta lights cannot be sampled by the BSDF strategy, so their MIS weight\n // is exactly one even when their light-selection PMF is small.\n float misWeight = lightSample.isDelta\n ? 1.0\n : sampling_power_heuristic(lightPdf, scatteringPdf);\n return misWeight > 0.0\n ? misWeight * lightSample.emission * f / lightPdf\n : vec3(0.0);\n}\n\n#ifdef NUM_COAT_NORMAL_MAPS\nvec3 coat_frame_normal(vec3 inputNormal, vec3 face, vec3 view) {\n bool front = dot(face, view) >= 0.0;\n vec3 ffFace = front ? face : -face;\n vec3 ffInput = front ? inputNormal : -inputNormal;\n if (dot(inputNormal, face) <= 0.0 || dot(ffInput, view) <= 1e-6) { return ffFace; }\n return ffInput;\n}\n#endif\nvoid SampleMaterial(inout SurfaceInteraction si, OpenPbrResolvedMaterial mat, inout Path path) {\n vec3 matRnd = vec3(sample2D(bounceDim(BSDF_DIRECTION)), sample1D(bounceDim(BSDF_LOBE)));\n#ifdef NUM_COAT_NORMAL_MAPS\n vec3 originalFace = si.faceNormal;\n vec3 originalNormal = si.normal;\n#endif\n float ndv1 = -dot(si.faceNormal, path.ray.d);\n float ndv2 = -dot(si.normal, path.ray.d);\n if ((mat.transmissionWeight > 0.0 || mat.subsurfaceWeight > 0.0) && mat.thinWalled) {\n // Always treat thin material as entering medium\n if (ndv1 < 0.0) {\n si.faceNormal = -si.faceNormal;\n ndv1 = -ndv1;\n }\n if (ndv2 < 0.0) {\n si.normal = -si.normal;\n ndv2 = -ndv2;\n }\n }\n // In same edge cases normal is not torwards the camera while we can still see the face.\n // We need to choose faceNormal in this case.\n bool useFaceN = ndv1 >= 0.0 && ndv2 < 0.0;\n float ndv = useFaceN ? ndv1 : ndv2;\n vec3 normal = useFaceN ? si.faceNormal : si.normal;\n\n mat.inside = ndv <= 0.0 && !mat.thinWalled;\n // In or out\n mat.relativeIor = ndv > 0.0 ? (1.0 / mat.specularIor) : mat.specularIor;\n vec3 ffnormal = ndv >= 0.0 ? normal : -normal;\n#ifdef NUM_COAT_NORMAL_MAPS\n if (mat.coatNormalEnabled) {\n vec3 view = -path.ray.d;\n float geometricView = dot(originalFace, view);\n mat.geometricNormal = geometricView >= 0.0 ? originalFace : -originalFace;\n ffnormal = coat_frame_normal(originalNormal, originalFace, view);\n mat.coatNormal = coat_frame_normal(si.coatNormal, originalFace, view);\n mat.inside = geometricView <= 0.0 && !mat.thinWalled;\n mat.relativeIor = (geometricView > 0.0 || mat.thinWalled) ? 1.0 / mat.specularIor : mat.specularIor;\n }\n#endif\n\n\n float scatteringPdf;\n vec3 scatterDir;\n path.scatteringIsDelta = false;\n bool mediumSampled = false;\n bool crossedBoundary = false;\n OpenPbrPreparedBsdf prepared;\n\n#ifdef HAS_MEDIUM\n int mediumType = si.mediumType;\n float d = distance(si.position, path.ray.o);\n vec3 segmentOrigin = path.ray.o;\n vec3 extinction = si.mediumExtinction;\n vec3 scattering = min(si.mediumScattering, extinction);\n float majorant = max(max(extinction.x, extinction.y), extinction.z);\n if (mediumType > 0 && majorant > 0.0) {\n // Sample one RGB extinction channel and divide by the mixture PDF. This\n // is the homogeneous-medium estimator used by PBRT and avoids the very\n // large exp((majorant - extinction) * distance) weights produced by\n // majorant tracking when OpenPBR SSS radii differ strongly by channel.\n int mediumChannel = min(int(sample1D(bounceDim(MEDIUM_CHANNEL)) * 3.0), 2);\n float channelExtinction = extinction[mediumChannel];\n float scatterDist = channelExtinction > 0.0\n ? min(-log(max(sample1D(bounceDim(MEDIUM_DISTANCE)), 1e-7)) / channelExtinction, d)\n : d;\n mediumSampled = scatterDist < d;\n vec3 transmittance = exp(-extinction * scatterDist);\n vec3 density = mediumSampled\n ? extinction * transmittance\n : transmittance;\n float mediumPdf = max(\n (density.x + density.y + density.z) / 3.0,\n 1e-8\n );\n if (mediumSampled) {\n path.beta *= transmittance * scattering / mediumPdf;\n // Move from the start of the segment, not from its end surface.\n path.ray.o = segmentOrigin + scatterDist * path.ray.d;\n si.position = path.ray.o;\n path.li += DirectLight(si, mat, prepared, path, ffnormal, false) * path.beta;\n\n // Pick a new direction based on the phase function\n scatterDir = sampling_henyey_greenstein(\n -path.ray.d,\n si.mediumAnisotropy,\n sample2D(bounceDim(PHASE_DIRECTION))\n );\n scatteringPdf = sampling_henyey_greenstein_phase(\n dot(scatterDir, -path.ray.d),\n si.mediumAnisotropy\n );\n }\n else {\n path.beta *= transmittance / mediumPdf;\n }\n }\n#endif\n\n // Direct lighting\n if (!mediumSampled) {\n path.li += mat.emission * path.beta;\n if (mat.materialType == UNLIT) {\n path.abort = true;\n return;\n }\n vec3 surfaceTangent = vec3(0.0);\n#ifdef USE_TANGENT\n surfaceTangent = si.tangent;\n#endif\n mat.directionTangent = si.directionTangent;\n mat.directionBitangent = si.directionBitangent;\n mat.geometryTangent = si.geometryTangent;\n mat.geometryBitangent = si.geometryBitangent;\n prepared = openpbr_prepare(surfaceTangent, mat, -path.ray.d, ffnormal);\n path.li += DirectLight(si, mat, prepared, path, ffnormal, true) * path.beta;\n // Sample BSDF for color and outgoing direction\n bool isNextRefraction;\n vec3 f = openpbr_sample_prepared(\n prepared,\n matRnd,\n scatterDir,\n scatteringPdf,\n isNextRefraction\n );\n // Null-boundary transmission is discrete and has no NEE competitor.\n path.scatteringIsDelta = !prepared.material.thinWalled &&\n abs(prepared.material.relativeIor - 1.0) <= 1e-6 &&\n prepared.probabilities[OPENPBR_LOBE_TRANSMISSION] >= 1.0 - 1e-6;\n // Match WebGPU: rejected VNDF/refraction proposals have no continuation.\n // Tracing their fallback direction with the incoming throughput invents\n // light paths, especially after total internal reflection inside glass.\n if (!(scatteringPdf > 0.0) || any(isnan(f)) || any(isinf(f)) ||\n dot(scatterDir, scatterDir) < 0.5) {\n path.scatteringPdf = 0.0;\n path.abort = true;\n return;\n }\n path.beta *= f / scatteringPdf;\n crossedBoundary = !mat.thinWalled &&\n isNextRefraction;\n path.isNextRefraction = isNextRefraction;\n // TODO prefer the opaque surface when transmission surface and opaque surface are overlapped.\n // Or the ray go out from transmission material will miss the opque surface.\n path.ray.o = si.position + EPS * scatterDir;\n#ifdef NUM_COAT_NORMAL_MAPS\n if (mat.coatNormalEnabled) { path.ray.o = si.position + EPS * (dot(originalFace, scatterDir) >= 0.0 ? originalFace : -originalFace); }\n#endif\n }\n\n path.scatteringPdf = scatteringPdf;\n initRay(path.ray, path.ray.o, scatterDir);\n if (mediumSampled) {\n path.isNextRefraction = false;\n }\n path.fromEye = false;\n\n#ifdef HAS_MEDIUM\n // A reflected ray stays in its current medium. Only a sampled transmission\n // event crosses the boundary of a medium-bearing closed mesh.\n if (!mediumSampled && crossedBoundary && mat.mediumType > 0) {\n if (ndv1 >= 0.0) {\n si.mediumType = mat.mediumType;\n si.mediumExtinction = mat.mediumExtinction;\n si.mediumScattering = mat.mediumScattering;\n si.mediumAnisotropy = mat.mediumAnisotropy;\n }\n else {\n si.mediumType = 0;\n si.mediumExtinction = vec3(0.0);\n si.mediumScattering = vec3(0.0);\n si.mediumAnisotropy = 0.0;\n }\n }\n#endif\n}\n`;\n"]}
1
+ {"version":3,"file":"sampleMaterial.glsl.js","sourceRoot":"","sources":["../../../../src/renderer/glsl/chunks/sampleMaterial.glsl.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,iIAAiI;AAEjI,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvC,eAAe,IAAI,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkRlB,CAAC","sourcesContent":["// Estimate the direct lighting integral using multiple importance sampling\n// http://www.pbr-book.org/3ed-2018/Light_Transport_I_Surface_Reflection/Direct_Lighting.html#EstimatingtheDirectLightingIntegral\n\nimport { glsl } from '../../shader.js';\nexport default glsl`\nvec3 DirectLight(SurfaceInteraction si, OpenPbrResolvedMaterial mat, OpenPbrPreparedBsdf prepared, inout Path path, vec3 ffnormal, bool isSurface) {\n float occluded = 1.0;\n vec3 lightRnd = vec3(sample2D(bounceDim(LIGHT_POSITION)), sample1D(bounceDim(LIGHT_SELECT)));\n\n LightSampleRec lightSample;\n sampleLight(si.position, lightRnd, lightSample, false);\n lightSample.emission = sampling_spectral_rgb_filter(lightSample.emission, pathWavelength);\n\n vec3 lightDir = lightSample.direction;\n vec3 viewDir = -path.ray.d;\n float lightPdf = lightSample.pdf;\n // Opaque surfaces are rendered two-sided by the core renderer. Use the\n // face-forward shading normal here as well, otherwise the early-out rejects\n // every direct-light sample seen from the back of a triangle (for example\n // the inside of an imported room wall).\n float cosThetaL = dot(ffnormal, lightDir);\n#ifdef USE_COAT_NORMAL_FRAMES\n if (isSurface && mat.coatNormalEnabled) { cosThetaL = dot(mat.geometricNormal, lightDir); }\n#endif\n\n if (lightPdf <= 0.0 || max(max(lightSample.emission.x, lightSample.emission.y), lightSample.emission.z) <= 0.0) {\n return vec3(0.0);\n }\n\n float scatteringPdf = 0.0;\n vec3 f = vec3(0.0);\n if (isSurface) {\n if (cosThetaL <= 0.0 && mat.transmissionWeight <= 0.0 && mat.subsurfaceWeight <= 0.0) {\n return vec3(0.0);\n }\n f = openpbr_eval_prepared(prepared, lightDir, scatteringPdf);\n }\n else {\n scatteringPdf = sampling_henyey_greenstein_phase(\n dot(viewDir, lightDir),\n si.mediumAnisotropy\n );\n f = vec3(scatteringPdf);\n }\n\n if (scatteringPdf <= 0.0 || max(max(f.x, f.y), f.z) <= 0.0) {\n return vec3(0.0);\n }\n\n Ray lightRay;\n vec3 shadowOrigin = si.position + EPS * lightDir;\n if (isSurface) {\n const float shadowTerminatorCutoff = 0.1;\n float normalLight = dot(si.normal, lightDir);\n#ifdef USE_COAT_NORMAL_FRAMES\n if (mat.coatNormalEnabled) { normalLight = dot(si.faceNormal, lightDir); }\n#endif\n vec3 geometricNormal = normalLight < 0.0 ? -si.faceNormal : si.faceNormal;\n normalLight = abs(normalLight);\n float geometricLight = dot(geometricNormal, lightDir);\n float offsetAmount = normalLight < shadowTerminatorCutoff\n ? clamp(\n 2.0 - (geometricLight + normalLight) / shadowTerminatorCutoff,\n 0.0,\n 1.0\n )\n : clamp(1.0 - geometricLight / shadowTerminatorCutoff, 0.0, 1.0);\n shadowOrigin += si.shadowOffset * offsetAmount;\n }\n initRay(lightRay, shadowOrigin, lightDir);\n if (intersectSceneShadow(lightRay, lightSample.dist - EPS, si.triangleIndex)) {\n return vec3(0.0);\n }\n\n#ifdef USE_ENVMAP\n // Match the endpoint used by a BSDF-sampled surface transmission, including\n // a separately displayed or grounded background and its coverage.\n if (isSurface && cosThetaL < 0.0 && lightRnd.z < envLightSelectionPmf) {\n vec4 background = sampleBackgroundFromRay(lightRay.o, lightDir);\n lightSample.emission = sampling_spectral_rgb_filter(background.rgb * background.a, pathWavelength);\n }\n#endif\n\n // Delta lights cannot be sampled by the BSDF strategy, so their MIS weight\n // is exactly one even when their light-selection PMF is small.\n float misWeight = lightSample.isDelta\n ? 1.0\n : sampling_power_heuristic(lightPdf, scatteringPdf);\n return misWeight > 0.0\n ? misWeight * lightSample.emission * f / lightPdf\n : vec3(0.0);\n}\n\n#ifdef USE_COAT_NORMAL_FRAMES\nvec3 coat_frame_normal(vec3 inputNormal, vec3 face, vec3 view) {\n bool front = dot(face, view) >= 0.0;\n vec3 ffFace = front ? face : -face;\n vec3 ffInput = front ? inputNormal : -inputNormal;\n if (dot(inputNormal, face) <= 0.0 || dot(ffInput, view) <= 1e-6) { return ffFace; }\n return ffInput;\n}\n#endif\nvoid SampleMaterial(inout SurfaceInteraction si, OpenPbrResolvedMaterial mat, inout Path path) {\n vec3 matRnd = vec3(sample2D(bounceDim(BSDF_DIRECTION)), sample1D(bounceDim(BSDF_LOBE)));\n#ifdef USE_COAT_NORMAL_FRAMES\n vec3 originalFace = si.faceNormal;\n vec3 originalNormal = si.normal;\n#endif\n float ndv1 = -dot(si.faceNormal, path.ray.d);\n float ndv2 = -dot(si.normal, path.ray.d);\n if ((mat.transmissionWeight > 0.0 || mat.subsurfaceWeight > 0.0) && mat.thinWalled) {\n // Always treat thin material as entering medium\n if (ndv1 < 0.0) {\n si.faceNormal = -si.faceNormal;\n ndv1 = -ndv1;\n }\n if (ndv2 < 0.0) {\n si.normal = -si.normal;\n ndv2 = -ndv2;\n }\n }\n // In same edge cases normal is not torwards the camera while we can still see the face.\n // We need to choose faceNormal in this case.\n bool useFaceN = ndv1 >= 0.0 && ndv2 < 0.0;\n float ndv = useFaceN ? ndv1 : ndv2;\n vec3 normal = useFaceN ? si.faceNormal : si.normal;\n\n mat.inside = ndv <= 0.0 && !mat.thinWalled;\n // In or out\n mat.relativeIor = ndv > 0.0 ? (1.0 / mat.specularIor) : mat.specularIor;\n vec3 ffnormal = ndv >= 0.0 ? normal : -normal;\n#ifdef USE_COAT_NORMAL_FRAMES\n if (mat.coatNormalEnabled) {\n vec3 view = -path.ray.d;\n float geometricView = dot(originalFace, view);\n mat.geometricNormal = geometricView >= 0.0 ? originalFace : -originalFace;\n ffnormal = coat_frame_normal(originalNormal, originalFace, view);\n mat.coatNormal = coat_frame_normal(si.coatNormal, originalFace, view);\n mat.inside = geometricView <= 0.0 && !mat.thinWalled;\n mat.relativeIor = (geometricView > 0.0 || mat.thinWalled) ? 1.0 / mat.specularIor : mat.specularIor;\n }\n#endif\n\n\n float scatteringPdf;\n vec3 scatterDir;\n path.scatteringIsDelta = false;\n bool mediumSampled = false;\n bool crossedBoundary = false;\n OpenPbrPreparedBsdf prepared;\n\n#ifdef HAS_MEDIUM\n int mediumType = si.mediumType;\n float d = distance(si.position, path.ray.o);\n vec3 segmentOrigin = path.ray.o;\n vec3 extinction = si.mediumExtinction;\n vec3 scattering = min(si.mediumScattering, extinction);\n float majorant = max(max(extinction.x, extinction.y), extinction.z);\n if (mediumType > 0 && majorant > 0.0) {\n // Sample one RGB extinction channel and divide by the mixture PDF. This\n // is the homogeneous-medium estimator used by PBRT and avoids the very\n // large exp((majorant - extinction) * distance) weights produced by\n // majorant tracking when OpenPBR SSS radii differ strongly by channel.\n int mediumChannel = min(int(sample1D(bounceDim(MEDIUM_CHANNEL)) * 3.0), 2);\n float channelExtinction = extinction[mediumChannel];\n float scatterDist = channelExtinction > 0.0\n ? min(-log(max(sample1D(bounceDim(MEDIUM_DISTANCE)), 1e-7)) / channelExtinction, d)\n : d;\n mediumSampled = scatterDist < d;\n vec3 transmittance = exp(-extinction * scatterDist);\n vec3 density = mediumSampled\n ? extinction * transmittance\n : transmittance;\n float mediumPdf = max(\n (density.x + density.y + density.z) / 3.0,\n 1e-8\n );\n if (mediumSampled) {\n path.beta *= transmittance * scattering / mediumPdf;\n // Move from the start of the segment, not from its end surface.\n path.ray.o = segmentOrigin + scatterDist * path.ray.d;\n si.position = path.ray.o;\n path.li += DirectLight(si, mat, prepared, path, ffnormal, false) * path.beta;\n\n // Pick a new direction based on the phase function\n scatterDir = sampling_henyey_greenstein(\n -path.ray.d,\n si.mediumAnisotropy,\n sample2D(bounceDim(PHASE_DIRECTION))\n );\n scatteringPdf = sampling_henyey_greenstein_phase(\n dot(scatterDir, -path.ray.d),\n si.mediumAnisotropy\n );\n }\n else {\n path.beta *= transmittance / mediumPdf;\n }\n }\n#endif\n\n // Direct lighting\n if (!mediumSampled) {\n path.li += mat.emission * path.beta;\n if (mat.materialType == UNLIT) {\n path.abort = true;\n return;\n }\n vec3 surfaceTangent = vec3(0.0);\n#ifdef USE_TANGENT\n surfaceTangent = si.tangent;\n#endif\n mat.directionTangent = si.directionTangent;\n mat.directionBitangent = si.directionBitangent;\n mat.geometryTangent = si.geometryTangent;\n mat.geometryBitangent = si.geometryBitangent;\n prepared = openpbr_prepare(surfaceTangent, mat, -path.ray.d, ffnormal);\n path.li += DirectLight(si, mat, prepared, path, ffnormal, true) * path.beta;\n // Sample BSDF for color and outgoing direction\n bool isNextRefraction;\n vec3 f = openpbr_sample_prepared(\n prepared,\n matRnd,\n scatterDir,\n scatteringPdf,\n isNextRefraction\n );\n // Null-boundary transmission is discrete and has no NEE competitor.\n path.scatteringIsDelta = !prepared.material.thinWalled &&\n abs(prepared.material.relativeIor - 1.0) <= 1e-6 &&\n prepared.probabilities[OPENPBR_LOBE_TRANSMISSION] >= 1.0 - 1e-6;\n // Match WebGPU: rejected VNDF/refraction proposals have no continuation.\n // Tracing their fallback direction with the incoming throughput invents\n // light paths, especially after total internal reflection inside glass.\n if (!(scatteringPdf > 0.0) || any(isnan(f)) || any(isinf(f)) ||\n dot(scatterDir, scatterDir) < 0.5) {\n path.scatteringPdf = 0.0;\n path.abort = true;\n return;\n }\n path.beta *= f / scatteringPdf;\n crossedBoundary = !mat.thinWalled &&\n isNextRefraction;\n path.isNextRefraction = isNextRefraction;\n // TODO prefer the opaque surface when transmission surface and opaque surface are overlapped.\n // Or the ray go out from transmission material will miss the opque surface.\n path.ray.o = si.position + EPS * scatterDir;\n#ifdef USE_COAT_NORMAL_FRAMES\n if (mat.coatNormalEnabled) { path.ray.o = si.position + EPS * (dot(originalFace, scatterDir) >= 0.0 ? originalFace : -originalFace); }\n#endif\n }\n\n path.scatteringPdf = scatteringPdf;\n initRay(path.ray, path.ray.o, scatterDir);\n if (mediumSampled) {\n path.isNextRefraction = false;\n }\n path.fromEye = false;\n\n#ifdef HAS_MEDIUM\n // A reflected ray stays in its current medium. Only a sampled transmission\n // event crosses the boundary of a medium-bearing closed mesh.\n if (!mediumSampled && crossedBoundary && mat.mediumType > 0) {\n if (ndv1 >= 0.0) {\n si.mediumType = mat.mediumType;\n si.mediumExtinction = mat.mediumExtinction;\n si.mediumScattering = mat.mediumScattering;\n si.mediumAnisotropy = mat.mediumAnisotropy;\n }\n else {\n si.mediumType = 0;\n si.mediumExtinction = vec3(0.0);\n si.mediumScattering = vec3(0.0);\n si.mediumAnisotropy = 0.0;\n }\n }\n#endif\n}\n`;\n"]}
@@ -16,28 +16,28 @@ return candidate == 0u ? cw(slot) : cw(9u + (candidate - 1u) * 3u + slot);
16
16
  }
17
17
 
18
18
  void sampleShadowCatcher(ad si, int bounce, inout Path aa) {
19
- vec3 oT = -aa.ray.d;
19
+ vec3 oS = -aa.ray.d;
20
20
 
21
21
  #if defined(NUM_LIGHTS) || defined(USE_ENVMAP)
22
22
  float visibility = 0.0;
23
23
  for (uint candidate = 0u; candidate < SHADOW_CATCHER_LIGHT_SAMPLES; candidate++) {
24
24
  LightSampleRec lightSample;
25
25
  vec3 ln = vec3(
26
- fo(ky(candidate, LIGHT_POSITION)),
26
+ fp(ky(candidate, LIGHT_POSITION)),
27
27
  dz(ky(candidate, LIGHT_SELECT))
28
28
  );
29
29
  sampleLight(si.position, ln, lightSample, false);
30
30
 
31
31
  vec3 lightDir = lightSample.direction;
32
32
  float cosThetaL = dot(si.normal, lightDir);
33
- float pM = dot(si.normal, oT) * cosThetaL;
34
- bool mD = false;
33
+ float pM = dot(si.normal, oS) * cosThetaL;
34
+ bool mC = false;
35
35
  if (pM >= 0.0) {
36
36
  Ray ray;
37
37
  iC(ray, si.position + EPS * lightDir, lightDir);
38
- mD = ex(ray, lightSample.dist - EPS, si.triangleIndex);
38
+ mC = ex(ray, lightSample.dist - EPS, si.triangleIndex);
39
39
  }
40
- visibility += mD ? 0.0 : 1.0;
40
+ visibility += mC ? 0.0 : 1.0;
41
41
  }
42
42
 
43
43
  aa.alpha = visibility / float(SHADOW_CATCHER_LIGHT_SAMPLES);
@@ -6,27 +6,27 @@ export default glsl `
6
6
 
7
7
  vec3 aQ(vec3 view, vec2 alpha, vec2 samplePoint) {
8
8
  vec3 rm = vec3(alpha, 1.0);
9
- vec3 gj = normalize(rm * view);
10
- float uh = min(gj.z, 1.0);
9
+ vec3 gk = normalize(rm * view);
10
+ float uh = min(gk.z, 1.0);
11
11
  float qQ = 1.0 + uh;
12
12
  float rh = (1.0 - samplePoint.y) * qQ;
13
13
  float rR = samplePoint.y * qQ;
14
14
  float sI = rh + (1.0 - uh);
15
15
  float fl = sqrt(max(0.0, sI * rR));
16
16
  float br = TWOPI * samplePoint.x;
17
- vec3 lJ = vec3(
18
- gj.x + fl * cos(br),
19
- gj.y + fl * sin(br),
17
+ vec3 lI = vec3(
18
+ gk.x + fl * cos(br),
19
+ gk.y + fl * sin(br),
20
20
  rh
21
21
  );
22
- return normalize(rm * lJ);
22
+ return normalize(rm * lI);
23
23
  }
24
24
 
25
- float gK(vec3 oq, vec2 alpha) {
25
+ float gL(vec3 oo, vec2 alpha) {
26
26
  vec3 hr = vec3(
27
- oq.x / alpha.x,
28
- oq.y / alpha.y,
29
- oq.z
27
+ oo.x / alpha.x,
28
+ oo.y / alpha.y,
29
+ oo.z
30
30
  );
31
31
  float ap = dot(hr, hr);
32
32
  return 1.0 / (
@@ -40,9 +40,9 @@ if (eF <= 1e-8) {
40
40
  return 0.0;
41
41
  }
42
42
  vec2 ic = alpha * direction.xy;
43
- float lK = dot(ic, ic)
43
+ float lJ = dot(ic, ic)
44
44
  / (eF * eF);
45
- return 2.0 / (1.0 + sqrt(1.0 + lK));
45
+ return 2.0 / (1.0 + sqrt(1.0 + lJ));
46
46
  }
47
47
 
48
48
  float aE(float au) {
@@ -58,17 +58,17 @@ if (kl >= 1.0) {
58
58
  return 1.0;
59
59
  }
60
60
 
61
- float lU = sqrt(max(0.0, 1.0 - kl));
62
- float ba = (iA - cJ * lU)
63
- / max(iA + cJ * lU, 1e-8);
64
- float pN = (cJ * iA - lU)
65
- / max(cJ * iA + lU, 1e-8);
61
+ float lT = sqrt(max(0.0, 1.0 - kl));
62
+ float ba = (iA - cJ * lT)
63
+ / max(iA + cJ * lT, 1e-8);
64
+ float pN = (cJ * iA - lT)
65
+ / max(cJ * iA + lT, 1e-8);
66
66
  return 0.5 * (
67
67
  ba * ba + pN * pN
68
68
  );
69
69
  }
70
70
 
71
- vec2 gh(vec2 samplePoint) {
71
+ vec2 gi(vec2 samplePoint) {
72
72
  vec2 offset = 2.0 * samplePoint - vec2(1.0);
73
73
  if (offset.x == 0.0 && offset.y == 0.0) {
74
74
  return vec2(0.0);
@@ -88,21 +88,21 @@ return radius * vec2(cos(angle), sin(angle));
88
88
  }
89
89
 
90
90
  vec3 bi(vec2 samplePoint) {
91
- vec2 kF = gh(samplePoint);
91
+ vec2 kF = gi(samplePoint);
92
92
  return vec3(
93
93
  kF,
94
94
  sqrt(max(0.0, 1.0 - dot(kF, kF)))
95
95
  );
96
96
  }
97
97
 
98
- float aG(float pr, float nO) {
99
- float scale = max(pr, nO);
98
+ float aG(float pr, float nN) {
99
+ float scale = max(pr, nN);
100
100
  if (scale <= 0.0) {
101
101
  return 0.0;
102
102
  }
103
- vec2 normalized = vec2(pr, nO) / scale;
104
- vec2 oP = normalized * normalized;
105
- return oP.x / (oP.x + oP.y);
103
+ vec2 normalized = vec2(pr, nN) / scale;
104
+ vec2 oO = normalized * normalized;
105
+ return oO.x / (oO.x + oO.y);
106
106
  }
107
107
 
108
108
  void aL(in vec3 normal, out vec3 tangent, out vec3 bitangent) {
@@ -135,12 +135,12 @@ return rgb * tN;
135
135
 
136
136
  float eN(
137
137
  float wavelength,
138
- float hg,
138
+ float hh,
139
139
  float hp,
140
140
  float qs
141
141
  ) {
142
142
  if (wavelength == 0.0 || hp <= 0.0) {
143
- return hg;
143
+ return hh;
144
144
  }
145
145
 
146
146
  const float FRAUNHOFER_C = 656.3;
@@ -150,15 +150,15 @@ float jR = 1.0 / (
150
150
  1.0 / (FRAUNHOFER_F * FRAUNHOFER_F)
151
151
  - 1.0 / (FRAUNHOFER_C * FRAUNHOFER_C)
152
152
  );
153
- float nh = max(qs / hp, 1e-6);
154
- float qR = (hg - 1.0) * jR / nh;
155
- float tl = hg
153
+ float ng = max(qs / hp, 1e-6);
154
+ float qR = (hh - 1.0) * jR / ng;
155
+ float tl = hh
156
156
  - qR / (FRAUNHOFER_D * FRAUNHOFER_D);
157
157
  return tl + qR / (wavelength * wavelength);
158
158
  }
159
159
 
160
- vec3 fp(
161
- vec3 gy,
160
+ vec3 fq(
161
+ vec3 gz,
162
162
  float anisotropy,
163
163
  vec2 samplePoint
164
164
  ) {
@@ -178,10 +178,10 @@ float ud = sqrt(max(0.0, 1.0 - au * au));
178
178
  float br = TWOPI * samplePoint.x;
179
179
  vec3 tangent;
180
180
  vec3 bitangent;
181
- aL(gy, tangent, bitangent);
181
+ aL(gz, tangent, bitangent);
182
182
  return tangent * (ud * cos(br))
183
183
  + bitangent * (ud * sin(br))
184
- + gy * au;
184
+ + gz * au;
185
185
  }
186
186
 
187
187
  float bD(float au, float anisotropy) {
@@ -99,18 +99,18 @@ return CAMERA_BEVEL_BASE + uint(BEVEL_SAMPLES) + cF * BOUNCE_STRIDE + slot;
99
99
 
100
100
  uvec4 hl;
101
101
  uint hm;
102
- bool fB = false;
102
+ bool fC = false;
103
103
  bool dg = false;
104
104
  uint dF;
105
- uint gu;
105
+ uint gv;
106
106
  vec2 eQ;
107
107
  void dw(uint dim) {
108
108
 
109
109
  uint kd = bc.x + bc.y * uint(round(1.0 / pixelSize.x));
110
110
  uvec4 key = uvec4(dim, bd, kd, uint(sequenceSeed));
111
- if (fB && all(equal(hl, key)) && hm == uint(zSobolLogSPP)) { return; }
111
+ if (fC && all(equal(hl, key)) && hm == uint(zSobolLogSPP)) { return; }
112
112
  hl = key; hm = uint(zSobolLogSPP);
113
- fB = true; dg = false;
113
+ fC = true; dg = false;
114
114
  uint ij = aq(aq(kd, dim), uint(sequenceSeed));
115
115
  uint index = bd;
116
116
  if (samplingPattern == 1) {
@@ -129,14 +129,14 @@ if (bd != 0u) { jb += 1u; }
129
129
  ij = aq(ij, jb);
130
130
  }
131
131
  dF = sK(index, aq(ij, 0u));
132
- gu = ij;
132
+ gv = ij;
133
133
  uint x = reverseBits(iE(dF, aq(ij, 1u)));
134
134
  eQ.x = float(x >> 8u) * (1.0 / 16777216.0);
135
135
  }
136
136
  vec2 kS(uint dim) {
137
137
  dw(dim);
138
138
  if (!dg) {
139
- uint y = sK(rl(dF), aq(gu, 2u));
139
+ uint y = sK(rl(dF), aq(gv, 2u));
140
140
  eQ.y = float(y >> 8u) * (1.0 / 16777216.0);
141
141
  dg = true;
142
142
  }
@@ -147,7 +147,7 @@ if (samplingPattern == 2) { return EPS + (1.0 - 2.0*EPS)*rand(); }
147
147
  dw(dim);
148
148
  return EPS + (1.0 - 2.0*EPS) * eQ.x;
149
149
  }
150
- vec2 fo(uint dim) {
150
+ vec2 fp(uint dim) {
151
151
  if (samplingPattern == 2) {
152
152
  float x = dz(dim); float y = dz(dim);
153
153
  return vec2(x,y);
@@ -58,7 +58,7 @@ float theta = atan(pos.z, pos.x) / (2.0 * PI) + 0.5;
58
58
  return vec2(theta, pos.y);
59
59
  }
60
60
 
61
- vec2 gH(int fk, vec3 pos, vec3 normal, vec2 uvScale) {
61
+ vec2 gI(int fk, vec3 pos, vec3 normal, vec2 uvScale) {
62
62
  if (fk == ${uvProjectionConstants.triplanar + ''}) {
63
63
  return iR(pos, normal, uvScale);
64
64
  } else if (fk == ${uvProjectionConstants.spherical + ''}) {
@@ -35,7 +35,7 @@ vec4 target = viewProjectionInv * vec4(uv * 2.0 - 1.0, 1.0, 1.0);
35
35
  Ray ray;
36
36
  iC(ray, origin.xyz / origin.w, normalize(target.xyz * origin.w - origin.xyz * target.w));
37
37
  vec3 eye = viewInv[3].xyz;
38
- vec3 ol = -normalize(viewInv[2].xyz);
38
+ vec3 oj = -normalize(viewInv[2].xyz);
39
39
  ad si;
40
40
  si.triangleIndex = -1;
41
41
  for (int layer = 0; layer < 32; layer++) {
@@ -44,7 +44,7 @@ if (!si.hit) return;
44
44
  J material;
45
45
  eX(material, si.materialIndex, si.uv, si.uv1, si.instanceIndex, si.vertexColor);
46
46
  if (material.materialType != SHADOW_CATCHER && material.alpha > 0.0) {
47
- out_depth.r = max(dot(si.position - eye, ol), 0.0);
47
+ out_depth.r = max(dot(si.position - eye, oj), 0.0);
48
48
  return;
49
49
  }
50
50
  ray.o = si.position + ray.d * (EPS * 0.02);