@meimu/mutracer 0.1.3 → 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.
- package/dist/assets/bvh.worker.js +1 -1
- package/dist/mutracer.umd.js +4155 -4052
- package/docs/api.md +13 -10
- package/docs/materials.md +17 -26
- package/docs/threejs.md +35 -9
- package/docs/viewer.md +36 -3
- package/lib/Engine.js +18 -1
- package/lib/Engine.js.map +1 -1
- package/lib/main.d.ts +1 -1
- package/lib/main.js.map +1 -1
- package/lib/oidn.d.ts +1 -1
- package/lib/oidnBundledWeights.cdn.d.ts +2 -2
- package/lib/renderer/MaterialTable.d.ts +1 -0
- package/lib/renderer/MaterialTable.js +10 -4
- package/lib/renderer/MaterialTable.js.map +1 -1
- package/lib/renderer/WGPUBloomPass.js +18 -18
- package/lib/renderer/WGPUFullQuadPass.js +6 -6
- package/lib/renderer/WGPUJNLMDenoiser.js +69 -69
- package/lib/renderer/WGPURayTraceOutput.js +14 -14
- package/lib/renderer/WGPURayTracePass.d.ts +2 -0
- package/lib/renderer/WGPURayTracePass.js +17 -9
- package/lib/renderer/WGPURayTracePass.js.map +1 -1
- package/lib/renderer/WGPURenderingPipeline.js +15 -15
- package/lib/renderer/WebGLJNLMDenoiser.js +69 -69
- package/lib/renderer/WebGLRayTraceOutputPass.js +4 -4
- package/lib/renderer/WebGLRayTracePass.d.ts +1 -0
- package/lib/renderer/WebGLRayTracePass.js +8 -1
- package/lib/renderer/WebGLRayTracePass.js.map +1 -1
- package/lib/renderer/envMapCreation.d.ts +5 -1
- package/lib/renderer/envMapCreation.js +42 -5
- package/lib/renderer/envMapCreation.js.map +1 -1
- package/lib/renderer/geometryUpdates.js +1 -1
- package/lib/renderer/geometryUpdates.js.map +1 -1
- package/lib/renderer/glsl/chunks/cameraRay.glsl.js +12 -12
- package/lib/renderer/glsl/chunks/envMap.glsl.js +66 -54
- package/lib/renderer/glsl/chunks/envMap.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/intersect.glsl.js +323 -315
- package/lib/renderer/glsl/chunks/intersect.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.js +154 -121
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js +434 -434
- package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/rand.glsl.js +3 -3
- package/lib/renderer/glsl/chunks/random.glsl.js +3 -3
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js +42 -41
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleLight.glsl.js +69 -69
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js +84 -84
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js +12 -12
- package/lib/renderer/glsl/chunks/sampling.glsl.js +75 -75
- package/lib/renderer/glsl/chunks/sobol.glsl.js +61 -61
- package/lib/renderer/glsl/chunks/textureLinear.glsl.js +5 -5
- package/lib/renderer/glsl/chunks/uvProjection.glsl.js +11 -11
- package/lib/renderer/glsl/depthQuery.frag.js +5 -5
- package/lib/renderer/glsl/depthQuery.frag.js.map +1 -1
- package/lib/renderer/glsl/normalizeRayTraceOutput.frag.js +8 -8
- package/lib/renderer/glsl/rayTrace.frag.js +133 -133
- package/lib/renderer/glsl/rayTrace.frag.js.map +1 -1
- package/lib/renderer/glsl/shadowCatcher.frag.js +9 -9
- package/lib/renderer/glsl/shadowCatcher.frag.js.map +1 -1
- package/lib/renderer/glsl/webglPipeline.frag.js +52 -52
- package/lib/renderer/lightsUtil.js +6 -4
- package/lib/renderer/lightsUtil.js.map +1 -1
- package/lib/renderer/materialChanges.js +1 -1
- package/lib/renderer/materialChanges.js.map +1 -1
- package/lib/renderer/materialComparison.generated.js +36 -18
- package/lib/renderer/materialComparison.generated.js.map +1 -1
- package/lib/renderer/prepareMeshBVH.js +2 -2
- package/lib/renderer/prepareMeshBVH.js.map +1 -1
- package/lib/renderer/sceneChangeDetector.js +4 -1
- package/lib/renderer/sceneChangeDetector.js.map +1 -1
- package/lib/renderer/sceneLightChanges.js +3 -2
- package/lib/renderer/sceneLightChanges.js.map +1 -1
- package/lib/renderer/scratchSampling.js +18 -18
- package/lib/renderer/wgsl/chunks/common.wgsl.js +4 -4
- package/lib/renderer/wgsl/chunks/envMap.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/envMap.wgsl.js +39 -31
- package/lib/renderer/wgsl/chunks/envMap.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/intersect.wgsl.js +476 -470
- package/lib/renderer/wgsl/chunks/intersect.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js +8 -8
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js +95 -60
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js +469 -469
- package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js +117 -120
- package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/rand.wgsl.js +3 -3
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js +25 -22
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js +127 -127
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js +136 -136
- package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js +6 -6
- package/lib/renderer/wgsl/chunks/sampling.wgsl.js +73 -73
- package/lib/renderer/wgsl/chunks/sobol.wgsl.js +62 -62
- package/lib/renderer/wgsl/chunks/uvProjection.wgsl.js +11 -11
- package/lib/renderer/wgsl/compose.frag.wgsl.js +105 -105
- package/lib/renderer/wgsl/customDenoise.wgsl.js +10 -10
- package/lib/renderer/wgsl/depthQuery.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/depthQuery.wgsl.js +5 -5
- package/lib/renderer/wgsl/depthQuery.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/offlineAdaptive.compute.js +28 -28
- package/lib/renderer/wgsl/rayTrace.compute.js +251 -248
- package/lib/renderer/wgsl/rayTrace.compute.js.map +1 -1
- package/lib/scene/EnvironmentLight.d.ts +9 -3
- package/lib/scene/EnvironmentLight.js +9 -2
- package/lib/scene/EnvironmentLight.js.map +1 -1
- package/lib/scene/OpenPBRMaterial.d.ts +1 -1
- package/lib/scene/OpenPBRMaterial.js +1 -1
- package/lib/scene/OpenPBRMaterial.js.map +1 -1
- package/lib/scene/Scene.d.ts +4 -0
- package/lib/scene/Scene.js.map +1 -1
- package/lib/scene/SpotLight.d.ts +2 -2
- package/lib/scene/SpotLight.js +1 -1
- package/lib/scene/SpotLight.js.map +1 -1
- package/lib/scene/Texture.d.ts +17 -6
- package/lib/scene/Texture.js +13 -4
- package/lib/scene/Texture.js.map +1 -1
- package/lib/util/fromTHREE.js +151 -29
- package/lib/util/fromTHREE.js.map +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/lib/version.js.map +1 -1
- package/package.json +1 -1
|
@@ -47,6 +47,7 @@ geometryBitangent: vec3f,
|
|
|
47
47
|
` : /* wgsl */ ``}
|
|
48
48
|
uv: vec2f,
|
|
49
49
|
uv1: vec2f,
|
|
50
|
+
vertexColor: vec3f,
|
|
50
51
|
|
|
51
52
|
triangleIndex: i32,
|
|
52
53
|
instanceIndex: i32,
|
|
@@ -202,7 +203,7 @@ secondaryUv1: vec2f,
|
|
|
202
203
|
secondaryUv2: vec2f,
|
|
203
204
|
};
|
|
204
205
|
|
|
205
|
-
struct
|
|
206
|
+
struct pe {
|
|
206
207
|
probability: f32,
|
|
207
208
|
aliasIndex: i32,
|
|
208
209
|
sourceType: i32,
|
|
@@ -249,6 +250,8 @@ sceneFeatureFlags: u32,
|
|
|
249
250
|
sequenceSeed: u32,
|
|
250
251
|
zSobolLogSPP: u32,
|
|
251
252
|
sampleSequenceOffset: u32,
|
|
253
|
+
environmentRotation: mat4x4f,
|
|
254
|
+
backgroundMapTransform: vec4f,
|
|
252
255
|
}
|
|
253
256
|
|
|
254
257
|
|
|
@@ -270,20 +273,20 @@ sampleSequenceOffset: u32,
|
|
|
270
273
|
@group(1) @binding(9) var openPbrEnergyLut: texture_2d<f32>;
|
|
271
274
|
@group(1) @binding(10) var adaptiveSampleTargets: texture_2d<f32>;
|
|
272
275
|
|
|
273
|
-
fn cL(dV: i32,
|
|
274
|
-
let
|
|
276
|
+
fn cL(dV: i32, ls: i32) -> f32 {
|
|
277
|
+
let im = dV + ls / 4;
|
|
275
278
|
let width = rtUniform.lightSamplingTextureWidth;
|
|
276
|
-
let packed = textureLoad(lightSamplingData, vec2i(
|
|
277
|
-
return packed[
|
|
279
|
+
let packed = textureLoad(lightSamplingData, vec2i(im % width, im / width), 0);
|
|
280
|
+
return packed[ls % 4];
|
|
278
281
|
}
|
|
279
282
|
|
|
280
|
-
fn
|
|
283
|
+
fn kR(dV: i32, uv: vec2f) -> f32 {
|
|
281
284
|
if (dV < 0) { return 1.0; }
|
|
282
|
-
let
|
|
283
|
-
let x0 = i32(floor(
|
|
284
|
-
let y0 = i32(floor(
|
|
285
|
-
let fx = fract(
|
|
286
|
-
let fy = fract(
|
|
285
|
+
let fQ = fract(uv) * 128.0 - vec2f(0.5);
|
|
286
|
+
let x0 = i32(floor(fQ.x));
|
|
287
|
+
let y0 = i32(floor(fQ.y));
|
|
288
|
+
let fx = fract(fQ.x);
|
|
289
|
+
let fy = fract(fQ.y);
|
|
287
290
|
let xa = select(x0, 127, x0 < 0);
|
|
288
291
|
let xb = select(x0 + 1, 0, x0 >= 127);
|
|
289
292
|
let ya = select(y0, 127, y0 < 0);
|
|
@@ -295,19 +298,19 @@ let d = cL(dV, yb * 128 + xb);
|
|
|
295
298
|
return mix(mix(a, b, fx), mix(c, d, fx), fy);
|
|
296
299
|
}
|
|
297
300
|
|
|
298
|
-
fn bL(light: Light,
|
|
301
|
+
fn bL(light: Light, dK: vec3f) -> f32 {
|
|
299
302
|
let axis = normalize(light.u);
|
|
300
|
-
let cc = dot(axis,
|
|
301
|
-
var
|
|
302
|
-
if (light.v.y > 1e-6) {
|
|
303
|
-
|
|
303
|
+
let cc = dot(axis, dK);
|
|
304
|
+
var tP = select(0.0, 1.0, cc >= light.v.x);
|
|
305
|
+
if (light.v.y > light.v.x + 1e-6) {
|
|
306
|
+
tP = smoothstep(light.v.x, light.v.y, cc);
|
|
304
307
|
}
|
|
305
|
-
if (
|
|
306
|
-
let
|
|
307
|
-
let
|
|
308
|
+
if (tP <= 0.0 || light.textureIndex < 0.0) { return tP; }
|
|
309
|
+
let uj = light.iesReference;
|
|
310
|
+
let vD = cross(axis, uj);
|
|
308
311
|
let vertical = acos(clamp(cc, -1.0, 1.0));
|
|
309
|
-
let horizontal = atan2(dot(
|
|
310
|
-
return
|
|
312
|
+
let horizontal = atan2(dot(dK, vD), dot(dK, uj));
|
|
313
|
+
return tP * kR(i32(light.textureIndex), vec2f(vertical / PI, horizontal / TWOPI + 0.5));
|
|
311
314
|
}
|
|
312
315
|
|
|
313
316
|
|
|
@@ -319,7 +322,7 @@ return tI * kI(i32(light.textureIndex), vec2f(vertical / PI, horizontal / TWOPI
|
|
|
319
322
|
@group(2) @binding(2) var<uniform> analyticLights: array<Light, NUM_UNIFORM_LIGHTS>;
|
|
320
323
|
|
|
321
324
|
|
|
322
|
-
fn
|
|
325
|
+
fn iC(ray: ptr<function, Ray>, origin: vec3f, direction: vec3f) {
|
|
323
326
|
(*ray).o = origin;
|
|
324
327
|
(*ray).d = direction;
|
|
325
328
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rayTraceCore.wgsl.js","sourceRoot":"","sources":["../../../../src/renderer/wgsl/chunks/rayTraceCore.wgsl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC7E,OAAO,EACL,0BAA0B,EAC1B,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,EACpB,MAAM,qBAAqB,CAAC;AAE7B,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,EACnC,uBAAuB,GAAG,IAAI,EAC9B,cAAc,GAAG,KAAK,EACtB,aAAa,GAAG,IAAI,EAKrB;IACC,OAAO,QAAQ,CAAC;;;;;;gBAMF,aAAa;yBACJ,qBAAqB;;qBAEzB,mBAAmB;uBACjB,qBAAqB;4BAChB,0BAA0B;qBACjC,mBAAmB;;;;;;;;;;;;;;;EAetC,cAAc,CAAC,CAAC,CAAC,UAAU,CAAC;;CAE7B,CAAC,CAAC,CAAC,EAAE;;;;;;;;EAQJ,uBAAuB,CAAC,CAAC,CAAC,UAAU,CAAC;;;;;CAKtC,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0Df,uBAAuB,CAAC,CAAC,CAAC,UAAU,CAAC;;;;EAIrC,uBAAuB,CAAC,CAAC,CAAC,UAAU,CAAC;;;;;CAKtC,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE;CAChB,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE;EACf,cAAc,CAAC,CAAC,CAAC,UAAU,CAAC;;;;CAI7B,CAAC,CAAC,CAAC,EAAE;;;;;;EAMF,aAAa,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsFxC,kBAAkB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8DA6CwC,uBAAuB,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqE9H,CAAC;AACF,CAAC","sourcesContent":["import { materialBufferWgsl } from '../../materialLayout.js';\nimport { ShadowCatcherMaterial, UnlitMaterial } from '../../../constants.js';\nimport {\n CONSTANT_DIRECTIONAL_LIGHT,\n CONSTANT_RECT_LIGHT,\n CONSTANT_SPHERE_LIGHT,\n CONSTANT_SPOT_LIGHT\n} from '../../lightsUtil.js';\n\nexport default function rayTraceCore({\n hasAnisotropyDirections = true,\n hasCoatNormals = false,\n hasSceneAlpha = true\n}: {\n hasAnisotropyDirections?: boolean;\n hasCoatNormals?: boolean;\n hasSceneAlpha?: boolean;\n}) {\n return /*wgsl*/ `\n// https://www.w3.org/WAI/GL/wiki/Relative_luminance\nconst luminance = vec3f(0.2126, 0.7152, 0.0722);\nconst RAY_MAX_DISTANCE = 9999.0;\n\nconst STANDARD = 0;\nconst UNLIT = ${UnlitMaterial};\nconst SHADOW_CATCHER = ${ShadowCatcherMaterial};\n\nconst RECT_LIGHT = ${CONSTANT_RECT_LIGHT};\nconst SPHERE_LIGHT = ${CONSTANT_SPHERE_LIGHT};\nconst DIRECTIONAL_LIGHT = ${CONSTANT_DIRECTIONAL_LIGHT};\nconst SPOT_LIGHT = ${CONSTANT_SPOT_LIGHT};\n\nstruct Ray {\n o: vec3f,\n d: vec3f,\n};\n\nstruct SurfaceInteraction {\n position: vec3f,\n // For perfect specular or transmission surface\n // We use the albedo and normal of first diffuse or glossy surface hit instead for denoising\n // See albedo section in https://www.openimagedenoise.org/documentation.html\n albedoSampled: bool,\n\n normal: vec3f, // material shading normal\n${hasCoatNormals ? /* wgsl */ `\n coatNormal: vec3f, // independent, built before base normal mapping\n` : ''}\n vertexNormal: vec3f, // interpolated mesh normal before normal mapping\n shadowOffset: vec3f, // smooth-surface offset for direct-light shadow rays\n\n faceNormal: vec3f, // normal of the triangle\n hit: bool,\n\n tangent: vec3f,\n${hasAnisotropyDirections ? /* wgsl */ `\n directionTangent: vec3f,\n directionBitangent: vec3f,\n geometryTangent: vec3f,\n geometryBitangent: vec3f,\n` : /* wgsl */ ``}\n uv: vec2f,\n uv1: vec2f,\n\n triangleIndex: i32,\n instanceIndex: i32,\n materialIndex: i32,\n barycentrics: vec2f,\n\n wavelength: f32,\n\n mediumType: i32,\n mediumExtinction: vec3f,\n mediumScattering: vec3f,\n mediumAnisotropy: f32,\n\n};\n\n// Texture-resolved OpenPBR inputs used by the surface integrator. The storage\n// buffer keeps its compact legacy layout; getMaterial() is the compatibility\n// boundary that maps it to these canonical names.\nstruct OpenPbrResolvedMaterial {\n baseColor: vec3f,\n transmissionWeight: f32,\n\n emission: vec3f,\n specularAnisotropy: f32,\n\n baseMetalness: f32,\n specularIor: f32,\n specularRoughness: f32,\n\n transmissionDispersionScale: f32,\n dispersionAbbeNumber: f32,\n thinFilmThickness: f32,\n thinFilmIor: f32,\n thinFilmWeight: f32,\n\n // Medium\n mediumType: i32,\n mediumExtinction: vec3f,\n mediumScattering: vec3f,\n mediumAnisotropy: f32,\n\n baseWeight: f32,\n diffuseRoughness: f32,\n specularWeight: f32,\n specularColor: vec3f,\n subsurfaceWeight: f32,\n subsurfaceColor: vec3f,\n transmissionColor: vec3f,\n fuzzWeight: f32,\n fuzzColor: vec3f,\n fuzzRoughness: f32,\n coatWeight: f32,\n coatColor: vec3f,\n coatRoughness: f32,\n coatAnisotropy: f32,\n${hasAnisotropyDirections ? /* wgsl */ `\n anisotropyDirection: vec2f,\n anisotropyDirectionEnabled: bool,\n coatAnisotropyRotation: f32,\n${hasAnisotropyDirections ? /* wgsl */ `\n directionTangent: vec3f,\n directionBitangent: vec3f,\n geometryTangent: vec3f,\n geometryBitangent: vec3f,\n` : /* wgsl */ ``}\n` : /* wgsl */ ``}\n${hasCoatNormals ? /* wgsl */ `\n coatNormal: vec3f,\n coatNormalEnabled: bool,\n geometricNormal: vec3f, // face normal oriented toward the view\n` : ''}\n coatIor: f32,\n coatDarkening: f32,\n\n // Alpha\n alpha: f32,\n ${hasSceneAlpha ? 'alphaMode: i32,' : ''}\n\n materialType: i32,\n\n bevel: f32,\n\n relativeIor: f32,\n inside: bool,\n\n alphaX: f32,\n alphaY: f32,\n thinWalled: bool,\n};\n\nstruct Path {\n ray: Ray,\n li: vec3f,\n alpha: f32,\n beta: vec3f,\n fromEye: bool,\n abort: bool,\n scatteringPdf: f32,\n scatteringIsDelta: bool,\n isNextRefraction: bool,\n};\n\nstruct LightSampleRec {\n normal: vec3f,\n emission: vec3f,\n direction: vec3f,\n dist: f32,\n pdf: f32,\n // Discrete probability of selecting this light before sampling its\n // conditional point/direction. Light RIS excludes this term from the target\n // and carries it in the unbiased contribution weight instead.\n selectionPmf: f32,\n isDelta: bool,\n // Light source type: environment=0, emissive triangle=1, analytic=2.\n sourceType: u32,\n sourceIndex: u32,\n};\n\nstruct Light {\n position: vec3f,\n litType: f32,\n\n emission: vec3f,\n area: f32,\n\n u: vec3f,\n // Radius for sphere light, spread for rect light\n radiusOrSpread: f32,\n\n v: vec3f,\n textureIndex: f32,\n\n selectionPmf: f32,\n _samplingPadding0: f32,\n _samplingPadding1: f32,\n _samplingPadding2: f32,\n iesReference: vec3f,\n _iesPadding: f32,\n};\n\nstruct EmissiveTriangle {\n p0: vec3f,\n selectionPmf: f32,\n p1: vec3f,\n area: f32,\n p2: vec3f,\n materialIndex: f32,\n uv0: vec2f,\n uv1: vec2f,\n uv2: vec2f,\n secondaryUv0: vec2f,\n secondaryUv1: vec2f,\n secondaryUv2: vec2f,\n};\n\nstruct LightChoice {\n probability: f32,\n aliasIndex: i32,\n sourceType: i32,\n sourceIndex: i32,\n};\n\n${materialBufferWgsl()}\n\nstruct CameraUniform {\n viewProjectionInv: mat4x4<f32>,\n viewInv: mat4x4<f32>,\n apertureRadius: f32,\n focusDistance: f32,\n};\n\nstruct RayTraceUniform {\n outputSize: vec2f,\n sampleCount: f32,\n scaleOffset: vec4f,\n lightsCount: i32,\n transmissiveOutputAlphaMin: f32,\n jitter: vec2f,\n backgroundColor: vec4f,\n groundedBackgroundParams: vec4f,\n groundedBackgroundCenter: vec2f,\n blasOffset: i32,\n isEmpty: i32,\n bevel: i32,\n dispersionWavelengths: i32,\n envLightPmf: f32,\n lightChoiceCount: i32,\n lightWeightTotal: f32,\n lightSamplingTextureWidth: i32,\n lightChoiceTexelOffset: i32,\n bounces: i32,\n varianceMoments: i32,\n adaptiveSampling: i32,\n clamping: f32,\n directLightCandidates: i32,\n backgroundFlags: i32,\n // Fixed at 4: runtime trip bounds discourage thin-film loop unrolling.\n loopUnrollGuard: u32,\n sceneFeatureFlags: u32,\n sequenceSeed: u32,\n zSobolLogSPP: u32,\n sampleSequenceOffset: u32,\n}\n\n// Buffers\n@group(0) @binding(0) var<storage, read> bvhBuffer: array<vec4f>;\n@group(0) @binding(1) var<storage, read> instancesBuffer: array<vec4f>;\n@group(0) @binding(2) var<storage, read> attrBuffers: array<${hasAnisotropyDirections ? /* wgsl */ `vec4f` : /* wgsl */ `vec3f`}>;\n@group(0) @binding(3) var<storage, read> materialsBuffer: array<MaterialBuffer>;\n\n// Textures\n@group(1) @binding(0) var mapSampler: sampler;\n@group(1) @binding(1) var map: texture_2d_array<f32>;\n// The first NUM_MAPS entries contain atlas placement; the second half stores\n// per-texture UV scale/offset; the third block stores the UV channel in x.\n@group(1) @binding(3) var<uniform> mapInfo: array<vec4f, NUM_MAPS * 3>;\n@group(1) @binding(4) var envMap: texture_2d<f32>;\n@group(1) @binding(5) var envMapDistribution: texture_2d<f32>;\n@group(1) @binding(6) var backgroundMap: texture_2d<f32>;\n@group(1) @binding(8) var lightSamplingData: texture_2d<f32>;\n@group(1) @binding(9) var openPbrEnergyLut: texture_2d<f32>;\n@group(1) @binding(10) var adaptiveSampleTargets: texture_2d<f32>;\n\nfn iesProfileScalar(baseTexel: i32, scalarIndex: i32) -> f32 {\n let texelIndex = baseTexel + scalarIndex / 4;\n let width = rtUniform.lightSamplingTextureWidth;\n let packed = textureLoad(lightSamplingData, vec2i(texelIndex % width, texelIndex / width), 0);\n return packed[scalarIndex % 4];\n}\n\nfn sampleIESProfile(baseTexel: i32, uv: vec2f) -> f32 {\n if (baseTexel < 0) { return 1.0; }\n let pixel = fract(uv) * 128.0 - vec2f(0.5);\n let x0 = i32(floor(pixel.x));\n let y0 = i32(floor(pixel.y));\n let fx = fract(pixel.x);\n let fy = fract(pixel.y);\n let xa = select(x0, 127, x0 < 0);\n let xb = select(x0 + 1, 0, x0 >= 127);\n let ya = select(y0, 127, y0 < 0);\n let yb = select(y0 + 1, 0, y0 >= 127);\n let a = iesProfileScalar(baseTexel, ya * 128 + xa);\n let b = iesProfileScalar(baseTexel, ya * 128 + xb);\n let c = iesProfileScalar(baseTexel, yb * 128 + xa);\n let d = iesProfileScalar(baseTexel, yb * 128 + xb);\n return mix(mix(a, b, fx), mix(c, d, fx), fy);\n}\n\nfn evaluateSpotEmissionMultiplier(light: Light, lightToSurface: vec3f) -> f32 {\n let axis = normalize(light.u);\n let cosTheta = dot(axis, lightToSurface);\n var cone = select(0.0, 1.0, cosTheta >= light.v.x);\n if (light.v.y > 1e-6) {\n cone = smoothstep(light.v.x, light.v.x + light.v.y, cosTheta);\n }\n if (cone <= 0.0 || light.textureIndex < 0.0) { return cone; }\n let xAxis = light.iesReference;\n let yAxis = cross(axis, xAxis);\n let vertical = acos(clamp(cosTheta, -1.0, 1.0));\n let horizontal = atan2(dot(lightToSurface, yAxis), dot(lightToSurface, xAxis));\n return cone * sampleIESProfile(i32(light.textureIndex), vec2f(vertical / PI, horizontal / TWOPI + 0.5));\n}\n\n\n \n// Uniforms\n@group(2) @binding(0) var<uniform> cameraUniform: CameraUniform;\n@group(2) @binding(1) var<uniform> rtUniform: RayTraceUniform;\n\n@group(2) @binding(2) var<uniform> analyticLights: array<Light, NUM_UNIFORM_LIGHTS>;\n// TODO uniform must be aligned to 16 bytes.\n\nfn initRay(ray: ptr<function, Ray>, origin: vec3f, direction: vec3f) {\n (*ray).o = origin;\n (*ray).d = direction;\n}\n`;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"rayTraceCore.wgsl.js","sourceRoot":"","sources":["../../../../src/renderer/wgsl/chunks/rayTraceCore.wgsl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC7E,OAAO,EACL,0BAA0B,EAC1B,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,EACpB,MAAM,qBAAqB,CAAC;AAE7B,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,EACnC,uBAAuB,GAAG,IAAI,EAC9B,cAAc,GAAG,KAAK,EACtB,aAAa,GAAG,IAAI,EAKrB;IACC,OAAO,QAAQ,CAAC;;;;;;gBAMF,aAAa;yBACJ,qBAAqB;;qBAEzB,mBAAmB;uBACjB,qBAAqB;4BAChB,0BAA0B;qBACjC,mBAAmB;;;;;;;;;;;;;;;EAetC,cAAc,CAAC,CAAC,CAAC,UAAU,CAAC;;CAE7B,CAAC,CAAC,CAAC,EAAE;;;;;;;;EAQJ,uBAAuB,CAAC,CAAC,CAAC,UAAU,CAAC;;;;;CAKtC,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2Df,uBAAuB,CAAC,CAAC,CAAC,UAAU,CAAC;;;;EAIrC,uBAAuB,CAAC,CAAC,CAAC,UAAU,CAAC;;;;;CAKtC,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE;CAChB,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE;EACf,cAAc,CAAC,CAAC,CAAC,UAAU,CAAC;;;;CAI7B,CAAC,CAAC,CAAC,EAAE;;;;;;EAMF,aAAa,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsFxC,kBAAkB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8DA+CwC,uBAAuB,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqE9H,CAAC;AACF,CAAC","sourcesContent":["import { materialBufferWgsl } from '../../materialLayout.js';\nimport { ShadowCatcherMaterial, UnlitMaterial } from '../../../constants.js';\nimport {\n CONSTANT_DIRECTIONAL_LIGHT,\n CONSTANT_RECT_LIGHT,\n CONSTANT_SPHERE_LIGHT,\n CONSTANT_SPOT_LIGHT\n} from '../../lightsUtil.js';\n\nexport default function rayTraceCore({\n hasAnisotropyDirections = true,\n hasCoatNormals = false,\n hasSceneAlpha = true\n}: {\n hasAnisotropyDirections?: boolean;\n hasCoatNormals?: boolean;\n hasSceneAlpha?: boolean;\n}) {\n return /*wgsl*/ `\n// https://www.w3.org/WAI/GL/wiki/Relative_luminance\nconst luminance = vec3f(0.2126, 0.7152, 0.0722);\nconst RAY_MAX_DISTANCE = 9999.0;\n\nconst STANDARD = 0;\nconst UNLIT = ${UnlitMaterial};\nconst SHADOW_CATCHER = ${ShadowCatcherMaterial};\n\nconst RECT_LIGHT = ${CONSTANT_RECT_LIGHT};\nconst SPHERE_LIGHT = ${CONSTANT_SPHERE_LIGHT};\nconst DIRECTIONAL_LIGHT = ${CONSTANT_DIRECTIONAL_LIGHT};\nconst SPOT_LIGHT = ${CONSTANT_SPOT_LIGHT};\n\nstruct Ray {\n o: vec3f,\n d: vec3f,\n};\n\nstruct SurfaceInteraction {\n position: vec3f,\n // For perfect specular or transmission surface\n // We use the albedo and normal of first diffuse or glossy surface hit instead for denoising\n // See albedo section in https://www.openimagedenoise.org/documentation.html\n albedoSampled: bool,\n\n normal: vec3f, // material shading normal\n${hasCoatNormals ? /* wgsl */ `\n coatNormal: vec3f, // independent, built before base normal mapping\n` : ''}\n vertexNormal: vec3f, // interpolated mesh normal before normal mapping\n shadowOffset: vec3f, // smooth-surface offset for direct-light shadow rays\n\n faceNormal: vec3f, // normal of the triangle\n hit: bool,\n\n tangent: vec3f,\n${hasAnisotropyDirections ? /* wgsl */ `\n directionTangent: vec3f,\n directionBitangent: vec3f,\n geometryTangent: vec3f,\n geometryBitangent: vec3f,\n` : /* wgsl */ ``}\n uv: vec2f,\n uv1: vec2f,\n vertexColor: vec3f,\n\n triangleIndex: i32,\n instanceIndex: i32,\n materialIndex: i32,\n barycentrics: vec2f,\n\n wavelength: f32,\n\n mediumType: i32,\n mediumExtinction: vec3f,\n mediumScattering: vec3f,\n mediumAnisotropy: f32,\n\n};\n\n// Texture-resolved OpenPBR inputs used by the surface integrator. The storage\n// buffer keeps its compact legacy layout; getMaterial() is the compatibility\n// boundary that maps it to these canonical names.\nstruct OpenPbrResolvedMaterial {\n baseColor: vec3f,\n transmissionWeight: f32,\n\n emission: vec3f,\n specularAnisotropy: f32,\n\n baseMetalness: f32,\n specularIor: f32,\n specularRoughness: f32,\n\n transmissionDispersionScale: f32,\n dispersionAbbeNumber: f32,\n thinFilmThickness: f32,\n thinFilmIor: f32,\n thinFilmWeight: f32,\n\n // Medium\n mediumType: i32,\n mediumExtinction: vec3f,\n mediumScattering: vec3f,\n mediumAnisotropy: f32,\n\n baseWeight: f32,\n diffuseRoughness: f32,\n specularWeight: f32,\n specularColor: vec3f,\n subsurfaceWeight: f32,\n subsurfaceColor: vec3f,\n transmissionColor: vec3f,\n fuzzWeight: f32,\n fuzzColor: vec3f,\n fuzzRoughness: f32,\n coatWeight: f32,\n coatColor: vec3f,\n coatRoughness: f32,\n coatAnisotropy: f32,\n${hasAnisotropyDirections ? /* wgsl */ `\n anisotropyDirection: vec2f,\n anisotropyDirectionEnabled: bool,\n coatAnisotropyRotation: f32,\n${hasAnisotropyDirections ? /* wgsl */ `\n directionTangent: vec3f,\n directionBitangent: vec3f,\n geometryTangent: vec3f,\n geometryBitangent: vec3f,\n` : /* wgsl */ ``}\n` : /* wgsl */ ``}\n${hasCoatNormals ? /* wgsl */ `\n coatNormal: vec3f,\n coatNormalEnabled: bool,\n geometricNormal: vec3f, // face normal oriented toward the view\n` : ''}\n coatIor: f32,\n coatDarkening: f32,\n\n // Alpha\n alpha: f32,\n ${hasSceneAlpha ? 'alphaMode: i32,' : ''}\n\n materialType: i32,\n\n bevel: f32,\n\n relativeIor: f32,\n inside: bool,\n\n alphaX: f32,\n alphaY: f32,\n thinWalled: bool,\n};\n\nstruct Path {\n ray: Ray,\n li: vec3f,\n alpha: f32,\n beta: vec3f,\n fromEye: bool,\n abort: bool,\n scatteringPdf: f32,\n scatteringIsDelta: bool,\n isNextRefraction: bool,\n};\n\nstruct LightSampleRec {\n normal: vec3f,\n emission: vec3f,\n direction: vec3f,\n dist: f32,\n pdf: f32,\n // Discrete probability of selecting this light before sampling its\n // conditional point/direction. Light RIS excludes this term from the target\n // and carries it in the unbiased contribution weight instead.\n selectionPmf: f32,\n isDelta: bool,\n // Light source type: environment=0, emissive triangle=1, analytic=2.\n sourceType: u32,\n sourceIndex: u32,\n};\n\nstruct Light {\n position: vec3f,\n litType: f32,\n\n emission: vec3f,\n area: f32,\n\n u: vec3f,\n // Radius for sphere light, spread for rect light\n radiusOrSpread: f32,\n\n v: vec3f,\n textureIndex: f32,\n\n selectionPmf: f32,\n _samplingPadding0: f32,\n _samplingPadding1: f32,\n _samplingPadding2: f32,\n iesReference: vec3f,\n _iesPadding: f32,\n};\n\nstruct EmissiveTriangle {\n p0: vec3f,\n selectionPmf: f32,\n p1: vec3f,\n area: f32,\n p2: vec3f,\n materialIndex: f32,\n uv0: vec2f,\n uv1: vec2f,\n uv2: vec2f,\n secondaryUv0: vec2f,\n secondaryUv1: vec2f,\n secondaryUv2: vec2f,\n};\n\nstruct LightChoice {\n probability: f32,\n aliasIndex: i32,\n sourceType: i32,\n sourceIndex: i32,\n};\n\n${materialBufferWgsl()}\n\nstruct CameraUniform {\n viewProjectionInv: mat4x4<f32>,\n viewInv: mat4x4<f32>,\n apertureRadius: f32,\n focusDistance: f32,\n};\n\nstruct RayTraceUniform {\n outputSize: vec2f,\n sampleCount: f32,\n scaleOffset: vec4f,\n lightsCount: i32,\n transmissiveOutputAlphaMin: f32,\n jitter: vec2f,\n backgroundColor: vec4f,\n groundedBackgroundParams: vec4f,\n groundedBackgroundCenter: vec2f,\n blasOffset: i32,\n isEmpty: i32,\n bevel: i32,\n dispersionWavelengths: i32,\n envLightPmf: f32,\n lightChoiceCount: i32,\n lightWeightTotal: f32,\n lightSamplingTextureWidth: i32,\n lightChoiceTexelOffset: i32,\n bounces: i32,\n varianceMoments: i32,\n adaptiveSampling: i32,\n clamping: f32,\n directLightCandidates: i32,\n backgroundFlags: i32,\n // Fixed at 4: runtime trip bounds discourage thin-film loop unrolling.\n loopUnrollGuard: u32,\n sceneFeatureFlags: u32,\n sequenceSeed: u32,\n zSobolLogSPP: u32,\n sampleSequenceOffset: u32,\n environmentRotation: mat4x4f,\n backgroundMapTransform: vec4f,\n}\n\n// Buffers\n@group(0) @binding(0) var<storage, read> bvhBuffer: array<vec4f>;\n@group(0) @binding(1) var<storage, read> instancesBuffer: array<vec4f>;\n@group(0) @binding(2) var<storage, read> attrBuffers: array<${hasAnisotropyDirections ? /* wgsl */ `vec4f` : /* wgsl */ `vec3f`}>;\n@group(0) @binding(3) var<storage, read> materialsBuffer: array<MaterialBuffer>;\n\n// Textures\n@group(1) @binding(0) var mapSampler: sampler;\n@group(1) @binding(1) var map: texture_2d_array<f32>;\n// The first NUM_MAPS entries contain atlas placement; the second half stores\n// per-texture UV scale/offset; the third block stores the UV channel in x.\n@group(1) @binding(3) var<uniform> mapInfo: array<vec4f, NUM_MAPS * 3>;\n@group(1) @binding(4) var envMap: texture_2d<f32>;\n@group(1) @binding(5) var envMapDistribution: texture_2d<f32>;\n@group(1) @binding(6) var backgroundMap: texture_2d<f32>;\n@group(1) @binding(8) var lightSamplingData: texture_2d<f32>;\n@group(1) @binding(9) var openPbrEnergyLut: texture_2d<f32>;\n@group(1) @binding(10) var adaptiveSampleTargets: texture_2d<f32>;\n\nfn iesProfileScalar(baseTexel: i32, scalarIndex: i32) -> f32 {\n let texelIndex = baseTexel + scalarIndex / 4;\n let width = rtUniform.lightSamplingTextureWidth;\n let packed = textureLoad(lightSamplingData, vec2i(texelIndex % width, texelIndex / width), 0);\n return packed[scalarIndex % 4];\n}\n\nfn sampleIESProfile(baseTexel: i32, uv: vec2f) -> f32 {\n if (baseTexel < 0) { return 1.0; }\n let pixel = fract(uv) * 128.0 - vec2f(0.5);\n let x0 = i32(floor(pixel.x));\n let y0 = i32(floor(pixel.y));\n let fx = fract(pixel.x);\n let fy = fract(pixel.y);\n let xa = select(x0, 127, x0 < 0);\n let xb = select(x0 + 1, 0, x0 >= 127);\n let ya = select(y0, 127, y0 < 0);\n let yb = select(y0 + 1, 0, y0 >= 127);\n let a = iesProfileScalar(baseTexel, ya * 128 + xa);\n let b = iesProfileScalar(baseTexel, ya * 128 + xb);\n let c = iesProfileScalar(baseTexel, yb * 128 + xa);\n let d = iesProfileScalar(baseTexel, yb * 128 + xb);\n return mix(mix(a, b, fx), mix(c, d, fx), fy);\n}\n\nfn evaluateSpotEmissionMultiplier(light: Light, lightToSurface: vec3f) -> f32 {\n let axis = normalize(light.u);\n let cosTheta = dot(axis, lightToSurface);\n var cone = select(0.0, 1.0, cosTheta >= light.v.x);\n if (light.v.y > light.v.x + 1e-6) {\n cone = smoothstep(light.v.x, light.v.y, cosTheta);\n }\n if (cone <= 0.0 || light.textureIndex < 0.0) { return cone; }\n let xAxis = light.iesReference;\n let yAxis = cross(axis, xAxis);\n let vertical = acos(clamp(cosTheta, -1.0, 1.0));\n let horizontal = atan2(dot(lightToSurface, yAxis), dot(lightToSurface, xAxis));\n return cone * sampleIESProfile(i32(light.textureIndex), vec2f(vertical / PI, horizontal / TWOPI + 0.5));\n}\n\n\n \n// Uniforms\n@group(2) @binding(0) var<uniform> cameraUniform: CameraUniform;\n@group(2) @binding(1) var<uniform> rtUniform: RayTraceUniform;\n\n@group(2) @binding(2) var<uniform> analyticLights: array<Light, NUM_UNIFORM_LIGHTS>;\n// TODO uniform must be aligned to 16 bytes.\n\nfn initRay(ray: ptr<function, Ray>, origin: vec3f, direction: vec3f) {\n (*ray).o = origin;\n (*ray).d = direction;\n}\n`;\n}\n"]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { LIGHT_CHOICE_ANALYTIC, LIGHT_CHOICE_EMISSIVE_TRIANGLE, LIGHT_CHOICE_ENVIRONMENT } from '../../lightSampling.js';
|
|
2
2
|
export default /*wgsl */ `
|
|
3
|
-
fn
|
|
4
|
-
let
|
|
5
|
-
let aj = length(
|
|
3
|
+
fn eM(light: Light, ft: vec3f, iZ: vec2f, lightSample: ptr<function, LightSampleRec>) {
|
|
4
|
+
let iw = light.position - ft;
|
|
5
|
+
let aj = length(iw);
|
|
6
6
|
if (light.radiusOrSpread <= 0.0) {
|
|
7
7
|
|
|
8
8
|
|
|
@@ -16,7 +16,7 @@ if (aj <= 1e-6) {
|
|
|
16
16
|
(*lightSample).isDelta = true;
|
|
17
17
|
return;
|
|
18
18
|
}
|
|
19
|
-
(*lightSample).direction =
|
|
19
|
+
(*lightSample).direction = iw / aj;
|
|
20
20
|
(*lightSample).normal = -(*lightSample).direction;
|
|
21
21
|
(*lightSample).dist = aj;
|
|
22
22
|
(*lightSample).pdf = 1.0;
|
|
@@ -27,33 +27,33 @@ return;
|
|
|
27
27
|
}
|
|
28
28
|
let radius = max(light.radiusOrSpread, 1e-6);
|
|
29
29
|
(*lightSample).isDelta = false;
|
|
30
|
-
var
|
|
30
|
+
var gK: vec3f;
|
|
31
31
|
|
|
32
32
|
if (aj <= radius) {
|
|
33
|
-
let z = 1.0 - 2.0 *
|
|
34
|
-
let
|
|
35
|
-
let br = TWOPI *
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
33
|
+
let z = 1.0 - 2.0 * iZ.x;
|
|
34
|
+
let fl = sqrt(max(0.0, 1.0 - z * z));
|
|
35
|
+
let br = TWOPI * iZ.y;
|
|
36
|
+
gK = vec3f(
|
|
37
|
+
fl * cos(br),
|
|
38
|
+
fl * sin(br),
|
|
39
39
|
z
|
|
40
40
|
);
|
|
41
41
|
(*lightSample).pdf = INV4PI;
|
|
42
42
|
}
|
|
43
43
|
else {
|
|
44
|
-
let
|
|
45
|
-
let
|
|
44
|
+
let sS = iw / aj;
|
|
45
|
+
let jv = min(
|
|
46
46
|
1.0,
|
|
47
47
|
radius * radius / (aj * aj)
|
|
48
48
|
);
|
|
49
|
-
let cosThetaMax = sqrt(max(0.0, 1.0 -
|
|
50
|
-
let cc = mix(1.0, cosThetaMax,
|
|
49
|
+
let cosThetaMax = sqrt(max(0.0, 1.0 - jv));
|
|
50
|
+
let cc = mix(1.0, cosThetaMax, iZ.x);
|
|
51
51
|
let sinTheta = sqrt(max(0.0, 1.0 - cc * cc));
|
|
52
|
-
let br = TWOPI *
|
|
52
|
+
let br = TWOPI * iZ.y;
|
|
53
53
|
var tangent: vec3f;
|
|
54
54
|
var bitangent: vec3f;
|
|
55
|
-
aL(
|
|
56
|
-
|
|
55
|
+
aL(sS, &tangent, &bitangent);
|
|
56
|
+
gK = sS * cc
|
|
57
57
|
+ tangent * (sinTheta * cos(br))
|
|
58
58
|
+ bitangent * (sinTheta * sin(br));
|
|
59
59
|
(*lightSample).pdf = 1.0 / max(
|
|
@@ -62,20 +62,20 @@ TWOPI * (1.0 - cosThetaMax),
|
|
|
62
62
|
);
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
let
|
|
66
|
-
let
|
|
67
|
-
let ej =
|
|
68
|
-
-
|
|
69
|
-
let cN =
|
|
70
|
-
let cC =
|
|
65
|
+
let iz = dot(gK, iw);
|
|
66
|
+
let qc = dot(iw, iw);
|
|
67
|
+
let ej = iz * iz
|
|
68
|
+
- qc + radius * radius;
|
|
69
|
+
let cN = iz - sqrt(max(0.0, ej));
|
|
70
|
+
let cC = iz + sqrt(max(0.0, ej));
|
|
71
71
|
(*lightSample).dist = select(cC, cN, cN > 1e-6);
|
|
72
|
-
(*lightSample).direction =
|
|
73
|
-
let
|
|
74
|
-
(*lightSample).normal = normalize(
|
|
72
|
+
(*lightSample).direction = gK;
|
|
73
|
+
let sd = ft + gK * (*lightSample).dist;
|
|
74
|
+
(*lightSample).normal = normalize(sd - light.position);
|
|
75
75
|
(*lightSample).emission = light.emission;
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
fn
|
|
78
|
+
fn da(
|
|
79
79
|
light: Light,
|
|
80
80
|
surfacePoint: vec3f,
|
|
81
81
|
lowerLeft: vec3f,
|
|
@@ -86,15 +86,15 @@ return;
|
|
|
86
86
|
}
|
|
87
87
|
let width = length(light.u);
|
|
88
88
|
let height = length(light.v);
|
|
89
|
-
let
|
|
89
|
+
let ib = surfacePoint - lowerLeft;
|
|
90
90
|
let uv = vec2f(
|
|
91
|
-
dot(
|
|
92
|
-
dot(
|
|
91
|
+
dot(ib, light.u / width) / width,
|
|
92
|
+
dot(ib, light.v / height) / height
|
|
93
93
|
);
|
|
94
94
|
(*result).emission *= sampleMap(i32(light.textureIndex), uv).rgb;
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
fn
|
|
97
|
+
fn jS(
|
|
98
98
|
light: Light,
|
|
99
99
|
shadingPoint: vec3f,
|
|
100
100
|
samplePoint: vec2f,
|
|
@@ -105,27 +105,27 @@ let lowerLeft = light.position - 0.5 * (light.u + light.v);
|
|
|
105
105
|
let spread = clamp(light.radiusOrSpread, 0.0, 1.0);
|
|
106
106
|
|
|
107
107
|
if (spread <= 0.001) {
|
|
108
|
-
let
|
|
109
|
-
let surfacePoint = shadingPoint - normal *
|
|
110
|
-
let
|
|
108
|
+
let gg = dot(normal, shadingPoint - light.position);
|
|
109
|
+
let surfacePoint = shadingPoint - normal * gg;
|
|
110
|
+
let ib = surfacePoint - lowerLeft;
|
|
111
111
|
let width = length(light.u);
|
|
112
112
|
let height = length(light.v);
|
|
113
113
|
let uv = vec2f(
|
|
114
|
-
dot(
|
|
115
|
-
dot(
|
|
114
|
+
dot(ib, light.u / width) / width,
|
|
115
|
+
dot(ib, light.v / height) / height
|
|
116
116
|
);
|
|
117
|
-
if (
|
|
117
|
+
if (gg <= 0.0 || any(uv < vec2f(0.0)) || any(uv > vec2f(1.0))) {
|
|
118
118
|
(*result).emission = vec3f(0.0);
|
|
119
119
|
(*result).pdf = 0.0;
|
|
120
120
|
return;
|
|
121
121
|
}
|
|
122
122
|
(*result).direction = -normal;
|
|
123
|
-
(*result).dist =
|
|
123
|
+
(*result).dist = gg;
|
|
124
124
|
(*result).normal = normal;
|
|
125
125
|
(*result).emission = light.emission;
|
|
126
126
|
(*result).pdf = 1.0;
|
|
127
127
|
(*result).isDelta = true;
|
|
128
|
-
|
|
128
|
+
da(light, surfacePoint, lowerLeft, result);
|
|
129
129
|
return;
|
|
130
130
|
}
|
|
131
131
|
|
|
@@ -133,23 +133,23 @@ let surfacePoint = lowerLeft
|
|
|
133
133
|
+ light.u * samplePoint.x
|
|
134
134
|
+ light.v * samplePoint.y;
|
|
135
135
|
let offset = surfacePoint - shadingPoint;
|
|
136
|
-
let
|
|
137
|
-
(*result).dist = sqrt(
|
|
136
|
+
let hq = dot(offset, offset);
|
|
137
|
+
(*result).dist = sqrt(hq);
|
|
138
138
|
(*result).direction = offset / (*result).dist;
|
|
139
139
|
(*result).normal = normal;
|
|
140
|
-
let
|
|
141
|
-
let
|
|
142
|
-
if (
|
|
140
|
+
let ga = dot(-(*result).direction, normal);
|
|
141
|
+
let oN = cos(0.5 * PI * spread);
|
|
142
|
+
if (ga <= 0.0 || ga < oN) {
|
|
143
143
|
(*result).emission = vec3f(0.0);
|
|
144
144
|
(*result).pdf = 0.0;
|
|
145
145
|
return;
|
|
146
146
|
}
|
|
147
147
|
(*result).emission = light.emission;
|
|
148
|
-
(*result).pdf =
|
|
149
|
-
|
|
148
|
+
(*result).pdf = hq / max(light.area * ga, 1e-8);
|
|
149
|
+
da(light, surfacePoint, lowerLeft, result);
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
-
fn
|
|
152
|
+
fn gd(
|
|
153
153
|
light: Light,
|
|
154
154
|
result: ptr<function, LightSampleRec>
|
|
155
155
|
) {
|
|
@@ -161,59 +161,59 @@ result: ptr<function, LightSampleRec>
|
|
|
161
161
|
(*result).isDelta = true;
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
-
fn
|
|
164
|
+
fn jT(
|
|
165
165
|
light: Light,
|
|
166
166
|
shadingPoint: vec3f,
|
|
167
167
|
samplePoint: vec2f,
|
|
168
168
|
result: ptr<function, LightSampleRec>
|
|
169
169
|
) {
|
|
170
|
-
|
|
170
|
+
eM(light, shadingPoint, samplePoint, result);
|
|
171
171
|
let surfacePoint = shadingPoint + (*result).direction * (*result).dist;
|
|
172
|
-
let
|
|
173
|
-
(*result).emission *= bL(light,
|
|
172
|
+
let dK = normalize(shadingPoint - surfacePoint);
|
|
173
|
+
(*result).emission *= bL(light, dK);
|
|
174
174
|
}
|
|
175
175
|
|
|
176
|
-
fn
|
|
176
|
+
fn iQ(
|
|
177
177
|
light: Light,
|
|
178
178
|
shadingPoint: vec3f,
|
|
179
179
|
samplePoint: vec2f,
|
|
180
180
|
result: ptr<function, LightSampleRec>
|
|
181
181
|
) {
|
|
182
|
-
let
|
|
183
|
-
if (
|
|
184
|
-
|
|
182
|
+
let dP = i32(light.litType);
|
|
183
|
+
if (dP == RECT_LIGHT) {
|
|
184
|
+
jS(light, shadingPoint, samplePoint, result);
|
|
185
185
|
return;
|
|
186
186
|
}
|
|
187
|
-
if (
|
|
188
|
-
|
|
187
|
+
if (dP == SPHERE_LIGHT) {
|
|
188
|
+
eM(light, shadingPoint, samplePoint, result);
|
|
189
189
|
return;
|
|
190
190
|
}
|
|
191
|
-
if (
|
|
192
|
-
|
|
191
|
+
if (dP == SPOT_LIGHT) {
|
|
192
|
+
jT(light, shadingPoint, samplePoint, result);
|
|
193
193
|
return;
|
|
194
194
|
}
|
|
195
|
-
if (
|
|
196
|
-
|
|
195
|
+
if (dP == DIRECTIONAL_LIGHT) {
|
|
196
|
+
gd(light, result);
|
|
197
197
|
}
|
|
198
198
|
}
|
|
199
199
|
|
|
200
|
-
fn
|
|
200
|
+
fn mG(iZ: vec2f, lightSample: ptr<function, LightSampleRec>) {
|
|
201
201
|
var uv: vec2f;
|
|
202
|
-
(*lightSample).direction =
|
|
202
|
+
(*lightSample).direction = oL(iZ, &uv, &(*lightSample).pdf);
|
|
203
203
|
(*lightSample).emission = textureLinear(envMap, uv).rgb;
|
|
204
204
|
(*lightSample).dist = INF;
|
|
205
205
|
}
|
|
206
206
|
|
|
207
|
-
fn bV(
|
|
207
|
+
fn bV(im: i32) -> vec4f {
|
|
208
208
|
let width = rtUniform.lightSamplingTextureWidth;
|
|
209
209
|
return textureLoad(
|
|
210
210
|
lightSamplingData,
|
|
211
|
-
vec2i(
|
|
211
|
+
vec2i(im % width, im / width),
|
|
212
212
|
0
|
|
213
213
|
);
|
|
214
214
|
}
|
|
215
215
|
|
|
216
|
-
fn
|
|
216
|
+
fn qd(index: i32) -> EmissiveTriangle {
|
|
217
217
|
let offset = index * 6;
|
|
218
218
|
let a = bV(offset);
|
|
219
219
|
let b = bV(offset + 1);
|
|
@@ -230,9 +230,9 @@ e.zw, f.xy, f.zw
|
|
|
230
230
|
);
|
|
231
231
|
}
|
|
232
232
|
|
|
233
|
-
fn
|
|
233
|
+
fn sp(index: i32) -> pe {
|
|
234
234
|
let data = bV(rtUniform.lightChoiceTexelOffset + index);
|
|
235
|
-
return
|
|
235
|
+
return pe(
|
|
236
236
|
data.x,
|
|
237
237
|
bitcast<i32>(data.y),
|
|
238
238
|
bitcast<i32>(data.z),
|
|
@@ -240,35 +240,35 @@ bitcast<i32>(data.w)
|
|
|
240
240
|
);
|
|
241
241
|
}
|
|
242
242
|
|
|
243
|
-
fn
|
|
244
|
-
return
|
|
243
|
+
fn jB(nd: i32, index: i32) -> pe {
|
|
244
|
+
return sp(nd + index);
|
|
245
245
|
}
|
|
246
246
|
|
|
247
|
-
fn
|
|
247
|
+
fn mS(
|
|
248
248
|
rnd: vec3f,
|
|
249
249
|
ca: u32,
|
|
250
|
-
|
|
250
|
+
aV: u32
|
|
251
251
|
) -> vec3f {
|
|
252
|
-
var
|
|
253
|
-
let count = max(
|
|
254
|
-
|
|
252
|
+
var sU = rnd;
|
|
253
|
+
let count = max(aV, 1u);
|
|
254
|
+
sU.z = (rnd.z + f32(min(ca, count - 1u))) /
|
|
255
255
|
f32(count);
|
|
256
|
-
return
|
|
256
|
+
return sU;
|
|
257
257
|
}
|
|
258
258
|
|
|
259
|
-
fn
|
|
259
|
+
fn lW(
|
|
260
260
|
triangle: EmissiveTriangle,
|
|
261
|
-
|
|
262
|
-
|
|
261
|
+
ft: vec3f,
|
|
262
|
+
iZ: vec2f,
|
|
263
263
|
lightSample: ptr<function, LightSampleRec>
|
|
264
264
|
) {
|
|
265
|
-
let
|
|
265
|
+
let vC = sqrt(iZ.x);
|
|
266
266
|
let barycentric = vec3f(
|
|
267
|
-
1.0 -
|
|
268
|
-
|
|
269
|
-
|
|
267
|
+
1.0 - vC,
|
|
268
|
+
vC * (1.0 - iZ.y),
|
|
269
|
+
vC * iZ.y
|
|
270
270
|
);
|
|
271
|
-
let
|
|
271
|
+
let sZ =
|
|
272
272
|
barycentric.x * triangle.p0 +
|
|
273
273
|
barycentric.y * triangle.p1 +
|
|
274
274
|
barycentric.z * triangle.p2;
|
|
@@ -281,7 +281,7 @@ barycentric.x * triangle.secondaryUv0 +
|
|
|
281
281
|
barycentric.y * triangle.secondaryUv1 +
|
|
282
282
|
barycentric.z * triangle.secondaryUv2;
|
|
283
283
|
let normal = normalize(cross(triangle.p1 - triangle.p0, triangle.p2 - triangle.p0));
|
|
284
|
-
(*lightSample).direction =
|
|
284
|
+
(*lightSample).direction = sZ - ft;
|
|
285
285
|
(*lightSample).dist = length((*lightSample).direction);
|
|
286
286
|
if ((*lightSample).dist <= EPS) {
|
|
287
287
|
(*lightSample).emission = vec3f(0.0);
|
|
@@ -290,27 +290,27 @@ return;
|
|
|
290
290
|
}
|
|
291
291
|
(*lightSample).direction /= (*lightSample).dist;
|
|
292
292
|
(*lightSample).normal = normal;
|
|
293
|
-
let
|
|
294
|
-
if (
|
|
293
|
+
let pm = dot(normal, -(*lightSample).direction);
|
|
294
|
+
if (pm <= 0.0) {
|
|
295
295
|
(*lightSample).emission = vec3f(0.0);
|
|
296
296
|
(*lightSample).pdf = 0.0;
|
|
297
297
|
return;
|
|
298
298
|
}
|
|
299
|
-
(*lightSample).emission =
|
|
299
|
+
(*lightSample).emission = lN(
|
|
300
300
|
i32(triangle.materialIndex), uv, cX
|
|
301
301
|
);
|
|
302
302
|
(*lightSample).selectionPmf = triangle.selectionPmf;
|
|
303
303
|
(*lightSample).pdf = triangle.selectionPmf *
|
|
304
304
|
((*lightSample).dist * (*lightSample).dist) /
|
|
305
|
-
max(triangle.area *
|
|
305
|
+
max(triangle.area * pm, 1e-8);
|
|
306
306
|
}
|
|
307
307
|
|
|
308
|
-
fn
|
|
309
|
-
|
|
308
|
+
fn ki(
|
|
309
|
+
ft: vec3f,
|
|
310
310
|
rnd: vec3f,
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
311
|
+
nd: i32,
|
|
312
|
+
pl: i32,
|
|
313
|
+
mZ: f32,
|
|
314
314
|
lightSample: ptr<function, LightSampleRec>
|
|
315
315
|
) {
|
|
316
316
|
(*lightSample).emission = vec3f(0.0);
|
|
@@ -320,56 +320,56 @@ lightSample: ptr<function, LightSampleRec>
|
|
|
320
320
|
(*lightSample).isDelta = false;
|
|
321
321
|
(*lightSample).sourceType = 0u;
|
|
322
322
|
(*lightSample).sourceIndex = 0xffffffffu;
|
|
323
|
-
if (
|
|
323
|
+
if (pl <= 0) {
|
|
324
324
|
return;
|
|
325
325
|
}
|
|
326
326
|
|
|
327
|
-
let
|
|
328
|
-
let column = min(i32(
|
|
329
|
-
let
|
|
330
|
-
let
|
|
331
|
-
|
|
327
|
+
let rj = rnd.z * f32(pl);
|
|
328
|
+
let column = min(i32(rj), pl - 1);
|
|
329
|
+
let qS = jB(nd, column);
|
|
330
|
+
let lc = select(
|
|
331
|
+
qS.aliasIndex,
|
|
332
332
|
column,
|
|
333
|
-
fract(
|
|
333
|
+
fract(rj) < qS.probability
|
|
334
334
|
);
|
|
335
|
-
let
|
|
336
|
-
if (
|
|
335
|
+
let pk = jB(nd, lc);
|
|
336
|
+
if (pk.sourceType == ${LIGHT_CHOICE_ENVIRONMENT}) {
|
|
337
337
|
(*lightSample).sourceType = 0u;
|
|
338
|
-
(*lightSample).sourceIndex = u32(
|
|
339
|
-
|
|
338
|
+
(*lightSample).sourceIndex = u32(pk.sourceIndex);
|
|
339
|
+
mG(rnd.xy, lightSample);
|
|
340
340
|
(*lightSample).selectionPmf = rtUniform.envLightPmf;
|
|
341
341
|
(*lightSample).pdf *= rtUniform.envLightPmf;
|
|
342
342
|
}
|
|
343
|
-
else if (
|
|
343
|
+
else if (pk.sourceType == ${LIGHT_CHOICE_ANALYTIC}) {
|
|
344
344
|
(*lightSample).sourceType = 2u;
|
|
345
|
-
(*lightSample).sourceIndex = u32(
|
|
346
|
-
let light = analyticLights[
|
|
347
|
-
|
|
345
|
+
(*lightSample).sourceIndex = u32(pk.sourceIndex);
|
|
346
|
+
let light = analyticLights[pk.sourceIndex];
|
|
347
|
+
iQ(light, ft, rnd.xy, lightSample);
|
|
348
348
|
(*lightSample).selectionPmf = light.selectionPmf;
|
|
349
349
|
(*lightSample).pdf *= light.selectionPmf;
|
|
350
350
|
}
|
|
351
|
-
else if (
|
|
351
|
+
else if (pk.sourceType == ${LIGHT_CHOICE_EMISSIVE_TRIANGLE}) {
|
|
352
352
|
(*lightSample).sourceType = 1u;
|
|
353
|
-
(*lightSample).sourceIndex = u32(
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
353
|
+
(*lightSample).sourceIndex = u32(pk.sourceIndex);
|
|
354
|
+
lW(
|
|
355
|
+
qd(pk.sourceIndex),
|
|
356
|
+
ft,
|
|
357
357
|
rnd.xy,
|
|
358
358
|
lightSample
|
|
359
359
|
);
|
|
360
360
|
}
|
|
361
|
-
(*lightSample).selectionPmf *=
|
|
362
|
-
(*lightSample).pdf *=
|
|
361
|
+
(*lightSample).selectionPmf *= mZ;
|
|
362
|
+
(*lightSample).pdf *= mZ;
|
|
363
363
|
}
|
|
364
364
|
|
|
365
365
|
fn sampleLight(
|
|
366
|
-
|
|
366
|
+
ft: vec3f,
|
|
367
367
|
rnd: vec3f,
|
|
368
368
|
lightSample: ptr<function, LightSampleRec>,
|
|
369
|
-
|
|
369
|
+
sc: bool
|
|
370
370
|
) {
|
|
371
|
-
|
|
372
|
-
|
|
371
|
+
ki(
|
|
372
|
+
ft,
|
|
373
373
|
rnd,
|
|
374
374
|
0,
|
|
375
375
|
rtUniform.lightChoiceCount,
|
|
@@ -380,16 +380,16 @@ lightSample
|
|
|
380
380
|
|
|
381
381
|
|
|
382
382
|
|
|
383
|
-
fn
|
|
384
|
-
|
|
383
|
+
fn mH(
|
|
384
|
+
ft: vec3f,
|
|
385
385
|
rnd: vec3f,
|
|
386
386
|
ca: u32,
|
|
387
|
-
|
|
387
|
+
aV: u32,
|
|
388
388
|
lightSample: ptr<function, LightSampleRec>
|
|
389
389
|
) {
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
390
|
+
ki(
|
|
391
|
+
ft,
|
|
392
|
+
mS(rnd, ca, aV),
|
|
393
393
|
0,
|
|
394
394
|
rtUniform.lightChoiceCount,
|
|
395
395
|
1.0,
|