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
|
@@ -14,6 +14,46 @@ const PICK_EVENT_TYPES = [
|
|
|
14
14
|
"mouseup",
|
|
15
15
|
];
|
|
16
16
|
|
|
17
|
+
/** 一个 batch 的合并情况快照(详见 `InstancedGroup.snapshot`) */
|
|
18
|
+
export interface InstancedBatchSnapshot {
|
|
19
|
+
/** 分桶键:`geo:<geometryUuid>/<materialUuid>` 或 `url:<glb>:anim:<剪辑名>` */
|
|
20
|
+
key: string;
|
|
21
|
+
/** 本桶里的逻辑实例数(InstancedChild) */
|
|
22
|
+
childCount: number;
|
|
23
|
+
/** 真实 InstancedMesh 个数 = 本桶一帧的 draw call 数(GLB 多 submesh ⇒ 大于 1) */
|
|
24
|
+
drawCalls: number;
|
|
25
|
+
/** 实例缓冲容量(只增不减) */
|
|
26
|
+
capacity: number;
|
|
27
|
+
/** GLB 模板是否已就绪;false ⇒ 实例已登记但还没画出来 */
|
|
28
|
+
ready: boolean;
|
|
29
|
+
/** 每个 InstancedMesh 实际写入的实例数(与 drawCalls 一一对应) */
|
|
30
|
+
counts: number[];
|
|
31
|
+
/** 子实例的可读标签(name 优先,其次构造器名) */
|
|
32
|
+
children: string[];
|
|
33
|
+
/** 首个 InstancedMesh 的几何类型名(如 `BoxGeometry`);模板未就绪时为空串 */
|
|
34
|
+
geomType: string;
|
|
35
|
+
/** 首个 InstancedMesh 的材质类型名(多材质为 `多材质`);模板未就绪时为空串 */
|
|
36
|
+
matType: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** 一个 InstancedGroup 的合并总览 */
|
|
40
|
+
export interface InstancedGroupSnapshot {
|
|
41
|
+
/** 本组归属 tag;undefined = ThreeBase 默认组(只收未声明归属的实例) */
|
|
42
|
+
owner?: string;
|
|
43
|
+
batches: InstancedBatchSnapshot[];
|
|
44
|
+
/** 已收进各 batch 的实例总数 */
|
|
45
|
+
merged: number;
|
|
46
|
+
/** 全局注册表里的 InstancedChild 总数(含归属其他组的) */
|
|
47
|
+
registryTotal: number;
|
|
48
|
+
/**
|
|
49
|
+
* 累计创建过的 InstancedChild 总数(只增不减,dispose 不回退)。
|
|
50
|
+
* 与 `registryTotal` 配对即得「已销毁 = createdTotal - registryTotal」。
|
|
51
|
+
*/
|
|
52
|
+
createdTotal: number;
|
|
53
|
+
/** 归属本组却没进任何 batch 的实例数:正常恒为 0,非 0 说明分桶/收集有漏 */
|
|
54
|
+
leaked: number;
|
|
55
|
+
}
|
|
56
|
+
|
|
17
57
|
/**
|
|
18
58
|
* 固定在 ThreeBase.scene 里的分组器。每帧收集所有 InstancedChild,按 batchKey(glb+当前生效动画)分组,
|
|
19
59
|
* 为每个 key 创建/复用 InstancedBatch,把实例的世界矩阵 / 颜色同步进真实 InstancedMesh。
|
|
@@ -118,6 +158,51 @@ export default class InstancedGroup extends Object3D {
|
|
|
118
158
|
}
|
|
119
159
|
}
|
|
120
160
|
|
|
161
|
+
/**
|
|
162
|
+
* 只读快照:本组当前的合并情况,供调试面板画拓扑图。
|
|
163
|
+
*
|
|
164
|
+
* 归属判定(哪些注册表实例该由本组收集)刻意留在这里而不是让调用方自己判 ——
|
|
165
|
+
* 规则与 `_accepts` 必须同源,否则面板报的「未合并数」会与实际渲染不符。
|
|
166
|
+
*
|
|
167
|
+
* ⚠️ 子实例标签取 `name`,其次取构造器名:业务子类若没设 `name`,生产构建(压缩后)
|
|
168
|
+
* 构造器名会变成短标识符。要在拓扑图里认出实例,请给实例设 `name`(同 [[InstancedChild]] 的控制台可读命名约定)。
|
|
169
|
+
*/
|
|
170
|
+
snapshot(): InstancedGroupSnapshot {
|
|
171
|
+
const batches: InstancedBatchSnapshot[] = [];
|
|
172
|
+
let merged = 0;
|
|
173
|
+
for (const batch of this.batches.values()) {
|
|
174
|
+
const childCount = batch.childCount;
|
|
175
|
+
merged += childCount;
|
|
176
|
+
const first = batch.pickables[0];
|
|
177
|
+
const mat = first?.material;
|
|
178
|
+
batches.push({
|
|
179
|
+
key: batch.key,
|
|
180
|
+
childCount,
|
|
181
|
+
drawCalls: batch.pickables.length,
|
|
182
|
+
capacity: batch.capacity,
|
|
183
|
+
ready: batch.ready,
|
|
184
|
+
counts: batch.pickables.map((im) => im.count),
|
|
185
|
+
children: batch.childrenView.map((c) => c.name || c.constructor.name),
|
|
186
|
+
geomType: first?.geometry.type ?? "",
|
|
187
|
+
matType: Array.isArray(mat) ? "多材质" : mat?.type ?? "",
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
let accepted = 0;
|
|
191
|
+
for (const child of instancedChildRegistry) {
|
|
192
|
+
if (this._accepts(child)) {
|
|
193
|
+
accepted++;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return {
|
|
197
|
+
owner: this.owner,
|
|
198
|
+
batches,
|
|
199
|
+
merged,
|
|
200
|
+
registryTotal: instancedChildRegistry.size,
|
|
201
|
+
createdTotal: InstancedChild.createdTotal,
|
|
202
|
+
leaked: accepted - merged,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
|
|
121
206
|
/**
|
|
122
207
|
* 释放本组的全部 batch(实例缓冲 + 从组内摘除 mesh)。
|
|
123
208
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "three-base",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.175",
|
|
4
4
|
"description": "A Three.js extension library providing common 3D components, animations, materials, and utilities",
|
|
5
5
|
"author": "xiaosihan",
|
|
6
6
|
"publishConfig": {
|
|
@@ -76,12 +76,8 @@
|
|
|
76
76
|
"./shaders/baseDepthVis": "./shaders/baseDepthVisShader.js",
|
|
77
77
|
"./shaders/debugDepthCompare": "./shaders/debugDepthCompareShader.js",
|
|
78
78
|
"./shaders/debugDepthJudge": "./shaders/debugDepthJudgeShader.js",
|
|
79
|
-
"./shaders/debugExcluded": "./shaders/debugExcludedShader.js",
|
|
80
79
|
"./Fire/FireGeometry": "./Fire/FireGeometry.js",
|
|
81
|
-
"./Fire/FireMaterial": "./Fire/FireMaterial.js"
|
|
82
|
-
"./WaterFlow": "./WaterFlow/WaterFlow.js",
|
|
83
|
-
"./WaterFlow/WaterFlow": "./WaterFlow/WaterFlow.js",
|
|
84
|
-
"./WaterFlow/waterFlowPass": "./WaterFlow/waterFlowPass.js"
|
|
80
|
+
"./Fire/FireMaterial": "./Fire/FireMaterial.js"
|
|
85
81
|
},
|
|
86
82
|
"files": [
|
|
87
83
|
"*.ts",
|
|
@@ -99,7 +95,6 @@
|
|
|
99
95
|
"SpriteModal1/",
|
|
100
96
|
"Text3D/",
|
|
101
97
|
"Water/",
|
|
102
|
-
"WaterFlow/",
|
|
103
98
|
"instanced/",
|
|
104
99
|
"lensflare/",
|
|
105
100
|
"pass/",
|
package/pass/bloom_pass.js
CHANGED
|
@@ -15,23 +15,18 @@ const selectDepthTexture = (() => {
|
|
|
15
15
|
baseDepthTexture.anisotropy = 16;
|
|
16
16
|
return baseDepthTexture;
|
|
17
17
|
})();
|
|
18
|
+
// ⭐ 2026-10-11 皇上旨「简化渲染」:selectDepthTexture 挂在本目标上当 depth attachment,
|
|
19
|
+
// mask 那一趟光栅化顺带写出本体深度 ⇒ 原来为同一对象再渲一趟「只出深度」整条删除。
|
|
18
20
|
const selectTextureTarget = new WebGLRenderTarget(1024, 1024, {
|
|
19
21
|
minFilter: LinearFilter,
|
|
20
22
|
magFilter: LinearFilter,
|
|
21
23
|
format: RGBAFormat,
|
|
24
|
+
depthTexture: selectDepthTexture,
|
|
22
25
|
anisotropy: 16,
|
|
23
|
-
// 无 MSAA:mask
|
|
26
|
+
// 无 MSAA:mask 颜色与它顺带写入的深度必须同为硬边缘,
|
|
24
27
|
// 否则 mask 边缘平滑而深度硬 → depthTest 判定边界与 mask 视觉边缘错位,bloom 边缘锯齿/摩尔纹。
|
|
25
28
|
// 边缘抗锯齿统一由终处理 FXAA 兜底。
|
|
26
29
|
});
|
|
27
|
-
// 无 MSAA 的深度专用目标:仅用于导出对象深度,供 depthTestShader 做遮挡判定(深度无需抗锯齿)
|
|
28
|
-
const selectDepthTextureTarget = new WebGLRenderTarget(1024, 1024, {
|
|
29
|
-
minFilter: LinearFilter,
|
|
30
|
-
magFilter: LinearFilter,
|
|
31
|
-
format: RGBAFormat,
|
|
32
|
-
depthTexture: selectDepthTexture,
|
|
33
|
-
anisotropy: 16,
|
|
34
|
-
});
|
|
35
30
|
const selectDepthTestTextureTarget = new WebGLRenderTarget(1024, 1024, {
|
|
36
31
|
minFilter: LinearFilter,
|
|
37
32
|
magFilter: LinearFilter,
|
|
@@ -117,7 +112,6 @@ export default function bloom_pass(renderer, camera, object3d, baseRenderTarget,
|
|
|
117
112
|
size.multiplyScalar(devicePixelRatio);
|
|
118
113
|
bloomPass.setSize(size.x, size.y);
|
|
119
114
|
selectTextureTarget.setSize(size.x, size.y);
|
|
120
|
-
selectDepthTextureTarget.setSize(size.x, size.y);
|
|
121
115
|
// 缺陷②修复:three r167 的 WebGLRenderTarget.setSize 不会同步 depthTexture,
|
|
122
116
|
// 需手动把 selectDepthTexture 的尺寸与全屏 baseDepth 对齐,否则深度比例错位导致 bloom 被全部 discard
|
|
123
117
|
selectDepthTexture.image.width = size.x;
|
|
@@ -168,13 +162,12 @@ export default function bloom_pass(renderer, camera, object3d, baseRenderTarget,
|
|
|
168
162
|
}
|
|
169
163
|
});
|
|
170
164
|
try {
|
|
165
|
+
// ⭐ mask 这一趟顺带把本体深度写进 selectDepthTexture(挂在 selectTextureTarget 的 depth
|
|
166
|
+
// attachment 上);原先紧随其后的「只渲深度」第二趟(同材质/同相机/同几何 ⇒ 深度逐位相同)
|
|
167
|
+
// 已在 2026-10-11 皇上旨简化时删除。与材质/父节点还原同生命周期。
|
|
171
168
|
renderer.setRenderTarget(selectTextureTarget);
|
|
172
169
|
renderer.clear();
|
|
173
170
|
renderer.render(scene, camera);
|
|
174
|
-
// 单独渲染对象深度到无 MSAA 目标,供 depthTestShader 做遮挡判定(与材质/父节点还原同生命周期)
|
|
175
|
-
renderer.setRenderTarget(selectDepthTextureTarget);
|
|
176
|
-
renderer.clear();
|
|
177
|
-
renderer.render(scene, camera);
|
|
178
171
|
}
|
|
179
172
|
finally {
|
|
180
173
|
// 还原材质 emissive
|
package/pass/bloom_pass.ts
CHANGED
|
@@ -18,25 +18,19 @@ const selectDepthTexture: DepthTexture = (() => {
|
|
|
18
18
|
return baseDepthTexture;
|
|
19
19
|
})();
|
|
20
20
|
|
|
21
|
+
// ⭐ 2026-10-11 皇上旨「简化渲染」:selectDepthTexture 挂在本目标上当 depth attachment,
|
|
22
|
+
// mask 那一趟光栅化顺带写出本体深度 ⇒ 原来为同一对象再渲一趟「只出深度」整条删除。
|
|
21
23
|
const selectTextureTarget: WebGLRenderTarget = new WebGLRenderTarget(1024, 1024, {
|
|
22
24
|
minFilter: LinearFilter,
|
|
23
25
|
magFilter: LinearFilter,
|
|
24
26
|
format: RGBAFormat,
|
|
27
|
+
depthTexture: selectDepthTexture,
|
|
25
28
|
anisotropy: 16,
|
|
26
|
-
// 无 MSAA:mask
|
|
29
|
+
// 无 MSAA:mask 颜色与它顺带写入的深度必须同为硬边缘,
|
|
27
30
|
// 否则 mask 边缘平滑而深度硬 → depthTest 判定边界与 mask 视觉边缘错位,bloom 边缘锯齿/摩尔纹。
|
|
28
31
|
// 边缘抗锯齿统一由终处理 FXAA 兜底。
|
|
29
32
|
});
|
|
30
33
|
|
|
31
|
-
// 无 MSAA 的深度专用目标:仅用于导出对象深度,供 depthTestShader 做遮挡判定(深度无需抗锯齿)
|
|
32
|
-
const selectDepthTextureTarget: WebGLRenderTarget = new WebGLRenderTarget(1024, 1024, {
|
|
33
|
-
minFilter: LinearFilter,
|
|
34
|
-
magFilter: LinearFilter,
|
|
35
|
-
format: RGBAFormat,
|
|
36
|
-
depthTexture: selectDepthTexture,
|
|
37
|
-
anisotropy: 16,
|
|
38
|
-
});
|
|
39
|
-
|
|
40
34
|
const selectDepthTestTextureTarget: WebGLRenderTarget = new WebGLRenderTarget(1024, 1024, {
|
|
41
35
|
minFilter: LinearFilter,
|
|
42
36
|
magFilter: LinearFilter,
|
|
@@ -145,7 +139,6 @@ export default function bloom_pass(
|
|
|
145
139
|
size.multiplyScalar(devicePixelRatio);
|
|
146
140
|
bloomPass.setSize(size.x, size.y);
|
|
147
141
|
selectTextureTarget.setSize(size.x, size.y);
|
|
148
|
-
selectDepthTextureTarget.setSize(size.x, size.y);
|
|
149
142
|
// 缺陷②修复:three r167 的 WebGLRenderTarget.setSize 不会同步 depthTexture,
|
|
150
143
|
// 需手动把 selectDepthTexture 的尺寸与全屏 baseDepth 对齐,否则深度比例错位导致 bloom 被全部 discard
|
|
151
144
|
selectDepthTexture.image.width = size.x;
|
|
@@ -198,14 +191,12 @@ export default function bloom_pass(
|
|
|
198
191
|
});
|
|
199
192
|
|
|
200
193
|
try {
|
|
194
|
+
// ⭐ mask 这一趟顺带把本体深度写进 selectDepthTexture(挂在 selectTextureTarget 的 depth
|
|
195
|
+
// attachment 上);原先紧随其后的「只渲深度」第二趟(同材质/同相机/同几何 ⇒ 深度逐位相同)
|
|
196
|
+
// 已在 2026-10-11 皇上旨简化时删除。与材质/父节点还原同生命周期。
|
|
201
197
|
renderer.setRenderTarget(selectTextureTarget);
|
|
202
198
|
renderer.clear();
|
|
203
199
|
renderer.render(scene, camera);
|
|
204
|
-
|
|
205
|
-
// 单独渲染对象深度到无 MSAA 目标,供 depthTestShader 做遮挡判定(与材质/父节点还原同生命周期)
|
|
206
|
-
renderer.setRenderTarget(selectDepthTextureTarget);
|
|
207
|
-
renderer.clear();
|
|
208
|
-
renderer.render(scene, camera);
|
|
209
200
|
} finally {
|
|
210
201
|
// 还原材质 emissive
|
|
211
202
|
emissiveBackup.forEach(({ material, emissive, emissiveIntensity }) => {
|
package/pass/cover_pass.js
CHANGED
|
@@ -20,23 +20,18 @@ const selectDepthTexture = (() => {
|
|
|
20
20
|
baseDepthTexture.anisotropy = 16;
|
|
21
21
|
return baseDepthTexture;
|
|
22
22
|
})();
|
|
23
|
+
// ⭐ 2026-10-11 皇上旨「简化渲染」:selectDepthTexture 挂在本目标上当 depth attachment,
|
|
24
|
+
// mask 那一趟光栅化顺带写出本体深度 ⇒ 原来为同一对象再渲一趟「只出深度」整条删除。
|
|
23
25
|
const selectTextureTarget = new WebGLRenderTarget(1024, 1024, {
|
|
24
26
|
minFilter: LinearFilter,
|
|
25
27
|
magFilter: LinearFilter,
|
|
26
28
|
format: RGBAFormat,
|
|
29
|
+
depthTexture: selectDepthTexture,
|
|
27
30
|
anisotropy: 16,
|
|
28
|
-
// 无 MSAA:mask
|
|
31
|
+
// 无 MSAA:mask 颜色与它顺带写入的深度必须同为硬边缘,
|
|
29
32
|
// 否则 mask 边缘平滑而深度硬 → depthTestShader 判定边界与 mask 视觉边缘错位,覆盖边缘锯齿。
|
|
30
33
|
// 边缘抗锯齿统一由终处理 FXAA 兜底。
|
|
31
34
|
});
|
|
32
|
-
// 无 MSAA 的深度专用目标:仅用于导出对象深度,供 depthTestShader 做遮挡判定(深度无需抗锯齿)
|
|
33
|
-
const selectDepthTextureTarget = new WebGLRenderTarget(1024, 1024, {
|
|
34
|
-
minFilter: LinearFilter,
|
|
35
|
-
magFilter: LinearFilter,
|
|
36
|
-
format: RGBAFormat,
|
|
37
|
-
depthTexture: selectDepthTexture,
|
|
38
|
-
anisotropy: 16,
|
|
39
|
-
});
|
|
40
35
|
const selectDepthTestTextureTarget = new WebGLRenderTarget(1024, 1024, {
|
|
41
36
|
minFilter: LinearFilter,
|
|
42
37
|
magFilter: LinearFilter,
|
|
@@ -125,7 +120,6 @@ export default function cover_pass(renderer, camera, object3d, baseDepthTexture,
|
|
|
125
120
|
renderer.getSize(size);
|
|
126
121
|
size.multiplyScalar(devicePixelRatio);
|
|
127
122
|
selectTextureTarget.setSize(size.x, size.y);
|
|
128
|
-
selectDepthTextureTarget.setSize(size.x, size.y);
|
|
129
123
|
// 缺陷修复:three r167 的 WebGLRenderTarget.setSize 不会同步 depthTexture,
|
|
130
124
|
// 需手动把 selectDepthTexture 尺寸与全屏 baseDepth 对齐,否则深度比例错位导致颜色覆盖被错误 discard
|
|
131
125
|
selectDepthTexture.image.width = size.x;
|
|
@@ -133,15 +127,13 @@ export default function cover_pass(renderer, camera, object3d, baseDepthTexture,
|
|
|
133
127
|
selectDepthTexture.needsUpdate = true;
|
|
134
128
|
selectDepthTestTextureTarget.setSize(size.x, size.y);
|
|
135
129
|
blur1TextureTarget.setSize(size.x, size.y);
|
|
130
|
+
// ⭐ mask 那一趟光栅化顺带把本体深度写进 selectDepthTexture(挂在 selectTextureTarget 的
|
|
131
|
+
// depth attachment 上);原先紧随其后的「只渲深度」第二趟(同材质/同相机/同几何 ⇒ 深度逐位相同)
|
|
132
|
+
// 已在 2026-10-11 皇上旨简化时删除。
|
|
136
133
|
renderer.setRenderTarget(selectTextureTarget);
|
|
137
134
|
scene.children = [object3d];
|
|
138
135
|
renderer.clear();
|
|
139
136
|
renderer.render(scene, camera);
|
|
140
|
-
// 单独渲染对象深度到无 MSAA 目标,供 depthTestShader 做遮挡判定
|
|
141
|
-
renderer.setRenderTarget(selectDepthTextureTarget);
|
|
142
|
-
scene.children = [object3d];
|
|
143
|
-
renderer.clear();
|
|
144
|
-
renderer.render(scene, camera);
|
|
145
137
|
// 调试:记录选区深度,供面板「深度判定图 / 辉光深度比对」排查 cover 的遮挡判定
|
|
146
138
|
debugDepthState.lastSelectDepth = selectDepthTexture;
|
|
147
139
|
renderer.setRenderTarget(originRenderTarget);
|
package/pass/cover_pass.ts
CHANGED
|
@@ -23,25 +23,19 @@ const selectDepthTexture: DepthTexture = (() => {
|
|
|
23
23
|
return baseDepthTexture;
|
|
24
24
|
})();
|
|
25
25
|
|
|
26
|
+
// ⭐ 2026-10-11 皇上旨「简化渲染」:selectDepthTexture 挂在本目标上当 depth attachment,
|
|
27
|
+
// mask 那一趟光栅化顺带写出本体深度 ⇒ 原来为同一对象再渲一趟「只出深度」整条删除。
|
|
26
28
|
const selectTextureTarget: WebGLRenderTarget = new WebGLRenderTarget(1024, 1024, {
|
|
27
29
|
minFilter: LinearFilter,
|
|
28
30
|
magFilter: LinearFilter,
|
|
29
31
|
format: RGBAFormat,
|
|
32
|
+
depthTexture: selectDepthTexture,
|
|
30
33
|
anisotropy: 16,
|
|
31
|
-
// 无 MSAA:mask
|
|
34
|
+
// 无 MSAA:mask 颜色与它顺带写入的深度必须同为硬边缘,
|
|
32
35
|
// 否则 mask 边缘平滑而深度硬 → depthTestShader 判定边界与 mask 视觉边缘错位,覆盖边缘锯齿。
|
|
33
36
|
// 边缘抗锯齿统一由终处理 FXAA 兜底。
|
|
34
37
|
});
|
|
35
38
|
|
|
36
|
-
// 无 MSAA 的深度专用目标:仅用于导出对象深度,供 depthTestShader 做遮挡判定(深度无需抗锯齿)
|
|
37
|
-
const selectDepthTextureTarget: WebGLRenderTarget = new WebGLRenderTarget(1024, 1024, {
|
|
38
|
-
minFilter: LinearFilter,
|
|
39
|
-
magFilter: LinearFilter,
|
|
40
|
-
format: RGBAFormat,
|
|
41
|
-
depthTexture: selectDepthTexture,
|
|
42
|
-
anisotropy: 16,
|
|
43
|
-
});
|
|
44
|
-
|
|
45
39
|
const selectDepthTestTextureTarget: WebGLRenderTarget = new WebGLRenderTarget(1024, 1024, {
|
|
46
40
|
minFilter: LinearFilter,
|
|
47
41
|
magFilter: LinearFilter,
|
|
@@ -149,7 +143,6 @@ export default function cover_pass(
|
|
|
149
143
|
renderer.getSize(size);
|
|
150
144
|
size.multiplyScalar(devicePixelRatio);
|
|
151
145
|
selectTextureTarget.setSize(size.x, size.y);
|
|
152
|
-
selectDepthTextureTarget.setSize(size.x, size.y);
|
|
153
146
|
// 缺陷修复:three r167 的 WebGLRenderTarget.setSize 不会同步 depthTexture,
|
|
154
147
|
// 需手动把 selectDepthTexture 尺寸与全屏 baseDepth 对齐,否则深度比例错位导致颜色覆盖被错误 discard
|
|
155
148
|
selectDepthTexture.image.width = size.x;
|
|
@@ -157,16 +150,13 @@ export default function cover_pass(
|
|
|
157
150
|
selectDepthTexture.needsUpdate = true;
|
|
158
151
|
selectDepthTestTextureTarget.setSize(size.x, size.y);
|
|
159
152
|
blur1TextureTarget.setSize(size.x, size.y);
|
|
153
|
+
// ⭐ mask 那一趟光栅化顺带把本体深度写进 selectDepthTexture(挂在 selectTextureTarget 的
|
|
154
|
+
// depth attachment 上);原先紧随其后的「只渲深度」第二趟(同材质/同相机/同几何 ⇒ 深度逐位相同)
|
|
155
|
+
// 已在 2026-10-11 皇上旨简化时删除。
|
|
160
156
|
renderer.setRenderTarget(selectTextureTarget);
|
|
161
157
|
scene.children = [object3d];
|
|
162
158
|
renderer.clear();
|
|
163
159
|
renderer.render(scene, camera);
|
|
164
|
-
|
|
165
|
-
// 单独渲染对象深度到无 MSAA 目标,供 depthTestShader 做遮挡判定
|
|
166
|
-
renderer.setRenderTarget(selectDepthTextureTarget);
|
|
167
|
-
scene.children = [object3d];
|
|
168
|
-
renderer.clear();
|
|
169
|
-
renderer.render(scene, camera);
|
|
170
160
|
// 调试:记录选区深度,供面板「深度判定图 / 辉光深度比对」排查 cover 的遮挡判定
|
|
171
161
|
debugDepthState.lastSelectDepth = selectDepthTexture;
|
|
172
162
|
|
|
@@ -1,20 +1,28 @@
|
|
|
1
|
-
import type { DepthTexture } from "three";
|
|
1
|
+
import type { DepthTexture, Texture } from "three";
|
|
2
2
|
/**
|
|
3
3
|
* 深度调试预览模式(面板按钮与控制台 `window.__TB_DEBUG_DEPTH` 共用同一枚举):
|
|
4
|
-
* - "none"
|
|
5
|
-
* - "global"
|
|
6
|
-
* - "ao"
|
|
7
|
-
* - "compare"
|
|
8
|
-
* - "judge"
|
|
9
|
-
* - "
|
|
4
|
+
* - "none" :正常渲染(默认)
|
|
5
|
+
* - "global" :可见深度图(baseDepthTexture,各物体自身材质渲染;2026-10-18 起收全场景对象,含地板)
|
|
6
|
+
* - "ao" :AO 深度图(aoDepthTexture,法线 pass 顺带写入,override 渲染,同样收全场景对象)
|
|
7
|
+
* - "compare" :R=base 深度、G=选区 select 深度(对数反解后归一化)
|
|
8
|
+
* - "judge" :R=base 原始深度、G=select 原始深度、B=判定结果(1=判为被遮挡应 discard)
|
|
9
|
+
* - "strokeSelect" :【描边步骤 1】选区本体深度(selectDepthTexture,mask 那趟光栅化顺带写入)
|
|
10
|
+
* - "strokeSelectBlur":【描边步骤 5.5】描边外扩后的选区深度(selectDepthBlurTextureTarget,
|
|
11
|
+
* RGBA8 的 R 通道存对数深度,外扩环取邻域最近深度)
|
|
12
|
+
* ⚠️ 2026-10-18 皇上旨「所有的对象都要进入到深度图里面了,不需要用参数过滤掉了」⇒ 原 "excluded"
|
|
13
|
+
* 档(把被排除的面叠红)连同 ssao_pass 的排除判据整条删除,已无「写不进深度图的面」可标。
|
|
10
14
|
*/
|
|
11
|
-
export type DebugDepthMode = "none" | "global" | "ao" | "compare" | "judge" | "
|
|
15
|
+
export type DebugDepthMode = "none" | "global" | "ao" | "compare" | "judge" | "strokeSelect" | "strokeSelectBlur";
|
|
12
16
|
/**
|
|
13
17
|
* 调试用全局状态:记录最近一次 glow_pass / stroke_pass 渲染的「选区自身深度图」(selectDepth)。
|
|
14
18
|
* 供 ThreeBase 渲染末尾的「辉光深度比对」调试视图读取(R=全局 base 深度,G=选区 select 深度),
|
|
15
19
|
* 让用户一眼看出到底是「全局 base 深度没写进」还是「选区自身深度没写进」。
|
|
16
20
|
* 由各 pass 在渲染完 selectDepth 后写入;每帧会被最后一个被处理的可见对象覆盖(调试够用)。
|
|
21
|
+
*
|
|
22
|
+
* lastSelectBlurDepth:描边专属(步骤 5.5 外扩后的选区深度)。它是 RGBA8 目标(不是 DepthTexture),
|
|
23
|
+
* 深度值存在 .r 通道里 —— 可视化时同样取 .r 即可。glow/cover/frosted 没有这一步,故只有 stroke_pass 写。
|
|
17
24
|
*/
|
|
18
25
|
export declare const debugDepthState: {
|
|
19
26
|
lastSelectDepth: DepthTexture | null;
|
|
27
|
+
lastSelectBlurDepth: Texture | null;
|
|
20
28
|
};
|
package/pass/debugDepthState.js
CHANGED
|
@@ -3,7 +3,11 @@
|
|
|
3
3
|
* 供 ThreeBase 渲染末尾的「辉光深度比对」调试视图读取(R=全局 base 深度,G=选区 select 深度),
|
|
4
4
|
* 让用户一眼看出到底是「全局 base 深度没写进」还是「选区自身深度没写进」。
|
|
5
5
|
* 由各 pass 在渲染完 selectDepth 后写入;每帧会被最后一个被处理的可见对象覆盖(调试够用)。
|
|
6
|
+
*
|
|
7
|
+
* lastSelectBlurDepth:描边专属(步骤 5.5 外扩后的选区深度)。它是 RGBA8 目标(不是 DepthTexture),
|
|
8
|
+
* 深度值存在 .r 通道里 —— 可视化时同样取 .r 即可。glow/cover/frosted 没有这一步,故只有 stroke_pass 写。
|
|
6
9
|
*/
|
|
7
10
|
export const debugDepthState = {
|
|
8
11
|
lastSelectDepth: null,
|
|
12
|
+
lastSelectBlurDepth: null,
|
|
9
13
|
};
|
package/pass/debugDepthState.ts
CHANGED
|
@@ -1,22 +1,40 @@
|
|
|
1
|
-
import type { DepthTexture } from "three";
|
|
1
|
+
import type { DepthTexture, Texture } from "three";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* 深度调试预览模式(面板按钮与控制台 `window.__TB_DEBUG_DEPTH` 共用同一枚举):
|
|
5
|
-
* - "none"
|
|
6
|
-
* - "global"
|
|
7
|
-
* - "ao"
|
|
8
|
-
* - "compare"
|
|
9
|
-
* - "judge"
|
|
10
|
-
* - "
|
|
5
|
+
* - "none" :正常渲染(默认)
|
|
6
|
+
* - "global" :可见深度图(baseDepthTexture,各物体自身材质渲染;2026-10-18 起收全场景对象,含地板)
|
|
7
|
+
* - "ao" :AO 深度图(aoDepthTexture,法线 pass 顺带写入,override 渲染,同样收全场景对象)
|
|
8
|
+
* - "compare" :R=base 深度、G=选区 select 深度(对数反解后归一化)
|
|
9
|
+
* - "judge" :R=base 原始深度、G=select 原始深度、B=判定结果(1=判为被遮挡应 discard)
|
|
10
|
+
* - "strokeSelect" :【描边步骤 1】选区本体深度(selectDepthTexture,mask 那趟光栅化顺带写入)
|
|
11
|
+
* - "strokeSelectBlur":【描边步骤 5.5】描边外扩后的选区深度(selectDepthBlurTextureTarget,
|
|
12
|
+
* RGBA8 的 R 通道存对数深度,外扩环取邻域最近深度)
|
|
13
|
+
* ⚠️ 2026-10-18 皇上旨「所有的对象都要进入到深度图里面了,不需要用参数过滤掉了」⇒ 原 "excluded"
|
|
14
|
+
* 档(把被排除的面叠红)连同 ssao_pass 的排除判据整条删除,已无「写不进深度图的面」可标。
|
|
11
15
|
*/
|
|
12
|
-
export type DebugDepthMode =
|
|
16
|
+
export type DebugDepthMode =
|
|
17
|
+
| "none"
|
|
18
|
+
| "global"
|
|
19
|
+
| "ao"
|
|
20
|
+
| "compare"
|
|
21
|
+
| "judge"
|
|
22
|
+
| "strokeSelect"
|
|
23
|
+
| "strokeSelectBlur";
|
|
13
24
|
|
|
14
25
|
/**
|
|
15
26
|
* 调试用全局状态:记录最近一次 glow_pass / stroke_pass 渲染的「选区自身深度图」(selectDepth)。
|
|
16
27
|
* 供 ThreeBase 渲染末尾的「辉光深度比对」调试视图读取(R=全局 base 深度,G=选区 select 深度),
|
|
17
28
|
* 让用户一眼看出到底是「全局 base 深度没写进」还是「选区自身深度没写进」。
|
|
18
29
|
* 由各 pass 在渲染完 selectDepth 后写入;每帧会被最后一个被处理的可见对象覆盖(调试够用)。
|
|
30
|
+
*
|
|
31
|
+
* lastSelectBlurDepth:描边专属(步骤 5.5 外扩后的选区深度)。它是 RGBA8 目标(不是 DepthTexture),
|
|
32
|
+
* 深度值存在 .r 通道里 —— 可视化时同样取 .r 即可。glow/cover/frosted 没有这一步,故只有 stroke_pass 写。
|
|
19
33
|
*/
|
|
20
|
-
export const debugDepthState: {
|
|
34
|
+
export const debugDepthState: {
|
|
35
|
+
lastSelectDepth: DepthTexture | null;
|
|
36
|
+
lastSelectBlurDepth: Texture | null;
|
|
37
|
+
} = {
|
|
21
38
|
lastSelectDepth: null,
|
|
39
|
+
lastSelectBlurDepth: null,
|
|
22
40
|
};
|
package/pass/glow_pass.js
CHANGED
|
@@ -14,23 +14,18 @@ const selectDepthTexture = (() => {
|
|
|
14
14
|
baseDepthTexture.anisotropy = 16;
|
|
15
15
|
return baseDepthTexture;
|
|
16
16
|
})();
|
|
17
|
+
// ⭐ 2026-10-11 皇上旨「简化渲染」:selectDepthTexture 挂在本目标上当 depth attachment,
|
|
18
|
+
// mask 那一趟光栅化顺带写出本体深度 ⇒ 原来为同一对象再渲一趟「只出深度」整条删除。
|
|
17
19
|
const selectTextureTarget = new WebGLRenderTarget(1024, 1024, {
|
|
18
20
|
minFilter: LinearFilter,
|
|
19
21
|
magFilter: LinearFilter,
|
|
20
22
|
format: RGBAFormat,
|
|
23
|
+
depthTexture: selectDepthTexture,
|
|
21
24
|
anisotropy: 16,
|
|
22
|
-
// 无 MSAA:mask
|
|
25
|
+
// 无 MSAA:mask 颜色与它顺带写入的深度必须同为硬边缘,
|
|
23
26
|
// 否则 mask 边缘平滑而深度硬 → depthTestShader 判定边界与 mask 视觉边缘错位,辉光边缘锯齿。
|
|
24
27
|
// 边缘抗锯齿统一由 mask 内部 FXAA + 终处理 FXAA 兜底。
|
|
25
28
|
});
|
|
26
|
-
// 无 MSAA 的深度专用目标:仅用于导出对象深度,供 depthTestShader 做遮挡判定(深度无需抗锯齿)
|
|
27
|
-
const selectDepthTextureTarget = new WebGLRenderTarget(1024, 1024, {
|
|
28
|
-
minFilter: LinearFilter,
|
|
29
|
-
magFilter: LinearFilter,
|
|
30
|
-
format: RGBAFormat,
|
|
31
|
-
depthTexture: selectDepthTexture,
|
|
32
|
-
anisotropy: 16,
|
|
33
|
-
});
|
|
34
29
|
const selectDepthTestTextureTarget = new WebGLRenderTarget(1024, 1024, {
|
|
35
30
|
minFilter: LinearFilter,
|
|
36
31
|
magFilter: LinearFilter,
|
|
@@ -48,24 +43,13 @@ const blur2TextureTarget = new WebGLRenderTarget(1024, 1024, {
|
|
|
48
43
|
magFilter: LinearFilter,
|
|
49
44
|
format: RGBAFormat,
|
|
50
45
|
});
|
|
51
|
-
//
|
|
52
|
-
//
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const selectDepthBlurTextureTarget = new WebGLRenderTarget(1024, 1024, {
|
|
59
|
-
minFilter: LinearFilter,
|
|
60
|
-
magFilter: LinearFilter,
|
|
61
|
-
format: RGBAFormat,
|
|
62
|
-
});
|
|
63
|
-
// 外扩辉光经深度测试后的结果(步骤 5.6):独立 target,避免回写 blur1 触发历史回归 bug
|
|
64
|
-
const blurDepthTestTextureTarget = new WebGLRenderTarget(1024, 1024, {
|
|
65
|
-
minFilter: LinearFilter,
|
|
66
|
-
magFilter: LinearFilter,
|
|
67
|
-
format: RGBAFormat,
|
|
68
|
-
});
|
|
46
|
+
// ⭐ 2026-10-25 皇上旨「步骤 5.6 外扩辉光再判遮挡 不要这不」:
|
|
47
|
+
// 原「步骤 5.5 深度外扩(min-blur)+ 5.6 外扩辉光再判遮挡」整段删除,连同
|
|
48
|
+
// selectDepthBlurTmp / selectDepthBlur / blurDepthTest 三个 RT 与 depthMinBlurShader。
|
|
49
|
+
// 原因:min-blur 的膨胀窗口是 ±10×radius 的方形(radius = glow_width×2,与单趟高斯采样步长同源),
|
|
50
|
+
// 而模糊迭代 N 次后等效扩散按 σ√N 增长 ⇒ 窗口外那圈光的 selD 仍是「背景 1.0」,
|
|
51
|
+
// 被 baseD(天空 0.9) < selD(1.0) 判成「被挡住」→ discard → 光晕被硬切一刀。
|
|
52
|
+
// 代价(已知并接受):物体被更近的物体挡住时,辉光不再从遮挡物前方被裁掉,会透出来。
|
|
69
53
|
const size = new Vector2();
|
|
70
54
|
const depthTestShader = new ShaderMaterial({
|
|
71
55
|
uniforms: {
|
|
@@ -209,52 +193,6 @@ const gaussianBlurVShader = new RawShaderMaterial({
|
|
|
209
193
|
depthWrite: false,
|
|
210
194
|
transparent: true,
|
|
211
195
|
});
|
|
212
|
-
// 深度 min-blur(最近深度,忽略背景 1.0):随 mask 一起把深度图向外扩,
|
|
213
|
-
// 外扩区 selD = 物体最近深度(<1.0) 而非清屏 1.0,depthTest 在外扩区才能正确判遮挡(不漏光),
|
|
214
|
-
// 同时本体区仍靠 depthTestShader 的 EPSILON 容差防自遮挡闪烁(无缝)。separable(direction 控制 H/V)。
|
|
215
|
-
const depthMinBlurShader = new ShaderMaterial({
|
|
216
|
-
uniforms: {
|
|
217
|
-
tDepth: { value: null },
|
|
218
|
-
resolution: { value: new Vector2(1 / 512, 1 / 512) },
|
|
219
|
-
radius: { value: 1.0 },
|
|
220
|
-
direction: { value: new Vector2(1, 0) },
|
|
221
|
-
},
|
|
222
|
-
vertexShader: `
|
|
223
|
-
${ShaderChunk.common}
|
|
224
|
-
${ShaderChunk.logdepthbuf_pars_vertex}
|
|
225
|
-
varying vec2 vUv;
|
|
226
|
-
void main() {
|
|
227
|
-
vUv = uv;
|
|
228
|
-
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
229
|
-
${ShaderChunk.logdepthbuf_vertex}
|
|
230
|
-
}
|
|
231
|
-
`,
|
|
232
|
-
fragmentShader: `
|
|
233
|
-
${ShaderChunk.logdepthbuf_pars_fragment}
|
|
234
|
-
uniform sampler2D tDepth;
|
|
235
|
-
uniform vec2 resolution;
|
|
236
|
-
uniform float radius;
|
|
237
|
-
uniform vec2 direction;
|
|
238
|
-
varying vec2 vUv;
|
|
239
|
-
void main() {
|
|
240
|
-
float minD = 1.0;
|
|
241
|
-
for (int i = -10; i <= 10; i++) {
|
|
242
|
-
float x = float(i);
|
|
243
|
-
vec2 off = direction * (x * radius * resolution);
|
|
244
|
-
float d = texture2D(tDepth, vUv + off).r;
|
|
245
|
-
if (d < 0.9999) {
|
|
246
|
-
minD = min(minD, d);
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
gl_FragColor = vec4(minD, 0.0, 0.0, 1.0);
|
|
250
|
-
${ShaderChunk.logdepthbuf_fragment}
|
|
251
|
-
}
|
|
252
|
-
`,
|
|
253
|
-
blending: NoBlending,
|
|
254
|
-
depthTest: false,
|
|
255
|
-
depthWrite: false,
|
|
256
|
-
transparent: true,
|
|
257
|
-
});
|
|
258
196
|
const glowCompositeShader = new RawShaderMaterial({
|
|
259
197
|
uniforms: {
|
|
260
198
|
tDiffuse: { value: null },
|
|
@@ -483,7 +421,6 @@ export default function glow_pass(renderer, camera, object3d, baseDepthTexture,
|
|
|
483
421
|
renderer.getSize(size);
|
|
484
422
|
size.multiplyScalar(devicePixelRatio);
|
|
485
423
|
selectTextureTarget.setSize(size.x, size.y);
|
|
486
|
-
selectDepthTextureTarget.setSize(size.x, size.y);
|
|
487
424
|
// 缺陷修复:three r167 的 WebGLRenderTarget.setSize 不会同步 depthTexture,
|
|
488
425
|
// 需手动把 selectDepthTexture 尺寸与全屏 baseDepth 对齐,否则深度比例错位导致辉光被错误 discard
|
|
489
426
|
selectDepthTexture.image.width = size.x;
|
|
@@ -492,19 +429,14 @@ export default function glow_pass(renderer, camera, object3d, baseDepthTexture,
|
|
|
492
429
|
selectDepthTestTextureTarget.setSize(size.x, size.y);
|
|
493
430
|
blur1TextureTarget.setSize(size.x, size.y);
|
|
494
431
|
blur2TextureTarget.setSize(size.x, size.y);
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
//
|
|
432
|
+
// 1. 渲染物体本体 mask(灰度)。⭐ 本体深度由同一趟光栅化顺带写进 selectDepthTexture
|
|
433
|
+
// (挂在 selectTextureTarget 的 depth attachment 上);原先的第 2 趟「只渲深度」(供 min-blur
|
|
434
|
+
// 外扩用)与这趟同材质/同相机/同几何 ⇒ 深度逐位相同,2026-10-11 皇上旨简化时删除。
|
|
435
|
+
// (下面的步骤编号保留 3/4/5…,别处注释按号交叉引用,不随之重排。)
|
|
499
436
|
renderer.setRenderTarget(selectTextureTarget);
|
|
500
437
|
scene.children = [object3d];
|
|
501
438
|
renderer.clear();
|
|
502
439
|
renderer.render(scene, camera);
|
|
503
|
-
// 2. 渲染物体本体深度(无 MSAA,供 min-blur 外扩用)
|
|
504
|
-
renderer.setRenderTarget(selectDepthTextureTarget);
|
|
505
|
-
scene.children = [object3d];
|
|
506
|
-
renderer.clear();
|
|
507
|
-
renderer.render(scene, camera);
|
|
508
440
|
// 调试:把本次渲染的选区深度记到全局调试状态,供面板「辉光深度比对」读取
|
|
509
441
|
debugDepthState.lastSelectDepth = selectDepthTexture;
|
|
510
442
|
// 3. 深度测试(用本体 mask):被真实更近物体挡住的「本体辉光」部分 discard。
|
|
@@ -553,36 +485,13 @@ export default function glow_pass(renderer, camera, object3d, baseDepthTexture,
|
|
|
553
485
|
glowCompositeShader.uniforms.threshold.value = glow_threshold;
|
|
554
486
|
glowCompositeShader.uniforms.intensity.value = glow_intensity;
|
|
555
487
|
fsQuad.render(renderer, glowCompositeShader);
|
|
556
|
-
//
|
|
557
|
-
//
|
|
558
|
-
// 再用它对外扩后的辉光做一次 depthTest —— 否则外扩环永远不参与遮挡判定,
|
|
559
|
-
// 物体被挡住时辉光依旧从遮挡物前方漏出来。
|
|
560
|
-
depthMinBlurShader.uniforms.resolution.value.set(1 / size.x, 1 / size.y);
|
|
561
|
-
depthMinBlurShader.uniforms.radius.value = Math.max(1, blurRadius);
|
|
562
|
-
depthMinBlurShader.uniforms.direction.value.set(1, 0);
|
|
563
|
-
depthMinBlurShader.uniforms.tDepth.value = selectDepthTexture;
|
|
564
|
-
renderer.setRenderTarget(selectDepthBlurTmpTextureTarget);
|
|
565
|
-
renderer.clear();
|
|
566
|
-
fsQuad.render(renderer, depthMinBlurShader);
|
|
567
|
-
depthMinBlurShader.uniforms.direction.value.set(0, 1);
|
|
568
|
-
depthMinBlurShader.uniforms.tDepth.value = selectDepthBlurTmpTextureTarget.texture;
|
|
569
|
-
renderer.setRenderTarget(selectDepthBlurTextureTarget);
|
|
570
|
-
renderer.clear();
|
|
571
|
-
fsQuad.render(renderer, depthMinBlurShader);
|
|
572
|
-
// 5.6 对外扩后的辉光判遮挡(输出到独立 target,绝不回写 blur1,避免步骤 6 相减归零)
|
|
573
|
-
renderer.setRenderTarget(blurDepthTestTextureTarget);
|
|
574
|
-
renderer.clear();
|
|
575
|
-
depthTestShader.uniforms.map.value = blur1TextureTarget.texture;
|
|
576
|
-
depthTestShader.uniforms.baseDepth.value = baseDepthTexture;
|
|
577
|
-
depthTestShader.uniforms.selectDepth.value = selectDepthBlurTextureTarget.texture;
|
|
578
|
-
depthTestShader.uniforms.cameraFar.value = camera.far;
|
|
579
|
-
fsQuad.render(renderer, depthTestShader);
|
|
580
|
-
// 6. 合成到屏幕:filterSelect(blur=上色后且已判遮挡的最终外扩辉光, select=深度测试后本体辉光)
|
|
581
|
-
// = 仅保留辉光外扩环;本体被减掉。⚠️ blur 必须是最终外扩辉光,绝不能被 depthTest 结果覆盖
|
|
488
|
+
// 6. 合成到屏幕:filterSelect(blur=上色后的外扩辉光 blur1, select=深度测试后本体辉光)
|
|
489
|
+
// = 仅保留辉光外扩环;本体被减掉。⚠️ blur 必须是上色后的 blur1,绝不能被别的结果覆盖
|
|
582
490
|
// (早期回归:误把 depthTest 结果上色进 blur1 → filterSelect 相减归零 → 辉光全不显示)。
|
|
491
|
+
// ⭐ 2026-10-25 起外扩环不再做第二次遮挡判定(皇上旨删 5.6),blur1 直接就是最终辉光。
|
|
583
492
|
renderer.setRenderTarget(originRenderTarget);
|
|
584
493
|
filterSelectShader.uniforms.selectTexture.value = selectDepthTestTextureTarget.texture;
|
|
585
|
-
filterSelectShader.uniforms.blurTexture.value =
|
|
494
|
+
filterSelectShader.uniforms.blurTexture.value = blur1TextureTarget.texture;
|
|
586
495
|
filterSelectShader.uniforms.opacity.value = glow_opacity;
|
|
587
496
|
// glow_additive=true 时用加性混合,光晕叠加到画面呈发光感(很亮那种);否则普通半透明覆盖(默认)
|
|
588
497
|
filterSelectShader.blending = glow_additive ? AdditiveBlending : NormalBlending;
|