three-base 2.0.169 → 2.0.175
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/FPScontrol.d.ts +55 -30
- package/FPScontrol.js +278 -225
- package/FPScontrol.ts +177 -127
- package/Ground1/Ground1.d.ts +4 -2
- package/Ground1/Ground1.js +77 -57
- package/Ground1/Ground1.ts +77 -57
- package/Mirror.js +0 -4
- package/Mirror.ts +0 -4
- package/MktMesh/MktMesh.d.ts +8 -3
- package/MktMesh/MktMesh.js +43 -14
- package/MktMesh/MktMesh.ts +40 -14
- package/MktMesh/mktMappingShader.d.ts +6 -5
- package/MktMesh/mktMappingShader.js +26 -19
- package/MktMesh/mktMappingShader.ts +28 -19
- package/MktMesh/mktShader.d.ts +127 -58
- package/MktMesh/mktShader.js +192 -117
- package/MktMesh/mktShader.ts +251 -127
- package/MktMesh/panoSlotRoster.d.ts +2 -2
- package/MktMesh/panoSlotRoster.js +9 -7
- package/MktMesh/panoSlotRoster.ts +9 -7
- package/MktMesh/panoTileStitcher.d.ts +20 -13
- package/MktMesh/panoTileStitcher.js +97 -76
- package/MktMesh/panoTileStitcher.ts +119 -90
- package/MktMesh/types.d.ts +5 -1
- package/MktMesh/types.ts +5 -1
- package/PipeMesh/PipeJoint.d.ts +22 -0
- package/PipeMesh/PipeJoint.js +33 -0
- package/PipeMesh/PipeJoint.ts +38 -0
- package/PipeMesh/PipeMesh.d.ts +94 -22
- package/PipeMesh/PipeMesh.js +192 -53
- package/PipeMesh/PipeMesh.ts +223 -76
- package/PipeMesh/PipeStraight.d.ts +19 -0
- package/PipeMesh/PipeStraight.js +34 -0
- package/PipeMesh/PipeStraight.ts +45 -0
- package/PipeMesh/axisSnap.d.ts +52 -0
- package/PipeMesh/axisSnap.js +52 -0
- package/PipeMesh/axisSnap.ts +93 -0
- package/PipeMesh/directRoute.d.ts +85 -0
- package/PipeMesh/directRoute.js +126 -0
- package/PipeMesh/directRoute.ts +190 -0
- package/PipeMesh/index.d.ts +6 -0
- package/PipeMesh/index.js +6 -0
- package/PipeMesh/index.ts +7 -1
- package/PipeMesh/pipeMaterial.d.ts +16 -0
- package/PipeMesh/pipeMaterial.js +23 -0
- package/PipeMesh/pipeMaterial.ts +26 -0
- package/ThreeBase.d.ts +2 -49
- package/ThreeBase.js +43 -164
- package/ThreeBase.ts +1176 -1314
- package/instanced/InstancedBatch.d.ts +14 -1
- package/instanced/InstancedBatch.js +53 -3
- package/instanced/InstancedBatch.ts +62 -3
- package/instanced/InstancedChild.d.ts +24 -0
- package/instanced/InstancedChild.js +40 -0
- package/instanced/InstancedChild.ts +41 -0
- package/instanced/InstancedGroup.d.ts +48 -0
- package/instanced/InstancedGroup.js +45 -1
- package/instanced/InstancedGroup.ts +85 -0
- package/package.json +2 -7
- package/pass/bloom_pass.js +7 -14
- package/pass/bloom_pass.ts +7 -16
- package/pass/cover_pass.js +7 -15
- package/pass/cover_pass.ts +7 -17
- package/pass/debugDepthState.d.ts +16 -8
- package/pass/debugDepthState.js +4 -0
- package/pass/debugDepthState.ts +27 -9
- package/pass/glow_pass.js +19 -110
- package/pass/glow_pass.ts +19 -115
- package/pass/ssao_pass.d.ts +14 -59
- package/pass/ssao_pass.js +66 -171
- package/pass/ssao_pass.ts +63 -207
- package/pass/stroke_pass.js +13 -16
- package/pass/stroke_pass.ts +14 -18
- package/shaders/baseDepthVisShader.d.ts +1 -1
- package/shaders/baseDepthVisShader.js +1 -1
- package/shaders/baseDepthVisShader.ts +1 -1
- package/shaders/debugDepthCompareShader.d.ts +2 -2
- package/shaders/debugDepthCompareShader.js +2 -2
- package/shaders/debugDepthCompareShader.ts +2 -2
- package/shaders/debugDepthJudgeShader.d.ts +1 -1
- package/shaders/debugDepthJudgeShader.js +1 -1
- package/shaders/debugDepthJudgeShader.ts +1 -1
- package/PipeMesh/PathGeometry.d.ts +0 -44
- package/PipeMesh/PathGeometry.js +0 -307
- package/PipeMesh/PathGeometry.ts +0 -343
- package/PipeMesh/PathPoint.d.ts +0 -17
- package/PipeMesh/PathPoint.js +0 -31
- package/PipeMesh/PathPoint.ts +0 -36
- package/PipeMesh/PathPointList.d.ts +0 -31
- package/PipeMesh/PathPointList.js +0 -209
- package/PipeMesh/PathPointList.ts +0 -227
- package/PipeMesh/PathTubeGeometry.d.ts +0 -25
- package/PipeMesh/PathTubeGeometry.js +0 -130
- package/PipeMesh/PathTubeGeometry.ts +0 -146
- package/WaterFlow/FloatingDuck.d.ts +0 -88
- package/WaterFlow/FloatingDuck.js +0 -307
- package/WaterFlow/FloatingDuck.ts +0 -445
- package/WaterFlow/GPUFluidSimulation.d.ts +0 -56
- package/WaterFlow/GPUFluidSimulation.js +0 -785
- package/WaterFlow/GPUFluidSimulation.ts +0 -827
- package/WaterFlow/ReservoirSystem.d.ts +0 -106
- package/WaterFlow/ReservoirSystem.js +0 -621
- package/WaterFlow/ReservoirSystem.ts +0 -754
- package/WaterFlow/SPHField.d.ts +0 -35
- package/WaterFlow/SPHField.js +0 -204
- package/WaterFlow/SPHField.ts +0 -228
- package/WaterFlow/ScreenSpaceFluidPass.d.ts +0 -69
- package/WaterFlow/ScreenSpaceFluidPass.js +0 -736
- package/WaterFlow/ScreenSpaceFluidPass.ts +0 -789
- package/WaterFlow/ShallowWaterSurface.d.ts +0 -45
- package/WaterFlow/ShallowWaterSurface.js +0 -441
- package/WaterFlow/ShallowWaterSurface.ts +0 -510
- package/WaterFlow/WaterFlow.d.ts +0 -87
- package/WaterFlow/WaterFlow.js +0 -171
- package/WaterFlow/WaterFlow.ts +0 -219
- package/WaterFlow/types.d.ts +0 -161
- package/WaterFlow/types.js +0 -1
- package/WaterFlow/types.ts +0 -189
- package/WaterFlow/waterFlowPass.d.ts +0 -3
- package/WaterFlow/waterFlowPass.js +0 -20
- package/WaterFlow/waterFlowPass.ts +0 -40
- package/shaders/debugExcludedShader.d.ts +0 -13
- package/shaders/debugExcludedShader.js +0 -46
- package/shaders/debugExcludedShader.ts +0 -48
package/pass/glow_pass.ts
CHANGED
|
@@ -17,25 +17,19 @@ const selectDepthTexture: DepthTexture = (() => {
|
|
|
17
17
|
return baseDepthTexture;
|
|
18
18
|
})();
|
|
19
19
|
|
|
20
|
+
// ⭐ 2026-10-11 皇上旨「简化渲染」:selectDepthTexture 挂在本目标上当 depth attachment,
|
|
21
|
+
// mask 那一趟光栅化顺带写出本体深度 ⇒ 原来为同一对象再渲一趟「只出深度」整条删除。
|
|
20
22
|
const selectTextureTarget: WebGLRenderTarget = new WebGLRenderTarget(1024, 1024, {
|
|
21
23
|
minFilter: LinearFilter,
|
|
22
24
|
magFilter: LinearFilter,
|
|
23
25
|
format: RGBAFormat,
|
|
26
|
+
depthTexture: selectDepthTexture,
|
|
24
27
|
anisotropy: 16,
|
|
25
|
-
// 无 MSAA:mask
|
|
28
|
+
// 无 MSAA:mask 颜色与它顺带写入的深度必须同为硬边缘,
|
|
26
29
|
// 否则 mask 边缘平滑而深度硬 → depthTestShader 判定边界与 mask 视觉边缘错位,辉光边缘锯齿。
|
|
27
30
|
// 边缘抗锯齿统一由 mask 内部 FXAA + 终处理 FXAA 兜底。
|
|
28
31
|
});
|
|
29
32
|
|
|
30
|
-
// 无 MSAA 的深度专用目标:仅用于导出对象深度,供 depthTestShader 做遮挡判定(深度无需抗锯齿)
|
|
31
|
-
const selectDepthTextureTarget: WebGLRenderTarget = new WebGLRenderTarget(1024, 1024, {
|
|
32
|
-
minFilter: LinearFilter,
|
|
33
|
-
magFilter: LinearFilter,
|
|
34
|
-
format: RGBAFormat,
|
|
35
|
-
depthTexture: selectDepthTexture,
|
|
36
|
-
anisotropy: 16,
|
|
37
|
-
});
|
|
38
|
-
|
|
39
33
|
const selectDepthTestTextureTarget: WebGLRenderTarget = new WebGLRenderTarget(1024, 1024, {
|
|
40
34
|
minFilter: LinearFilter,
|
|
41
35
|
magFilter: LinearFilter,
|
|
@@ -56,24 +50,13 @@ const blur2TextureTarget: WebGLRenderTarget = new WebGLRenderTarget(1024, 1024,
|
|
|
56
50
|
format: RGBAFormat,
|
|
57
51
|
});
|
|
58
52
|
|
|
59
|
-
//
|
|
60
|
-
//
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const selectDepthBlurTextureTarget: WebGLRenderTarget = new WebGLRenderTarget(1024, 1024, {
|
|
67
|
-
minFilter: LinearFilter,
|
|
68
|
-
magFilter: LinearFilter,
|
|
69
|
-
format: RGBAFormat,
|
|
70
|
-
});
|
|
71
|
-
// 外扩辉光经深度测试后的结果(步骤 5.6):独立 target,避免回写 blur1 触发历史回归 bug
|
|
72
|
-
const blurDepthTestTextureTarget: WebGLRenderTarget = new WebGLRenderTarget(1024, 1024, {
|
|
73
|
-
minFilter: LinearFilter,
|
|
74
|
-
magFilter: LinearFilter,
|
|
75
|
-
format: RGBAFormat,
|
|
76
|
-
});
|
|
53
|
+
// ⭐ 2026-10-25 皇上旨「步骤 5.6 外扩辉光再判遮挡 不要这不」:
|
|
54
|
+
// 原「步骤 5.5 深度外扩(min-blur)+ 5.6 外扩辉光再判遮挡」整段删除,连同
|
|
55
|
+
// selectDepthBlurTmp / selectDepthBlur / blurDepthTest 三个 RT 与 depthMinBlurShader。
|
|
56
|
+
// 原因:min-blur 的膨胀窗口是 ±10×radius 的方形(radius = glow_width×2,与单趟高斯采样步长同源),
|
|
57
|
+
// 而模糊迭代 N 次后等效扩散按 σ√N 增长 ⇒ 窗口外那圈光的 selD 仍是「背景 1.0」,
|
|
58
|
+
// 被 baseD(天空 0.9) < selD(1.0) 判成「被挡住」→ discard → 光晕被硬切一刀。
|
|
59
|
+
// 代价(已知并接受):物体被更近的物体挡住时,辉光不再从遮挡物前方被裁掉,会透出来。
|
|
77
60
|
|
|
78
61
|
const size: Vector2 = new Vector2();
|
|
79
62
|
|
|
@@ -222,53 +205,6 @@ const gaussianBlurVShader: RawShaderMaterial = new RawShaderMaterial({
|
|
|
222
205
|
transparent: true,
|
|
223
206
|
});
|
|
224
207
|
|
|
225
|
-
// 深度 min-blur(最近深度,忽略背景 1.0):随 mask 一起把深度图向外扩,
|
|
226
|
-
// 外扩区 selD = 物体最近深度(<1.0) 而非清屏 1.0,depthTest 在外扩区才能正确判遮挡(不漏光),
|
|
227
|
-
// 同时本体区仍靠 depthTestShader 的 EPSILON 容差防自遮挡闪烁(无缝)。separable(direction 控制 H/V)。
|
|
228
|
-
const depthMinBlurShader: ShaderMaterial = new ShaderMaterial({
|
|
229
|
-
uniforms: {
|
|
230
|
-
tDepth: { value: null },
|
|
231
|
-
resolution: { value: new Vector2(1 / 512, 1 / 512) },
|
|
232
|
-
radius: { value: 1.0 },
|
|
233
|
-
direction: { value: new Vector2(1, 0) },
|
|
234
|
-
},
|
|
235
|
-
vertexShader: `
|
|
236
|
-
${ShaderChunk.common}
|
|
237
|
-
${ShaderChunk.logdepthbuf_pars_vertex}
|
|
238
|
-
varying vec2 vUv;
|
|
239
|
-
void main() {
|
|
240
|
-
vUv = uv;
|
|
241
|
-
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
242
|
-
${ShaderChunk.logdepthbuf_vertex}
|
|
243
|
-
}
|
|
244
|
-
`,
|
|
245
|
-
fragmentShader: `
|
|
246
|
-
${ShaderChunk.logdepthbuf_pars_fragment}
|
|
247
|
-
uniform sampler2D tDepth;
|
|
248
|
-
uniform vec2 resolution;
|
|
249
|
-
uniform float radius;
|
|
250
|
-
uniform vec2 direction;
|
|
251
|
-
varying vec2 vUv;
|
|
252
|
-
void main() {
|
|
253
|
-
float minD = 1.0;
|
|
254
|
-
for (int i = -10; i <= 10; i++) {
|
|
255
|
-
float x = float(i);
|
|
256
|
-
vec2 off = direction * (x * radius * resolution);
|
|
257
|
-
float d = texture2D(tDepth, vUv + off).r;
|
|
258
|
-
if (d < 0.9999) {
|
|
259
|
-
minD = min(minD, d);
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
gl_FragColor = vec4(minD, 0.0, 0.0, 1.0);
|
|
263
|
-
${ShaderChunk.logdepthbuf_fragment}
|
|
264
|
-
}
|
|
265
|
-
`,
|
|
266
|
-
blending: NoBlending,
|
|
267
|
-
depthTest: false,
|
|
268
|
-
depthWrite: false,
|
|
269
|
-
transparent: true,
|
|
270
|
-
});
|
|
271
|
-
|
|
272
208
|
const glowCompositeShader: RawShaderMaterial = new RawShaderMaterial({
|
|
273
209
|
uniforms: {
|
|
274
210
|
tDiffuse: { value: null },
|
|
@@ -521,7 +457,6 @@ export default function glow_pass(
|
|
|
521
457
|
renderer.getSize(size);
|
|
522
458
|
size.multiplyScalar(devicePixelRatio);
|
|
523
459
|
selectTextureTarget.setSize(size.x, size.y);
|
|
524
|
-
selectDepthTextureTarget.setSize(size.x, size.y);
|
|
525
460
|
// 缺陷修复:three r167 的 WebGLRenderTarget.setSize 不会同步 depthTexture,
|
|
526
461
|
// 需手动把 selectDepthTexture 尺寸与全屏 baseDepth 对齐,否则深度比例错位导致辉光被错误 discard
|
|
527
462
|
selectDepthTexture.image.width = size.x;
|
|
@@ -530,21 +465,15 @@ export default function glow_pass(
|
|
|
530
465
|
selectDepthTestTextureTarget.setSize(size.x, size.y);
|
|
531
466
|
blur1TextureTarget.setSize(size.x, size.y);
|
|
532
467
|
blur2TextureTarget.setSize(size.x, size.y);
|
|
533
|
-
selectDepthBlurTmpTextureTarget.setSize(size.x, size.y);
|
|
534
|
-
selectDepthBlurTextureTarget.setSize(size.x, size.y);
|
|
535
|
-
blurDepthTestTextureTarget.setSize(size.x, size.y);
|
|
536
468
|
|
|
537
|
-
// 1. 渲染物体本体 mask
|
|
469
|
+
// 1. 渲染物体本体 mask(灰度)。⭐ 本体深度由同一趟光栅化顺带写进 selectDepthTexture
|
|
470
|
+
// (挂在 selectTextureTarget 的 depth attachment 上);原先的第 2 趟「只渲深度」(供 min-blur
|
|
471
|
+
// 外扩用)与这趟同材质/同相机/同几何 ⇒ 深度逐位相同,2026-10-11 皇上旨简化时删除。
|
|
472
|
+
// (下面的步骤编号保留 3/4/5…,别处注释按号交叉引用,不随之重排。)
|
|
538
473
|
renderer.setRenderTarget(selectTextureTarget);
|
|
539
474
|
scene.children = [object3d];
|
|
540
475
|
renderer.clear();
|
|
541
476
|
renderer.render(scene, camera);
|
|
542
|
-
|
|
543
|
-
// 2. 渲染物体本体深度(无 MSAA,供 min-blur 外扩用)
|
|
544
|
-
renderer.setRenderTarget(selectDepthTextureTarget);
|
|
545
|
-
scene.children = [object3d];
|
|
546
|
-
renderer.clear();
|
|
547
|
-
renderer.render(scene, camera);
|
|
548
477
|
// 调试:把本次渲染的选区深度记到全局调试状态,供面板「辉光深度比对」读取
|
|
549
478
|
debugDepthState.lastSelectDepth = selectDepthTexture;
|
|
550
479
|
|
|
@@ -597,38 +526,13 @@ export default function glow_pass(
|
|
|
597
526
|
glowCompositeShader.uniforms.intensity.value = glow_intensity;
|
|
598
527
|
fsQuad.render(renderer, glowCompositeShader);
|
|
599
528
|
|
|
600
|
-
//
|
|
601
|
-
//
|
|
602
|
-
// 再用它对外扩后的辉光做一次 depthTest —— 否则外扩环永远不参与遮挡判定,
|
|
603
|
-
// 物体被挡住时辉光依旧从遮挡物前方漏出来。
|
|
604
|
-
depthMinBlurShader.uniforms.resolution.value.set(1 / size.x, 1 / size.y);
|
|
605
|
-
depthMinBlurShader.uniforms.radius.value = Math.max(1, blurRadius);
|
|
606
|
-
depthMinBlurShader.uniforms.direction.value.set(1, 0);
|
|
607
|
-
depthMinBlurShader.uniforms.tDepth.value = selectDepthTexture;
|
|
608
|
-
renderer.setRenderTarget(selectDepthBlurTmpTextureTarget);
|
|
609
|
-
renderer.clear();
|
|
610
|
-
fsQuad.render(renderer, depthMinBlurShader);
|
|
611
|
-
depthMinBlurShader.uniforms.direction.value.set(0, 1);
|
|
612
|
-
depthMinBlurShader.uniforms.tDepth.value = selectDepthBlurTmpTextureTarget.texture;
|
|
613
|
-
renderer.setRenderTarget(selectDepthBlurTextureTarget);
|
|
614
|
-
renderer.clear();
|
|
615
|
-
fsQuad.render(renderer, depthMinBlurShader);
|
|
616
|
-
|
|
617
|
-
// 5.6 对外扩后的辉光判遮挡(输出到独立 target,绝不回写 blur1,避免步骤 6 相减归零)
|
|
618
|
-
renderer.setRenderTarget(blurDepthTestTextureTarget);
|
|
619
|
-
renderer.clear();
|
|
620
|
-
depthTestShader.uniforms.map.value = blur1TextureTarget.texture;
|
|
621
|
-
depthTestShader.uniforms.baseDepth.value = baseDepthTexture;
|
|
622
|
-
depthTestShader.uniforms.selectDepth.value = selectDepthBlurTextureTarget.texture;
|
|
623
|
-
depthTestShader.uniforms.cameraFar.value = (camera as PerspectiveCamera).far;
|
|
624
|
-
fsQuad.render(renderer, depthTestShader);
|
|
625
|
-
|
|
626
|
-
// 6. 合成到屏幕:filterSelect(blur=上色后且已判遮挡的最终外扩辉光, select=深度测试后本体辉光)
|
|
627
|
-
// = 仅保留辉光外扩环;本体被减掉。⚠️ blur 必须是最终外扩辉光,绝不能被 depthTest 结果覆盖
|
|
529
|
+
// 6. 合成到屏幕:filterSelect(blur=上色后的外扩辉光 blur1, select=深度测试后本体辉光)
|
|
530
|
+
// = 仅保留辉光外扩环;本体被减掉。⚠️ blur 必须是上色后的 blur1,绝不能被别的结果覆盖
|
|
628
531
|
// (早期回归:误把 depthTest 结果上色进 blur1 → filterSelect 相减归零 → 辉光全不显示)。
|
|
532
|
+
// ⭐ 2026-10-25 起外扩环不再做第二次遮挡判定(皇上旨删 5.6),blur1 直接就是最终辉光。
|
|
629
533
|
renderer.setRenderTarget(originRenderTarget);
|
|
630
534
|
filterSelectShader.uniforms.selectTexture.value = selectDepthTestTextureTarget.texture;
|
|
631
|
-
filterSelectShader.uniforms.blurTexture.value =
|
|
535
|
+
filterSelectShader.uniforms.blurTexture.value = blur1TextureTarget.texture;
|
|
632
536
|
filterSelectShader.uniforms.opacity.value = glow_opacity;
|
|
633
537
|
// glow_additive=true 时用加性混合,光晕叠加到画面呈发光感(很亮那种);否则普通半透明覆盖(默认)
|
|
634
538
|
filterSelectShader.blending = glow_additive ? AdditiveBlending : NormalBlending;
|
package/pass/ssao_pass.d.ts
CHANGED
|
@@ -1,67 +1,22 @@
|
|
|
1
1
|
import { MeshNormalMaterial, Scene, WebGLRenderTarget, WebGLRenderer, Camera } from "three";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* 法线写进去(近)→ 深度与法线指的不是同一个点 → GTAO 几乎必然算错发黑。
|
|
11
|
-
* 故深度 pass 与法线 pass 统一隐藏:该像素的深度/法线即身后不透明几何,AO 由真实可见几何
|
|
12
|
-
* 决定;身后是背景时深度为 1.0,shader 守卫直接判「无遮蔽」(=1),不会发黑。
|
|
13
|
-
*
|
|
14
|
-
* 判据只看 material.transparent 本身,不再依赖 opacity / depthWrite(2026-08-30 修正):
|
|
15
|
-
* 大量半透明是自定义 ShaderMaterial,alpha 由 shader 算出来,而材质的 opacity 仍是默认 1、
|
|
16
|
-
* depthWrite 仍是 true —— 典型如 Ground1 地板(mapColor.a 径向渐变)、聚光灯光斑、
|
|
17
|
-
* effectMaterial1,靠材质属性完全读不出来,会被漏判并继续污染 AO。
|
|
18
|
-
* 代价:Mirror 这类「标了 transparent 但 shader 实际输出 alpha=1.0」的实心反射面会被误排除,
|
|
19
|
-
* 故 Mirror 在构造函数里显式标记 userData.aoOpaque = true 保留(见各 Mirror 实现)。
|
|
20
|
-
* 其余特例同样可用 userData.aoTransparent=true 强制排除 / userData.aoOpaque=true 强制保留。
|
|
21
|
-
*
|
|
22
|
-
* @param includeFloor 是否为「含地板」的 AO 数据准备(GTAO 深度/法线)。
|
|
23
|
-
* - false(默认,可见深度 / 描边/辉光/毛玻璃遮挡判定):地板按普通半透明排除。
|
|
24
|
-
* - true(AO 深度):标了 userData.aoFloor 的地板保留为实体,参与接触 AO 计算。
|
|
3
|
+
* 可见深度 pass:用**各物体自身的材质**把整个场景的深度渲染到 depthRenderTarget。
|
|
4
|
+
* depthRenderTarget.depthTexture 即 baseDepthTexture,供描边 / 发光 / 覆盖 / 磨砂的遮挡判定,
|
|
5
|
+
* 也是 SSAO 合成时「真实可见表面」的参考。
|
|
6
|
+
* 2026-10-18 起**不排除任何对象**(皇上旨「所有的对象都要进入到深度图里面了,不需要用参数过滤掉了」):
|
|
7
|
+
* 场景里所有对象都参与这一趟,只有使用者自己 `visible = false` 的对象除外(那是显隐意图,本 pass 不碰)。
|
|
8
|
+
* ⚠️ 名字里的 ao 已不适用(2026-10-11 改名自 renderAoDepthPass):它产出的是**可见深度**,
|
|
9
|
+
* AO 自己的深度挂在法线 pass 上(见 renderAoNormalPass)。
|
|
25
10
|
*/
|
|
11
|
+
export declare function renderVisibleDepthPass(renderer: WebGLRenderer, camera: Camera, scene: Scene, depthRenderTarget: WebGLRenderTarget): void;
|
|
26
12
|
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* 只影响 aoFloor 地板这一类;transparent 面的处理不受影响(见 isSeeThroughSurface)。
|
|
13
|
+
* 法线 pass(仅 SSAO 开启时需要):以中性灰清屏 + normalMaterial override 将整个场景的
|
|
14
|
+
* 视图空间法线渲染到 normalRenderTarget,供 GTAO 风格 SSAO 使用。
|
|
15
|
+
* 2026-10-18 起同样不排除任何对象(与 renderVisibleDepthPass 一致,见文件头那道旨及其代价清单)。
|
|
16
|
+
* 深度白拿:normalRenderTarget 挂着 aoDepthTexture 作 depth attachment,这一趟的深度由光栅器
|
|
17
|
+
* 顺带写入 → 就是 AO 用的深度,无需再单独渲一遍(2026-09-14)。
|
|
34
18
|
*/
|
|
35
|
-
export declare
|
|
36
|
-
includeFloor: boolean;
|
|
37
|
-
};
|
|
38
|
-
/**
|
|
39
|
-
* 深度 pass:固定排除非实体表面后,将场景深度渲染到 depthRenderTarget。
|
|
40
|
-
* depthRenderTarget.depthTexture 即 baseDepthTexture,供 SSAO / 描边 / 发光等后续 pass 复用。
|
|
41
|
-
* 排除的非实体对象(sprite/线条/点)在深度图保留 clear 深度(1.0=远),与背景一致;排除的
|
|
42
|
-
* 半透明对象则保留其身后不透明几何的深度(身后无几何时同样为 1.0)。均不影响颜色通道渲染。
|
|
43
|
-
*/
|
|
44
|
-
export declare function renderAoDepthPass(renderer: WebGLRenderer, camera: Camera, scene: Scene, depthRenderTarget: WebGLRenderTarget, includeFloor?: boolean): void;
|
|
45
|
-
/**
|
|
46
|
-
* 调试用:把「被排除出可见深度图」的表面单独渲成红色 mask。
|
|
47
|
-
*
|
|
48
|
-
* 这些面在 renderAoDepthPass 里被 hideNonSurface 隐藏,因此**不会写进 baseDepthTexture**,
|
|
49
|
-
* 也就永远挡不住描边/辉光/毛玻璃/覆盖色 —— 这正是"深度测试看起来失效"最常见的成因
|
|
50
|
-
* (用户以为是 bug,其实是该面被设计成可透视:sprite/线条/点、userData.aoTransparent、
|
|
51
|
-
* 以及标了 userData.aoFloor 的地板 Ground1)。
|
|
52
|
-
* 面板「深度调试 → 排除面标记」叠加显示:灰=能挡住的真实遮挡面,红=被排除、挡不住任何东西。
|
|
53
|
-
*
|
|
54
|
-
* 只渲染 Mesh:sprite / Line2 / Points 在 MeshBasicMaterial override 下渲染异常(见文件头注释),
|
|
55
|
-
* 且它们数量少、用户关心的遮挡体基本都是 Mesh,故跳过。
|
|
56
|
-
*/
|
|
57
|
-
export declare function renderExcludedMaskPass(renderer: WebGLRenderer, camera: Camera, scene: Scene, maskRenderTarget: WebGLRenderTarget, includeFloor?: boolean): void;
|
|
58
|
-
/**
|
|
59
|
-
* 法线 pass(仅 SSAO 开启时需要):固定排除非实体表面后,以中性灰清屏 + normalMaterial
|
|
60
|
-
* override 将视图空间法线渲染到 normalRenderTarget,供 GTAO 风格 SSAO 使用。
|
|
61
|
-
* 排除对象在法线图保留中性灰清屏色 → unpackRGBToNormal(0.5,0.5,0.5)=(0,0,0) →
|
|
62
|
-
* SSAO 退化法线守卫判"无遮蔽"(=1),避免精灵弹窗被 AO 乘黑。清屏色用后即还原。
|
|
63
|
-
*/
|
|
64
|
-
export declare function renderAoNormalPass(renderer: WebGLRenderer, camera: Camera, scene: Scene, normalRenderTarget: WebGLRenderTarget, normalMaterial: MeshNormalMaterial, includeFloor?: boolean): void;
|
|
19
|
+
export declare function renderAoNormalPass(renderer: WebGLRenderer, camera: Camera, scene: Scene, normalRenderTarget: WebGLRenderTarget, normalMaterial: MeshNormalMaterial): void;
|
|
65
20
|
export interface SsaoOptions {
|
|
66
21
|
enable: boolean;
|
|
67
22
|
debug?: boolean;
|
package/pass/ssao_pass.js
CHANGED
|
@@ -1,98 +1,41 @@
|
|
|
1
|
-
import { Color, DataTexture,
|
|
1
|
+
import { Color, DataTexture, LinearFilter, NoBlending, RGBAFormat, RawShaderMaterial, RepeatWrapping, Vector2, Vector3, WebGLRenderTarget, Matrix4, MultiplyBlending, PerspectiveCamera, OrthographicCamera } from "three";
|
|
2
2
|
import fsQuad from "./fsQuad";
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// AO 数据准备 pass(深度 / 法线)
|
|
5
|
+
// 这些逻辑原本散落在 ThreeBase.render() 里,现收敛到此模块,ThreeBase 只调用下面两个函数。
|
|
6
|
+
// ⭐ 2026-10-18 皇上旨「所有的对象都要进入到深度图里面了,不需要用参数过滤掉了」⇒ 本模块原本的排除
|
|
7
|
+
// 逻辑**整条删除**(含 excludeTransparent 参数、按材质 transparent 的判据、userData.aoFloor /
|
|
8
|
+
// aoTransparent / aoOpaque 三个标记、sprite/线条/点的无条件排除),两张深度图都收全场景对象。
|
|
9
|
+
// 历史上这些排除是给 AO 兜底的,删掉后已知代价(皇上看过源码依据后确认接受):
|
|
10
|
+
// - 半透明面(玻璃、霓虹灯管、光晕、特效载体)也参与 AO → 透过它们看到的实体可能被乘黑;
|
|
11
|
+
// - sprite / 线条 / 点在 MeshNormalMaterial override 下法线不可信 → 该区域 AO 可能出黑块;
|
|
12
|
+
// - 地板(Ground1)重新写进可见深度图 → 透过地板看到的实体,其描边/辉光/覆盖色/磨砂会被裁掉。
|
|
13
|
+
// 10-12 旨「装饰地板需要透明」这次只保留**外观**(transparent + 径向 alpha 淡出 + depthWrite),
|
|
14
|
+
// 遮挡侧的 aoFloor 例外随本旨拆除。
|
|
15
|
+
// 出问题时用面板「深度调试 → 全局深度图 / AO深度图」两档定位是哪一侧。护栏:test/depthDebug.test.js J 组。
|
|
16
|
+
// 两张图仍然都存在、不能合并(现在两者渲染范围一致,差别只剩「用什么材质渲染」):
|
|
17
|
+
// - 可见深度(renderVisibleDepthPass,用各物体**自身材质**渲染):自身材质 ⇒ 单面墙只记正面、
|
|
18
|
+
// alpha 抠图(树叶、带 discard 的自定义 shader)只记真正可见的像素 —— 特效遮挡必须吃这份保真度。
|
|
19
|
+
// - AO 深度(normalRenderTarget 的 depth attachment,法线 pass 顺带白拿):override 材质是
|
|
20
|
+
// DoubleSide 且不做物体自己的 alpha discard,只能配法线给 GTAO 用;合成时靠 outputShader 那条
|
|
21
|
+
// 「AO 侧比可见深度更近 → 作废该像素 AO」的守卫兜住两套渲染结果的错位(别当死代码删)。
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
3
23
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* 法线写进去(近)→ 深度与法线指的不是同一个点 → GTAO 几乎必然算错发黑。
|
|
12
|
-
* 故深度 pass 与法线 pass 统一隐藏:该像素的深度/法线即身后不透明几何,AO 由真实可见几何
|
|
13
|
-
* 决定;身后是背景时深度为 1.0,shader 守卫直接判「无遮蔽」(=1),不会发黑。
|
|
14
|
-
*
|
|
15
|
-
* 判据只看 material.transparent 本身,不再依赖 opacity / depthWrite(2026-08-30 修正):
|
|
16
|
-
* 大量半透明是自定义 ShaderMaterial,alpha 由 shader 算出来,而材质的 opacity 仍是默认 1、
|
|
17
|
-
* depthWrite 仍是 true —— 典型如 Ground1 地板(mapColor.a 径向渐变)、聚光灯光斑、
|
|
18
|
-
* effectMaterial1,靠材质属性完全读不出来,会被漏判并继续污染 AO。
|
|
19
|
-
* 代价:Mirror 这类「标了 transparent 但 shader 实际输出 alpha=1.0」的实心反射面会被误排除,
|
|
20
|
-
* 故 Mirror 在构造函数里显式标记 userData.aoOpaque = true 保留(见各 Mirror 实现)。
|
|
21
|
-
* 其余特例同样可用 userData.aoTransparent=true 强制排除 / userData.aoOpaque=true 强制保留。
|
|
22
|
-
*
|
|
23
|
-
* @param includeFloor 是否为「含地板」的 AO 数据准备(GTAO 深度/法线)。
|
|
24
|
-
* - false(默认,可见深度 / 描边/辉光/毛玻璃遮挡判定):地板按普通半透明排除。
|
|
25
|
-
* - true(AO 深度):标了 userData.aoFloor 的地板保留为实体,参与接触 AO 计算。
|
|
26
|
-
*/
|
|
27
|
-
/**
|
|
28
|
-
* 可见深度图的运行时开关:**标了 `userData.aoFloor` 的地板是否参与遮挡判定**。
|
|
29
|
-
*
|
|
30
|
-
* 默认 false = 保持原设计(可透视地板:透过地板看到的物体照常显示,不被地板挡住)。
|
|
31
|
-
* 置 true 后,地板会写进 baseDepthTexture,于是**被地板挡住的描边/辉光/毛玻璃/覆盖色会被正确遮挡**。
|
|
32
|
-
* 面板「深度调试 → 地板参与遮挡」可一键切换,用于排查"挡不住"是不是地板(如 Ground1)造成的。
|
|
33
|
-
*
|
|
34
|
-
* 只影响 aoFloor 地板这一类;transparent 面的处理不受影响(见 isSeeThroughSurface)。
|
|
35
|
-
*/
|
|
36
|
-
export const visibleDepthOptions = { includeFloor: false };
|
|
37
|
-
const isSeeThroughSurface = (obj, includeFloor = false) => {
|
|
38
|
-
const o = obj;
|
|
39
|
-
const userData = o.userData;
|
|
40
|
-
if (userData && userData.aoOpaque === true)
|
|
41
|
-
return false;
|
|
42
|
-
if (userData && userData.aoTransparent === true)
|
|
43
|
-
return true;
|
|
44
|
-
// 地板类半透明:可见深度(includeFloor=false,描边/辉光/毛玻璃/覆盖色遮挡判定用)里排除
|
|
45
|
-
// → 可透视,透过地板看到的物体照常显示;AO 深度(includeFloor=true)里保留 → 接触 AO。
|
|
46
|
-
// ⚠️ 例外:visibleDepthOptions.includeFloor=true 时,可见深度里也保留地板 → 地板能挡住特效。
|
|
47
|
-
if (userData && userData.aoFloor === true) {
|
|
48
|
-
return includeFloor ? false : !visibleDepthOptions.includeFloor;
|
|
49
|
-
}
|
|
50
|
-
const mat = o.material;
|
|
51
|
-
if (!mat)
|
|
52
|
-
return false;
|
|
53
|
-
const list = Array.isArray(mat) ? mat : [mat];
|
|
54
|
-
const transparent = list.some((m) => m !== null && m.transparent === true);
|
|
55
|
-
// ⚠️ 关键修复(2026-09-06 回归根因):可见深度(includeFloor=false)必须把"标了
|
|
56
|
-
// transparent 但实为实心/不透明"的面当作实体参与遮挡——three-base 大量面(玻璃、特效载体、
|
|
57
|
-
// alpha 贴图实体、半透明墙)都标了 transparent:true;若在此排除,它们就不再遮挡身后特效,
|
|
58
|
-
// 所有依赖 baseDepthTexture 的深度测试(描边/辉光/毛玻璃/覆盖色)全部失效、一律显示在前面。
|
|
59
|
-
// 仅 AO 深度(includeFloor=true)需要排除透明面,避免 GTAO 在半透明面上算错发黑(保留原 AO 修复)。
|
|
60
|
-
return includeFloor && transparent;
|
|
61
|
-
};
|
|
62
|
-
const isNonSurface = (obj, includeFloor = false) => {
|
|
63
|
-
const o = obj;
|
|
64
|
-
if (o.isSprite === true || o.isLine === true || o.isLine2 === true || o.isLineSegments2 === true || o.isPoints === true) {
|
|
65
|
-
return true;
|
|
66
|
-
}
|
|
67
|
-
return isSeeThroughSurface(obj, includeFloor);
|
|
68
|
-
};
|
|
69
|
-
const hideNonSurface = (scene, includeFloor = false) => {
|
|
70
|
-
const list = [];
|
|
71
|
-
scene.traverse((obj) => {
|
|
72
|
-
if (isNonSurface(obj, includeFloor)) {
|
|
73
|
-
list.push({ obj, prev: obj.visible });
|
|
74
|
-
obj.visible = false;
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
return list;
|
|
78
|
-
};
|
|
79
|
-
const restoreVisibility = (list) => {
|
|
80
|
-
list.forEach(({ obj, prev }) => (obj.visible = prev));
|
|
81
|
-
};
|
|
82
|
-
/**
|
|
83
|
-
* 深度 pass:固定排除非实体表面后,将场景深度渲染到 depthRenderTarget。
|
|
84
|
-
* depthRenderTarget.depthTexture 即 baseDepthTexture,供 SSAO / 描边 / 发光等后续 pass 复用。
|
|
85
|
-
* 排除的非实体对象(sprite/线条/点)在深度图保留 clear 深度(1.0=远),与背景一致;排除的
|
|
86
|
-
* 半透明对象则保留其身后不透明几何的深度(身后无几何时同样为 1.0)。均不影响颜色通道渲染。
|
|
24
|
+
* 可见深度 pass:用**各物体自身的材质**把整个场景的深度渲染到 depthRenderTarget。
|
|
25
|
+
* depthRenderTarget.depthTexture 即 baseDepthTexture,供描边 / 发光 / 覆盖 / 磨砂的遮挡判定,
|
|
26
|
+
* 也是 SSAO 合成时「真实可见表面」的参考。
|
|
27
|
+
* 2026-10-18 起**不排除任何对象**(皇上旨「所有的对象都要进入到深度图里面了,不需要用参数过滤掉了」):
|
|
28
|
+
* 场景里所有对象都参与这一趟,只有使用者自己 `visible = false` 的对象除外(那是显隐意图,本 pass 不碰)。
|
|
29
|
+
* ⚠️ 名字里的 ao 已不适用(2026-10-11 改名自 renderAoDepthPass):它产出的是**可见深度**,
|
|
30
|
+
* AO 自己的深度挂在法线 pass 上(见 renderAoNormalPass)。
|
|
87
31
|
*/
|
|
88
|
-
export function
|
|
89
|
-
|
|
90
|
-
// ⚠️ 深度预通道铁律:必须让所有「未被排除」的可见表面都写入深度,深度图才有真实的几何遮挡信息。
|
|
32
|
+
export function renderVisibleDepthPass(renderer, camera, scene, depthRenderTarget) {
|
|
33
|
+
// ⚠️ 深度预通道铁律:必须让所有可见表面都写入深度,深度图才有真实的几何遮挡信息。
|
|
91
34
|
// 透明材质(特效载体、半透明墙、alpha 贴图实体等)大多 transparent:true 且 depthWrite:false,
|
|
92
35
|
// 若不强转,它们不会写进 baseDepthTexture → 深度图只剩不透明几何 → 描边/辉光/毛玻璃/覆盖色
|
|
93
|
-
// 依赖 baseDepthTexture
|
|
94
|
-
//
|
|
95
|
-
//
|
|
36
|
+
// 依赖 baseDepthTexture 的遮挡判定全部失效、一律显示在前(即 2026-09-06 那次回归根因)。
|
|
37
|
+
// 只强转 Mesh:sprite / 线条 / 点的材质默认就是 depthWrite:true,且叠加式光晕一旦强写深度会在
|
|
38
|
+
// 深度图上打洞、错误遮挡身后特效,故沿用原判据范围,不扩大。
|
|
96
39
|
const depthWriteRestore = [];
|
|
97
40
|
scene.traverse((obj) => {
|
|
98
41
|
const mesh = obj;
|
|
@@ -112,74 +55,21 @@ export function renderAoDepthPass(renderer, camera, scene, depthRenderTarget, in
|
|
|
112
55
|
renderer.render(scene, camera);
|
|
113
56
|
// 还原 depthWrite,避免污染后续颜色通道渲染的透明混合
|
|
114
57
|
depthWriteRestore.forEach(({ mat, val }) => { mat.depthWrite = val; });
|
|
115
|
-
restoreVisibility(hidden);
|
|
116
58
|
renderer.setRenderTarget(prevRenderTarget);
|
|
117
59
|
}
|
|
118
60
|
/**
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
* 以及标了 userData.aoFloor 的地板 Ground1)。
|
|
125
|
-
* 面板「深度调试 → 排除面标记」叠加显示:灰=能挡住的真实遮挡面,红=被排除、挡不住任何东西。
|
|
126
|
-
*
|
|
127
|
-
* 只渲染 Mesh:sprite / Line2 / Points 在 MeshBasicMaterial override 下渲染异常(见文件头注释),
|
|
128
|
-
* 且它们数量少、用户关心的遮挡体基本都是 Mesh,故跳过。
|
|
61
|
+
* 法线 pass(仅 SSAO 开启时需要):以中性灰清屏 + normalMaterial override 将整个场景的
|
|
62
|
+
* 视图空间法线渲染到 normalRenderTarget,供 GTAO 风格 SSAO 使用。
|
|
63
|
+
* 2026-10-18 起同样不排除任何对象(与 renderVisibleDepthPass 一致,见文件头那道旨及其代价清单)。
|
|
64
|
+
* 深度白拿:normalRenderTarget 挂着 aoDepthTexture 作 depth attachment,这一趟的深度由光栅器
|
|
65
|
+
* 顺带写入 → 就是 AO 用的深度,无需再单独渲一遍(2026-09-14)。
|
|
129
66
|
*/
|
|
130
|
-
export function
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
});
|
|
137
|
-
const prevVisible = [];
|
|
138
|
-
scene.traverse((obj) => {
|
|
139
|
-
const isMesh = obj.isMesh === true;
|
|
140
|
-
prevVisible.push({ obj, prev: obj.visible });
|
|
141
|
-
// 只显示「被排除的 Mesh」:其余一律隐藏,得到纯黑底 + 红面的 mask
|
|
142
|
-
obj.visible = isMesh && isNonSurface(obj, includeFloor);
|
|
143
|
-
});
|
|
144
|
-
const prevOverride = scene.overrideMaterial;
|
|
145
|
-
const prevTarget = renderer.getRenderTarget();
|
|
146
|
-
const prevClear = renderer.getClearColor(new Color());
|
|
147
|
-
const prevAlpha = renderer.getClearAlpha();
|
|
148
|
-
scene.overrideMaterial = maskMaterial;
|
|
149
|
-
renderer.setRenderTarget(maskRenderTarget);
|
|
150
|
-
renderer.setClearColor(0x000000, 1);
|
|
151
|
-
renderer.clear();
|
|
152
|
-
renderer.render(scene, camera);
|
|
153
|
-
renderer.setClearColor(prevClear, prevAlpha);
|
|
154
|
-
renderer.setRenderTarget(prevTarget);
|
|
155
|
-
scene.overrideMaterial = prevOverride;
|
|
156
|
-
restoreVisibility(prevVisible);
|
|
157
|
-
maskMaterial.dispose();
|
|
158
|
-
}
|
|
159
|
-
/**
|
|
160
|
-
* 法线 pass(仅 SSAO 开启时需要):固定排除非实体表面后,以中性灰清屏 + normalMaterial
|
|
161
|
-
* override 将视图空间法线渲染到 normalRenderTarget,供 GTAO 风格 SSAO 使用。
|
|
162
|
-
* 排除对象在法线图保留中性灰清屏色 → unpackRGBToNormal(0.5,0.5,0.5)=(0,0,0) →
|
|
163
|
-
* SSAO 退化法线守卫判"无遮蔽"(=1),避免精灵弹窗被 AO 乘黑。清屏色用后即还原。
|
|
164
|
-
*/
|
|
165
|
-
export function renderAoNormalPass(renderer, camera, scene, normalRenderTarget, normalMaterial, includeFloor = false) {
|
|
166
|
-
const hidden = hideNonSurface(scene, includeFloor);
|
|
167
|
-
// ⚠️ 与 renderAoDepthPass 同款「强制写深度」:本 pass 的深度会被当作含地板 AO 深度使用
|
|
168
|
-
// (normalRenderTarget.depthTexture)。透明面若因 depthWrite:false 不写深度,AO 深度就会漏掉它们,
|
|
169
|
-
// 与被本 pass 取代的那次独立深度 pass 内容不一致。pass 结束后立即还原。
|
|
170
|
-
const depthWriteRestore = [];
|
|
171
|
-
scene.traverse((obj) => {
|
|
172
|
-
const mesh = obj;
|
|
173
|
-
if (!mesh.isMesh || !mesh.material)
|
|
174
|
-
return;
|
|
175
|
-
const list = Array.isArray(mesh.material) ? mesh.material : [mesh.material];
|
|
176
|
-
list.forEach((m) => {
|
|
177
|
-
if (m && m.depthWrite === false) {
|
|
178
|
-
depthWriteRestore.push({ mat: m, val: false });
|
|
179
|
-
m.depthWrite = true;
|
|
180
|
-
}
|
|
181
|
-
});
|
|
182
|
-
});
|
|
67
|
+
export function renderAoNormalPass(renderer, camera, scene, normalRenderTarget, normalMaterial) {
|
|
68
|
+
// ⚠️ 2026-10-11 删掉了这里原有的「强制 depthWrite=true」整段遍历:scene.overrideMaterial 生效后,
|
|
69
|
+
// three 用的是 **override 材质**的渲染状态(WebGLRenderer.renderObjects:
|
|
70
|
+
// `material = overrideMaterial === null ? renderItem.material : overrideMaterial`,setDepthState 吃它),
|
|
71
|
+
// 物体自己材质的 depthWrite 根本读不到 ⇒ 那段是空转。需要强转的是用自身材质渲染的
|
|
72
|
+
// renderVisibleDepthPass(那边保留)。
|
|
183
73
|
const prevRenderTarget = renderer.getRenderTarget();
|
|
184
74
|
const prevClearColor = new Color();
|
|
185
75
|
renderer.getClearColor(prevClearColor);
|
|
@@ -190,8 +80,6 @@ export function renderAoNormalPass(renderer, camera, scene, normalRenderTarget,
|
|
|
190
80
|
scene.overrideMaterial = normalMaterial;
|
|
191
81
|
renderer.render(scene, camera);
|
|
192
82
|
scene.overrideMaterial = null;
|
|
193
|
-
restoreVisibility(hidden);
|
|
194
|
-
depthWriteRestore.forEach(({ mat, val }) => { mat.depthWrite = val; });
|
|
195
83
|
renderer.setClearColor(prevClearColor, prevClearAlpha);
|
|
196
84
|
renderer.setRenderTarget(prevRenderTarget);
|
|
197
85
|
}
|
|
@@ -658,9 +546,9 @@ const outputShader = new RawShaderMaterial({
|
|
|
658
546
|
ssaoTexture: { value: null },
|
|
659
547
|
ssaoStrength: { value: 1.0 },
|
|
660
548
|
debug: { value: 0.0 },
|
|
661
|
-
//
|
|
549
|
+
// 可见深度(用自身材质渲染,含地板)= baseDepthTexture:代表"真实可见表面"的深度。
|
|
662
550
|
tColorDepth: { value: null },
|
|
663
|
-
// AO
|
|
551
|
+
// AO 深度(= normalRenderTarget.depthTexture,法线 pass 顺带写入)。
|
|
664
552
|
tAoDepth: { value: null },
|
|
665
553
|
},
|
|
666
554
|
vertexShader: `
|
|
@@ -687,10 +575,15 @@ const outputShader = new RawShaderMaterial({
|
|
|
687
575
|
void main() {
|
|
688
576
|
float ssao = texture2D(ssaoTexture, vUv).r;
|
|
689
577
|
|
|
690
|
-
// 复合守卫:对数深度越小越近。若"
|
|
691
|
-
//
|
|
692
|
-
//
|
|
693
|
-
//
|
|
578
|
+
// 复合守卫:对数深度越小越近。若"AO 深度"比"可见深度"更近,说明该像素上法线趟
|
|
579
|
+
// (override 材质:DoubleSide、不做物体自己的 alpha discard)记到一个**屏幕上根本不可见**的面
|
|
580
|
+
// —— 典型如树叶抠图的空隙、单面墙的背面。此时深度与法线指的不是人眼看到的那个点,
|
|
581
|
+
// GTAO 算出的 AO 不可信 → 视为无遮蔽(=1)。
|
|
582
|
+
// ⚠️ 2026-10-18:两张图的渲染范围已统一(皇上旨「所有的对象都要进入到深度图里面了」⇒ excludeTransparent
|
|
583
|
+
// 参数与 aoFloor 特例整条拆除),本守卫不再承担「地板的接触 AO 别乘黑身后实体」这类职责,
|
|
584
|
+
// 它守的是上面那类 override 材质 / 自身材质两套渲染结果的错位(抠图空隙、单面墙背面、
|
|
585
|
+
// DoubleSide 记到背面),别当死代码删。
|
|
586
|
+
// 仅在最终合成时生效;debug 模式直接看 GTAO 原始 AO 图,便于排查。
|
|
694
587
|
float dColor = texture2D(tColorDepth, vUv).r;
|
|
695
588
|
float dAo = texture2D(tAoDepth, vUv).r;
|
|
696
589
|
if (debug < 0.5 && dAo < dColor - 0.0001) {
|
|
@@ -722,16 +615,18 @@ export default function ssao_pass(renderer, camera, scene, depthRenderTarget, no
|
|
|
722
615
|
// 故 AO 直接乘进 base,描边/发光/覆盖/磨砂都叠在 AO 之上不被压暗;末尾统一 FXAA 输出到屏幕,
|
|
723
616
|
// 覆盖 SSAO 自身的硬边。改动调用顺序时,本 pass 无需修改(输出到"绑定的那个目标"即可)。
|
|
724
617
|
const originRenderTarget = renderer.getRenderTarget();
|
|
725
|
-
// 法线 pass
|
|
618
|
+
// 法线 pass:整个场景都渲(2026-10-18 起不再按 transparent / aoFloor 排除任何面,见文件头那道旨)。
|
|
726
619
|
// ⭐ 深度白拿(2026-09-14 优化):normalRenderTarget 挂着 aoDepthTexture 作 depth attachment,
|
|
727
|
-
// 这一次渲染的深度由光栅器顺带写入 →
|
|
728
|
-
// (原先法线 pass
|
|
620
|
+
// 这一次渲染的深度由光栅器顺带写入 → 直接就是 AO 深度,**不再单独渲一遍深度 pass**。
|
|
621
|
+
// (原先法线 pass 之后还要再渲一遍「AO 深度」——它与法线 pass 的渲染集完全相同,
|
|
729
622
|
// 属于重复遍历全场景,2026-09-14 已删。)
|
|
730
|
-
//
|
|
731
|
-
|
|
732
|
-
|
|
623
|
+
// ⚠️ 这一趟的深度是 override 材质写的(DoubleSide、不做物体自己的 alpha discard),
|
|
624
|
+
// 所以只能给 AO 用;特效遮挡吃的是下面那张「用自身材质渲染」的可见深度。
|
|
625
|
+
renderAoNormalPass(renderer, camera, scene, normalRenderTarget, normalMaterial);
|
|
626
|
+
// 可见深度(用各物体自身材质渲染,含地板)= baseDepthTexture:描边/辉光/毛玻璃/覆盖色的遮挡参考,
|
|
627
|
+
// 也是复合守卫里「真实可见表面」的参考。
|
|
733
628
|
const colorDepthTexture = depthRenderTarget.depthTexture;
|
|
734
|
-
// AO
|
|
629
|
+
// AO 深度:GTAO 与去噪采样它(与上面的法线同一次光栅化,深度-法线永远同源)。
|
|
735
630
|
const aoDepthTexture = normalRenderTarget.depthTexture;
|
|
736
631
|
const normalTexture = normalRenderTarget.texture;
|
|
737
632
|
renderer.getSize(size);
|
|
@@ -796,8 +691,8 @@ export default function ssao_pass(renderer, camera, scene, depthRenderTarget, no
|
|
|
796
691
|
fsQuad.render(renderer, poissonDenoiseShader);
|
|
797
692
|
renderer.setRenderTarget(originRenderTarget);
|
|
798
693
|
outputShader.uniforms.ssaoTexture.value = blurTextureTarget.texture;
|
|
799
|
-
//
|
|
800
|
-
//
|
|
694
|
+
// 复合守卫:可见深度(自身材质渲染)与 AO 深度(override 渲染)两图比对,
|
|
695
|
+
// AO 侧更近 = 那像素记到屏幕上不可见的面(抠图空隙/单面墙背面)→ 作废该像素 AO(见 outputShader 注释)。
|
|
801
696
|
outputShader.uniforms.tColorDepth.value = colorDepthTexture;
|
|
802
697
|
outputShader.uniforms.tAoDepth.value = aoDepthTexture;
|
|
803
698
|
// 叠加强度:finalOcclusion = mix(1.0, ao, strength),0 = 完全不叠加 AO,1 = 原始强度,>1 外插加深。
|