three-base 2.0.134 → 2.0.142

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (305) hide show
  1. package/DirectionalLight.d.ts +6 -6
  2. package/DirectionalLight.js +68 -68
  3. package/DirectionalLight.ts +70 -0
  4. package/EventMap.d.ts +103 -0
  5. package/EventMap.js +17 -0
  6. package/EventMap.ts +139 -0
  7. package/EventMesh.d.ts +18 -18
  8. package/EventMesh.js +59 -59
  9. package/EventMesh.ts +60 -0
  10. package/ExtrudeMesh.d.ts +112 -112
  11. package/ExtrudeMesh.js +342 -366
  12. package/ExtrudeMesh.ts +553 -0
  13. package/FPScontrol.d.ts +511 -71
  14. package/FPScontrol.js +1799 -505
  15. package/FPScontrol.ts +1855 -0
  16. package/Fire/Fire.d.ts +28 -28
  17. package/Fire/Fire.js +80 -79
  18. package/Fire/Fire.ts +89 -0
  19. package/Fire/{FireGromtry.d.ts → FireGeometry.d.ts} +9 -9
  20. package/Fire/{FireGromtry.js → FireGeometry.js} +40 -40
  21. package/Fire/FireGeometry.ts +40 -0
  22. package/Fire/FireMaterial.d.ts +28 -28
  23. package/Fire/FireMaterial.js +32 -32
  24. package/Fire/FireMaterial.ts +89 -0
  25. package/Fire/index.d.ts +2 -1
  26. package/Fire/index.js +2 -1
  27. package/Fire/index.ts +2 -0
  28. package/GLTFDracoLoader.d.ts +71 -0
  29. package/GLTFDracoLoader.js +266 -0
  30. package/GLTFDracoLoader.ts +430 -0
  31. package/Grass/Grass.d.ts +8 -8
  32. package/Grass/Grass.js +38 -38
  33. package/Grass/Grass.ts +38 -0
  34. package/Grass/index.d.ts +2 -1
  35. package/Grass/index.js +2 -1
  36. package/Grass/index.ts +2 -0
  37. package/Ground1/Ground1.d.ts +10 -11
  38. package/Ground1/Ground1.js +95 -91
  39. package/Ground1/Ground1.ts +114 -0
  40. package/Ground1/index.d.ts +1 -1
  41. package/Ground1/index.js +1 -1
  42. package/Ground1/index.ts +1 -0
  43. package/MeshBase.d.ts +36 -35
  44. package/MeshBase.js +247 -223
  45. package/MeshBase.ts +253 -0
  46. package/Mirror.d.ts +25 -25
  47. package/Mirror.js +143 -139
  48. package/Mirror.ts +203 -0
  49. package/MktMesh/MktMesh.d.ts +291 -0
  50. package/MktMesh/MktMesh.js +1045 -0
  51. package/MktMesh/MktMesh.ts +1075 -0
  52. package/MktMesh/assetUrl.d.ts +35 -0
  53. package/MktMesh/assetUrl.js +69 -0
  54. package/MktMesh/assetUrl.ts +69 -0
  55. package/MktMesh/mktMappingShader.d.ts +12 -0
  56. package/MktMesh/mktMappingShader.js +139 -0
  57. package/MktMesh/mktMappingShader.ts +139 -0
  58. package/MktMesh/mktShader.d.ts +263 -0
  59. package/MktMesh/mktShader.js +1248 -0
  60. package/MktMesh/mktShader.ts +1344 -0
  61. package/MktMesh/panoBitmapTexture.d.ts +25 -0
  62. package/MktMesh/panoBitmapTexture.js +52 -0
  63. package/MktMesh/panoBitmapTexture.ts +54 -0
  64. package/MktMesh/panoSlotBind.d.ts +29 -0
  65. package/MktMesh/panoSlotBind.js +106 -0
  66. package/MktMesh/panoSlotBind.ts +153 -0
  67. package/MktMesh/panoSlotRoster.d.ts +22 -0
  68. package/MktMesh/panoSlotRoster.js +169 -0
  69. package/MktMesh/panoSlotRoster.ts +168 -0
  70. package/MktMesh/panoTileStitcher.d.ts +119 -0
  71. package/MktMesh/panoTileStitcher.js +533 -0
  72. package/MktMesh/panoTileStitcher.ts +616 -0
  73. package/MktMesh/types.d.ts +75 -0
  74. package/MktMesh/types.js +1 -0
  75. package/MktMesh/types.ts +87 -0
  76. package/MktMesh/wallCapTessellate.d.ts +33 -0
  77. package/MktMesh/wallCapTessellate.js +97 -0
  78. package/MktMesh/wallCapTessellate.ts +68 -0
  79. package/PipeMesh/PathGeometry.d.ts +44 -44
  80. package/PipeMesh/PathGeometry.js +307 -300
  81. package/PipeMesh/PathGeometry.ts +343 -0
  82. package/PipeMesh/PathPoint.d.ts +17 -17
  83. package/PipeMesh/PathPoint.js +31 -31
  84. package/PipeMesh/PathPoint.ts +36 -0
  85. package/PipeMesh/PathPointList.d.ts +31 -31
  86. package/PipeMesh/PathPointList.js +209 -208
  87. package/PipeMesh/PathPointList.ts +227 -0
  88. package/PipeMesh/PathTubeGeometry.d.ts +25 -25
  89. package/PipeMesh/PathTubeGeometry.js +130 -130
  90. package/PipeMesh/PathTubeGeometry.ts +146 -0
  91. package/PipeMesh/PipeMesh.d.ts +25 -25
  92. package/PipeMesh/PipeMesh.js +63 -63
  93. package/PipeMesh/PipeMesh.ts +76 -0
  94. package/PipeMesh/index.d.ts +1 -1
  95. package/PipeMesh/index.js +1 -1
  96. package/PipeMesh/index.ts +1 -0
  97. package/PlaneModal1/PlaneModal1.d.ts +34 -31
  98. package/PlaneModal1/PlaneModal1.js +109 -105
  99. package/PlaneModal1/PlaneModal1.ts +138 -0
  100. package/PlaneModal1/index.d.ts +1 -1
  101. package/PlaneModal1/index.js +1 -1
  102. package/PlaneModal1/index.ts +1 -0
  103. package/PlaneText.d.ts +27 -39
  104. package/PlaneText.js +35 -30
  105. package/PlaneText.ts +55 -0
  106. package/PlaneWithHtml.d.ts +13 -11
  107. package/PlaneWithHtml.js +64 -63
  108. package/PlaneWithHtml.ts +70 -0
  109. package/PointLight/PointLight.d.ts +13 -14
  110. package/PointLight/PointLight.js +64 -70
  111. package/PointLight/PointLight.ts +67 -0
  112. package/PointLight/index.d.ts +1 -1
  113. package/PointLight/index.js +1 -1
  114. package/PointLight/index.ts +1 -0
  115. package/README.md +110 -79
  116. package/Sky/Sky.d.ts +9 -9
  117. package/Sky/Sky.js +22 -22
  118. package/Sky/Sky.ts +22 -0
  119. package/Sky/index.d.ts +1 -1
  120. package/Sky/index.js +1 -1
  121. package/Sky/index.ts +1 -0
  122. package/SpotLight.d.ts +6 -6
  123. package/SpotLight.js +72 -72
  124. package/SpotLight.ts +74 -0
  125. package/SpriteModal1/SpriteModal1.d.ts +33 -30
  126. package/SpriteModal1/SpriteModal1.js +116 -110
  127. package/SpriteModal1/SpriteModal1.ts +146 -0
  128. package/SpriteModal1/index.d.ts +1 -1
  129. package/SpriteModal1/index.js +1 -1
  130. package/SpriteModal1/index.ts +1 -0
  131. package/SpriteText.d.ts +46 -45
  132. package/SpriteText.js +176 -163
  133. package/SpriteText.ts +205 -0
  134. package/SpriteText2.d.ts +48 -47
  135. package/SpriteText2.js +223 -198
  136. package/SpriteText2.ts +258 -0
  137. package/SpriteText3.d.ts +86 -0
  138. package/SpriteText3.js +519 -0
  139. package/SpriteText3.ts +599 -0
  140. package/SpriteWithHtml.d.ts +9 -7
  141. package/SpriteWithHtml.js +44 -44
  142. package/SpriteWithHtml.ts +50 -0
  143. package/Text3D/Text3D.d.ts +20 -20
  144. package/Text3D/Text3D.js +58 -62
  145. package/Text3D/Text3D.ts +77 -0
  146. package/Text3D/fontController.d.ts +60 -59
  147. package/Text3D/fontController.js +166 -199
  148. package/Text3D/fontController.ts +209 -0
  149. package/Text3D/index.d.ts +1 -1
  150. package/Text3D/index.js +1 -1
  151. package/Text3D/index.ts +1 -0
  152. package/ThreeBase.d.ts +248 -97
  153. package/ThreeBase.js +1202 -613
  154. package/ThreeBase.ts +1314 -0
  155. package/ThreeMouse.d.ts +54 -40
  156. package/ThreeMouse.js +453 -407
  157. package/ThreeMouse.ts +472 -0
  158. package/Transition.d.ts +45 -40
  159. package/Transition.js +209 -210
  160. package/Transition.ts +242 -0
  161. package/Water/Water.d.ts +5 -5
  162. package/Water/Water.js +44 -26
  163. package/Water/Water.ts +45 -0
  164. package/Water/index.d.ts +2 -0
  165. package/Water/index.js +2 -0
  166. package/Water/index.ts +2 -0
  167. package/WaterFlow/FloatingDuck.d.ts +88 -0
  168. package/WaterFlow/FloatingDuck.js +307 -0
  169. package/WaterFlow/FloatingDuck.ts +445 -0
  170. package/WaterFlow/GPUFluidSimulation.d.ts +56 -0
  171. package/WaterFlow/GPUFluidSimulation.js +785 -0
  172. package/WaterFlow/GPUFluidSimulation.ts +827 -0
  173. package/WaterFlow/ReservoirSystem.d.ts +106 -0
  174. package/WaterFlow/ReservoirSystem.js +621 -0
  175. package/WaterFlow/ReservoirSystem.ts +754 -0
  176. package/WaterFlow/SPHField.d.ts +35 -0
  177. package/WaterFlow/SPHField.js +204 -0
  178. package/WaterFlow/SPHField.ts +228 -0
  179. package/WaterFlow/ScreenSpaceFluidPass.d.ts +69 -0
  180. package/WaterFlow/ScreenSpaceFluidPass.js +736 -0
  181. package/WaterFlow/ScreenSpaceFluidPass.ts +789 -0
  182. package/WaterFlow/ShallowWaterSurface.d.ts +45 -0
  183. package/WaterFlow/ShallowWaterSurface.js +441 -0
  184. package/WaterFlow/ShallowWaterSurface.ts +510 -0
  185. package/WaterFlow/WaterFlow.d.ts +87 -0
  186. package/WaterFlow/WaterFlow.js +171 -0
  187. package/WaterFlow/WaterFlow.ts +219 -0
  188. package/WaterFlow/types.d.ts +161 -0
  189. package/WaterFlow/types.js +1 -0
  190. package/WaterFlow/types.ts +189 -0
  191. package/WaterFlow/waterFlowPass.d.ts +3 -0
  192. package/WaterFlow/waterFlowPass.js +20 -0
  193. package/WaterFlow/waterFlowPass.ts +40 -0
  194. package/collisionOBB.d.ts +42 -0
  195. package/collisionOBB.js +112 -0
  196. package/collisionOBB.ts +108 -0
  197. package/declare.d.ts +23 -165
  198. package/index.d.ts +1 -1
  199. package/index.js +1 -2
  200. package/index.ts +1 -0
  201. package/instanced/InstancedBatch.d.ts +57 -0
  202. package/instanced/InstancedBatch.js +348 -0
  203. package/instanced/InstancedBatch.ts +406 -0
  204. package/instanced/InstancedChild.d.ts +174 -0
  205. package/instanced/InstancedChild.js +264 -0
  206. package/instanced/InstancedChild.ts +327 -0
  207. package/instanced/InstancedGroup.d.ts +43 -0
  208. package/instanced/InstancedGroup.js +126 -0
  209. package/instanced/InstancedGroup.ts +137 -0
  210. package/{InstancedMeshBase.d.ts → instanced/InstancedMeshBase.d.ts} +38 -39
  211. package/{InstancedMeshBase.js → instanced/InstancedMeshBase.js} +282 -293
  212. package/instanced/InstancedMeshBase.ts +292 -0
  213. package/instanced/InstancedTemplate.d.ts +46 -0
  214. package/instanced/InstancedTemplate.js +125 -0
  215. package/instanced/InstancedTemplate.ts +188 -0
  216. package/keyControls.d.ts +30 -0
  217. package/{keyContorls.js → keyControls.js} +101 -98
  218. package/keyControls.ts +107 -0
  219. package/lensflare/LensFlare.d.ts +39 -0
  220. package/lensflare/LensFlare.js +373 -0
  221. package/lensflare/LensFlare.ts +448 -0
  222. package/lensflare/lensflare0.png +0 -0
  223. package/lensflare/lensflare3.png +0 -0
  224. package/lensflare/lensflare_custom.png +0 -0
  225. package/lensflare/lensflare_hex_ghost.png +0 -0
  226. package/lensflare/lensflare_hex_main.png +0 -0
  227. package/package.json +101 -26
  228. package/pass/bloom_pass.d.ts +2 -2
  229. package/pass/bloom_pass.js +188 -101
  230. package/pass/bloom_pass.ts +243 -0
  231. package/pass/cover_pass.d.ts +2 -2
  232. package/pass/cover_pass.js +122 -99
  233. package/pass/cover_pass.ts +182 -0
  234. package/pass/debugDepthState.d.ts +20 -0
  235. package/pass/debugDepthState.js +9 -0
  236. package/pass/debugDepthState.ts +22 -0
  237. package/pass/depthTestBias.d.ts +12 -0
  238. package/pass/depthTestBias.js +12 -0
  239. package/pass/depthTestBias.ts +12 -0
  240. package/pass/effectUserData.d.ts +27 -0
  241. package/pass/effectUserData.js +1 -0
  242. package/pass/effectUserData.ts +46 -0
  243. package/pass/frosted_glass_pass.d.ts +2 -2
  244. package/pass/frosted_glass_pass.js +167 -186
  245. package/pass/frosted_glass_pass.ts +288 -0
  246. package/pass/fsQuad.d.ts +9 -9
  247. package/pass/fsQuad.js +28 -28
  248. package/pass/fsQuad.ts +34 -0
  249. package/pass/glow_pass.d.ts +2 -2
  250. package/pass/glow_pass.js +449 -233
  251. package/pass/glow_pass.ts +654 -0
  252. package/pass/screen_bloom_pass.d.ts +11 -0
  253. package/pass/screen_bloom_pass.js +235 -0
  254. package/pass/screen_bloom_pass.ts +263 -0
  255. package/pass/ssao_pass.d.ts +88 -11
  256. package/pass/ssao_pass.js +802 -288
  257. package/pass/ssao_pass.ts +918 -0
  258. package/pass/stroke_pass.d.ts +2 -2
  259. package/pass/stroke_pass.js +329 -258
  260. package/pass/stroke_pass.ts +638 -0
  261. package/shaders/FXAAShaderMaterial.d.ts +3 -3
  262. package/shaders/FXAAShaderMaterial.js +23 -66
  263. package/shaders/FXAAShaderMaterial.ts +201 -0
  264. package/shaders/baseDepthVisShader.d.ts +11 -0
  265. package/shaders/baseDepthVisShader.js +36 -0
  266. package/shaders/baseDepthVisShader.ts +36 -0
  267. package/shaders/baseTextureToRenderShader.d.ts +2 -2
  268. package/shaders/baseTextureToRenderShader.js +55 -60
  269. package/shaders/baseTextureToRenderShader.ts +232 -0
  270. package/shaders/copyShader.d.ts +3 -3
  271. package/shaders/copyShader.js +13 -14
  272. package/shaders/copyShader.ts +32 -0
  273. package/shaders/debugDepthCompareShader.d.ts +14 -0
  274. package/shaders/debugDepthCompareShader.js +49 -0
  275. package/shaders/debugDepthCompareShader.ts +50 -0
  276. package/shaders/debugDepthJudgeShader.d.ts +18 -0
  277. package/shaders/debugDepthJudgeShader.js +52 -0
  278. package/shaders/debugDepthJudgeShader.ts +54 -0
  279. package/shaders/debugExcludedShader.d.ts +13 -0
  280. package/shaders/debugExcludedShader.js +46 -0
  281. package/shaders/debugExcludedShader.ts +48 -0
  282. package/spriteTextBg.d.ts +1 -0
  283. package/spriteTextBg.js +20 -0
  284. package/spriteTextBg.ts +20 -0
  285. package/threeLoader.d.ts +35 -34
  286. package/threeLoader.js +518 -527
  287. package/threeLoader.ts +525 -0
  288. package/threeUtils.d.ts +53 -52
  289. package/threeUtils.js +329 -330
  290. package/threeUtils.ts +373 -0
  291. package/types.d.ts +2 -0
  292. package/types.js +6 -0
  293. package/types.ts +8 -0
  294. package/ApngTexture.d.ts +0 -13
  295. package/ApngTexture.js +0 -61
  296. package/ApngTextureManage.d.ts +0 -18
  297. package/ApngTextureManage.js +0 -87
  298. package/KeyFrameAnimation.d.ts +0 -25
  299. package/KeyFrameAnimation.js +0 -78
  300. package/keyContorls.d.ts +0 -25
  301. package/lib/draco/draco_decoder.js +0 -34
  302. package/lib/draco/draco_decoder.wasm +0 -0
  303. package/lib/draco/draco_wasm_wrapper.js +0 -117
  304. package/shaders.d.ts +0 -5
  305. package/shaders.js +0 -93
@@ -1,86 +1,118 @@
1
- /*
2
- * @Author: xiaosihan
3
- * @Date: 2023-05-09 00:35:17
4
- * @Last Modified by: xiaosihan
5
- * @Last Modified time: 2025-01-28 04:02:16
6
- */
7
- import { Color, DepthFormat, DepthTexture, LinearFilter, NoBlending, NormalBlending, RGBAFormat, RawShaderMaterial, Scene, ShaderChunk, ShaderMaterial, UnsignedShortType, Vector2, WebGLRenderTarget } from "three";
8
- import fsQuad from "./fsQuad";
9
- // 选中对象的深度纹理
10
- const selectDepthTexture = (() => {
11
- const baseDepthTexture = new DepthTexture(1024, 1024);
12
- baseDepthTexture.format = DepthFormat;
13
- baseDepthTexture.type = UnsignedShortType;
14
- baseDepthTexture.anisotropy = 16;
15
- return baseDepthTexture;
16
- })();
17
- // 选中对象的纹理
18
- const selectTextureTarget = new WebGLRenderTarget(512, 512, {
19
- minFilter: LinearFilter,
20
- magFilter: LinearFilter,
21
- format: RGBAFormat,
22
- depthTexture: selectDepthTexture,
23
- anisotropy: 16,
24
- });
25
- // 深度测试后的选中纹理
26
- const selectDethpTestTextureTarget = new WebGLRenderTarget(512, 512, {
27
- minFilter: LinearFilter,
28
- magFilter: LinearFilter,
29
- format: RGBAFormat,
30
- anisotropy: 16,
31
- });
32
- // 由于不能同时读写自己的纹理
33
- const blur1TextureTarget = new WebGLRenderTarget(512, 512, { minFilter: LinearFilter, magFilter: LinearFilter, format: RGBAFormat });
34
- // 所以需要用2个模糊纹理相互读写
35
- const blur2TextureTarget = new WebGLRenderTarget(512, 512, { minFilter: LinearFilter, magFilter: LinearFilter, format: RGBAFormat });
36
- const size = new Vector2();
37
- //深度比对纹理
38
- const depthTestShader = new ShaderMaterial({
39
- uniforms: {
40
- map: { value: null }, // 贴图纹理
41
- baseDepth: { value: null }, // 整个场景的深度纹理
42
- selectDepth: { value: null }, // 选中的对象深度纹理
43
- },
1
+ /*
2
+ * @Author: xiaosihan
3
+ * @Date: 2023-05-09 00:35:17
4
+ * @Last Modified by: xiaosihan
5
+ * @Last Modified time: 2025-01-28 04:02:16
6
+ */
7
+ import { Color, DepthFormat, DepthTexture, LinearFilter, NoBlending, NormalBlending, RGBAFormat, RawShaderMaterial, Scene, ShaderChunk, ShaderMaterial, UnsignedIntType, Vector2, WebGLRenderTarget } from "three";
8
+ import fsQuad from "./fsQuad";
9
+ import { debugDepthState } from "./debugDepthState";
10
+ import { DEPTH_TEST_BIAS } from "./depthTestBias";
11
+ const selectDepthTexture = (() => {
12
+ const baseDepthTexture = new DepthTexture(1024, 1024);
13
+ baseDepthTexture.format = DepthFormat;
14
+ baseDepthTexture.type = UnsignedIntType;
15
+ baseDepthTexture.anisotropy = 16;
16
+ return baseDepthTexture;
17
+ })();
18
+ const selectTextureTarget = new WebGLRenderTarget(1024, 1024, {
19
+ minFilter: LinearFilter,
20
+ magFilter: LinearFilter,
21
+ format: RGBAFormat,
22
+ anisotropy: 16,
23
+ // 无 MSAA:mask 颜色与下方 selectDepthTextureTarget(深度)必须同为硬边缘,
24
+ // 否则 mask 边缘平滑而深度硬 → depthTestShader 判定边界与 mask 视觉边缘错位,描边边缘锯齿。
25
+ // 边缘抗锯齿统一由 mask 内部 FXAA + 终处理 FXAA 兜底。
26
+ });
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
+ const selectDepthTestTextureTarget = new WebGLRenderTarget(1024, 1024, {
36
+ minFilter: LinearFilter,
37
+ magFilter: LinearFilter,
38
+ format: RGBAFormat,
39
+ anisotropy: 16,
40
+ // 无 MSAA:深度测试 mask 无需抗锯齿,去掉以提速
41
+ });
42
+ const blur1TextureTarget = new WebGLRenderTarget(1024, 1024, { minFilter: LinearFilter, magFilter: LinearFilter, format: RGBAFormat });
43
+ const blur2TextureTarget = new WebGLRenderTarget(1024, 1024, { minFilter: LinearFilter, magFilter: LinearFilter, format: RGBAFormat });
44
+ // 外扩深度临时/结果目标:depthMinBlurShader 把本体深度图随描边一起外扩,
45
+ // 外扩区取邻域最近深度(忽略背景 1.0),使外扩区 selD<1.0,depthTest 才能正确判遮挡(不漏光)。
46
+ const selectDepthBlurTmpTextureTarget = new WebGLRenderTarget(1024, 1024, { minFilter: LinearFilter, magFilter: LinearFilter, format: RGBAFormat });
47
+ const selectDepthBlurTextureTarget = new WebGLRenderTarget(1024, 1024, { minFilter: LinearFilter, magFilter: LinearFilter, format: RGBAFormat });
48
+ // 外扩描边经深度测试后的结果(步骤 5.6):独立 target,避免回写 blur1 触发历史回归 bug
49
+ const blurDepthTestTextureTarget = new WebGLRenderTarget(1024, 1024, { minFilter: LinearFilter, magFilter: LinearFilter, format: RGBAFormat });
50
+ const size = new Vector2();
51
+ const depthTestShader = new ShaderMaterial({
52
+ uniforms: {
53
+ map: { value: null },
54
+ baseDepth: { value: null },
55
+ selectDepth: { value: null },
56
+ cameraFar: { value: 1000.0 },
57
+ uDebugVis: { value: 0.0 },
58
+ },
44
59
  vertexShader: `
45
60
  ${ShaderChunk.common}
46
61
  ${ShaderChunk.logdepthbuf_pars_vertex}
47
62
  varying vec2 vUv;
48
63
  void main() {
49
64
  vUv = uv;
50
- // gl_Position = vec4(position, 1.0);
51
- // gl_Position = projectionMatrix * modelViewMatrix * instanceMatrix * vec4(position, 1.0);
52
65
  gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
53
66
  ${ShaderChunk.logdepthbuf_vertex}
54
67
  }
55
- `,
68
+ `,
56
69
  fragmentShader: `
57
70
  ${ShaderChunk.logdepthbuf_pars_fragment}
58
71
  uniform sampler2D map;
59
72
  uniform sampler2D baseDepth;
60
73
  uniform sampler2D selectDepth;
74
+ uniform float cameraFar;
75
+ uniform float uDebugVis;
61
76
  varying vec2 vUv;
62
- void main() {
63
- if(texture2D(baseDepth, vUv).r < texture2D(selectDepth, vUv).r){
64
- discard;
65
- }
66
- if(texture2D(baseDepth, vUv).r == 1.0){
67
- discard;
68
- }
69
- gl_FragColor = texture2D(map, vUv);
70
- ${ShaderChunk.logdepthbuf_fragment}
77
+ void main() {
78
+ float baseD = texture2D(baseDepth, vUv).r;
79
+ float selD = texture2D(selectDepth, vUv).r;
80
+ // 调试可视化:R=base 线性深度归一化,G=select 线性深度归一化(背景≈1.0)。
81
+ // 全白(R=G≈1)→两路深度全是 clear 值 1.0(没写进数据);全黑→异常。
82
+ if (uDebugVis > 0.5) {
83
+ float vb = pow(cameraFar + 1.0, baseD) - 1.0;
84
+ float vs = pow(cameraFar + 1.0, selD) - 1.0;
85
+ gl_FragColor = vec4(vb / cameraFar, vs / cameraFar, 0.0, 1.0);
86
+ return;
87
+ }
88
+ // 参考手写版 a27bdea 的朴素对数深度比对:DepthTexture 存的是对数深度,
89
+ // 「更小 = 更近」,base 比 select 更近即被真实场景遮挡 → discard。
90
+ // 背景像素 base≈1.0(最远)永远不小于物体深度 selD(<1.0) → 不丢弃,
91
+ // 浮空物体的描边正常显示(不会被天空/空背景整片吃掉,这是早期回归 bug 已修的点)。
92
+ // 加一个极小对数空间容差 bias(≈0.0006)防「选中对象自身像素」因浮点精度被误判遮挡
93
+ // (z-fit 锯齿);真实更近物体的深度差远大于此,不受影响。
94
+ // 用二值 discard 而非软遮挡:相交场景里 base 深度在地板/物体间亚像素抖,
95
+ // 软遮挡的半透明渐隐边缘一抖就明显闪;二值硬边界经后续 4 次 blur + FXAA 柔化更干净。
96
+ // 容差取自单一常量源 DEPTH_TEST_BIAS(调试用 debugDepthJudgeShader 用同一常量,
97
+ // 保证调试视图与真实判定永远一致,不会各写各的导致排查结论错误)。
98
+ const float bias = ${DEPTH_TEST_BIAS};
99
+ if (baseD < selD - bias) {
100
+ discard;
71
101
  }
72
- `,
73
- blending: NoBlending, // 渲染时不与背景融合计算 直接替换
74
- depthTest: true,
75
- depthWrite: true,
76
- transparent: true
77
- });
78
- // 抗锯齿着色器
79
- const FXAAShaderMaterial = new ShaderMaterial({
80
- uniforms: {
81
- tDiffuse: { value: null }, // 贴图纹理
82
- resolution: { value: new Vector2(1 / 1024, 1 / 1024) }
83
- },
102
+ gl_FragColor = texture2D(map, vUv);
103
+ ${ShaderChunk.logdepthbuf_fragment}
104
+ }
105
+ `,
106
+ blending: NoBlending,
107
+ depthTest: true,
108
+ depthWrite: true,
109
+ transparent: true
110
+ });
111
+ const FXAAShaderMaterial = new ShaderMaterial({
112
+ uniforms: {
113
+ tDiffuse: { value: null },
114
+ resolution: { value: new Vector2(1 / 1024, 1 / 1024) }
115
+ },
84
116
  vertexShader: `
85
117
  ${ShaderChunk.common}
86
118
  ${ShaderChunk.logdepthbuf_pars_vertex}
@@ -90,7 +122,7 @@ const FXAAShaderMaterial = new ShaderMaterial({
90
122
  gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
91
123
  ${ShaderChunk.logdepthbuf_vertex}
92
124
  }
93
- `,
125
+ `,
94
126
  fragmentShader: `
95
127
  ${ShaderChunk.logdepthbuf_pars_fragment}
96
128
  precision highp float;
@@ -102,14 +134,6 @@ const FXAAShaderMaterial = new ShaderMaterial({
102
134
  varying vec2 vUv;
103
135
 
104
136
  #ifndef FXAA_DISCARD
105
- //
106
- // Only valid for PC OpenGL currently.
107
- // Probably will not work when FXAA_GREEN_AS_LUMA = 1.
108
- //
109
- // 1 = Use discard on pixels which don't need AA.
110
- // For APIs which enable concurrent TEX+ROP from same surface.
111
- // 0 = Return unchanged color on pixels which don't need AA.
112
- //
113
137
  #define FXAA_DISCARD 0
114
138
  #endif
115
139
 
@@ -120,7 +144,6 @@ const FXAAShaderMaterial = new ShaderMaterial({
120
144
 
121
145
  #define NUM_SAMPLES 5
122
146
 
123
- // assumes colors have premultipliedAlpha, so that the calculated color contrast is scaled by alpha
124
147
  float contrast( vec4 a, vec4 b ) {
125
148
  vec4 diff = abs( a - b );
126
149
  return max( max( max( diff.r, diff.g ), diff.b ), diff.a );
@@ -145,9 +168,6 @@ const FXAAShaderMaterial = new ShaderMaterial({
145
168
  vec4 rgbaE = FxaaTexOff(tex, posM, vec2( 1.0, 0.0), fxaaQualityRcpFrame.xy);
146
169
  vec4 rgbaN = FxaaTexOff(tex, posM, vec2( 0.0,-1.0), fxaaQualityRcpFrame.xy);
147
170
  vec4 rgbaW = FxaaTexOff(tex, posM, vec2(-1.0, 0.0), fxaaQualityRcpFrame.xy);
148
- // . S .
149
- // W M E
150
- // . N .
151
171
 
152
172
  bool earlyExit = max( max( max(
153
173
  contrast( rgbaM, rgbaN ),
@@ -155,9 +175,6 @@ const FXAAShaderMaterial = new ShaderMaterial({
155
175
  contrast( rgbaM, rgbaE ) ),
156
176
  contrast( rgbaM, rgbaW ) )
157
177
  < fxaaQualityEdgeThreshold;
158
- // . 0 .
159
- // 0 0 0
160
- // . 0 .
161
178
 
162
179
  #if (FXAA_DISCARD == 1)
163
180
  if(earlyExit) FxaaDiscard;
@@ -174,44 +191,22 @@ const FXAAShaderMaterial = new ShaderMaterial({
174
191
  relativeVContrast *= fxaaQualityinvEdgeThreshold;
175
192
 
176
193
  bool horzSpan = relativeVContrast > 0.;
177
- // . 1 .
178
- // 0 0 0
179
- // . 1 .
180
194
 
181
- // 45 deg edge detection and corners of objects, aka V/H contrast is too similar
182
195
  if( abs( relativeVContrast ) < .3 ) {
183
- // locate the edge
184
196
  vec2 dirToEdge;
185
197
  dirToEdge.x = contrastE > contrastW ? 1. : -1.;
186
198
  dirToEdge.y = contrastS > contrastN ? 1. : -1.;
187
- // . 2 . . 1 .
188
- // 1 0 2 ~= 0 0 1
189
- // . 1 . . 0 .
190
-
191
- // tap 2 pixels and see which ones are "outside" the edge, to
192
- // determine if the edge is vertical or horizontal
193
199
 
194
200
  vec4 rgbaAlongH = FxaaTexOff(tex, posM, vec2( dirToEdge.x, -dirToEdge.y ), fxaaQualityRcpFrame.xy);
195
201
  float matchAlongH = contrast( rgbaM, rgbaAlongH );
196
- // . 1 .
197
- // 0 0 1
198
- // . 0 H
199
202
 
200
203
  vec4 rgbaAlongV = FxaaTexOff(tex, posM, vec2( -dirToEdge.x, dirToEdge.y ), fxaaQualityRcpFrame.xy);
201
204
  float matchAlongV = contrast( rgbaM, rgbaAlongV );
202
- // V 1 .
203
- // 0 0 1
204
- // . 0 .
205
205
 
206
206
  relativeVContrast = matchAlongV - matchAlongH;
207
207
  relativeVContrast *= fxaaQualityinvEdgeThreshold;
208
208
 
209
- if( abs( relativeVContrast ) < .3 ) { // 45 deg edge
210
- // 1 1 .
211
- // 0 0 1
212
- // . 0 1
213
-
214
- // do a simple blur
209
+ if( abs( relativeVContrast ) < .3 ) {
215
210
  return mix(
216
211
  rgbaM,
217
212
  (rgbaN + rgbaS + rgbaE + rgbaW) * .25,
@@ -224,9 +219,6 @@ const FXAAShaderMaterial = new ShaderMaterial({
224
219
 
225
220
  if(!horzSpan) rgbaN = rgbaW;
226
221
  if(!horzSpan) rgbaS = rgbaE;
227
- // . 0 . 1
228
- // 1 0 1 -> 0
229
- // . 0 . 1
230
222
 
231
223
  bool pairN = contrast( rgbaM, rgbaN ) > contrast( rgbaM, rgbaS );
232
224
  if(!pairN) rgbaN = rgbaS;
@@ -272,15 +264,13 @@ const FXAAShaderMaterial = new ShaderMaterial({
272
264
  }
273
265
 
274
266
 
275
- if ( !doneP && !doneN ) return rgbaM; // failed to find end of edge
267
+ if ( !doneP && !doneN ) return rgbaM;
276
268
 
277
269
  float dist = min(
278
270
  doneN ? float( iterationsUsedN ) / float( NUM_SAMPLES - 1 ) : 1.,
279
271
  doneP ? float( iterationsUsedP ) / float( NUM_SAMPLES - 1 ) : 1.
280
272
  );
281
273
 
282
- // hacky way of reduces blurriness of mostly diagonal edges
283
- // but reduces AA quality
284
274
  dist = pow(dist, .5);
285
275
 
286
276
  dist = 1. - dist;
@@ -300,54 +290,53 @@ const FXAAShaderMaterial = new ShaderMaterial({
300
290
  vUv,
301
291
  tDiffuse,
302
292
  resolution,
303
- edgeDetectionQuality, // [0,1] contrast needed, otherwise early discard
293
+ edgeDetectionQuality,
304
294
  invEdgeDetectionQuality
305
295
  );
306
296
  ${ShaderChunk.logdepthbuf_fragment}
307
297
  }
308
- `,
309
- blending: NoBlending, // 渲染时不与背景融合计算 直接替换
310
- depthTest: false,
311
- depthWrite: false,
312
- transparent: true
313
- });
314
- // 描边着色器
315
- const strokeShader = new RawShaderMaterial({
316
- uniforms: {
317
- tDiffuse: { value: null },
318
- color: { value: new Color("#0f0") }, // 没有被挡住的地方的颜色绿色
319
- width: { value: 1.0 },
320
- opacity: { value: 1.0 },
321
- resolution: { value: new Vector2(1 / 512, 1 / 512) }, // 渲染器的分辨率
322
- offset: {
323
- value: [
324
- new Vector2(0.000, 1.000),
325
- new Vector2(0.259, 0.966),
326
- new Vector2(0.500, 0.866),
327
- new Vector2(0.707, 0.707),
328
- new Vector2(0.866, 0.500),
329
- new Vector2(0.966, 0.259),
330
- new Vector2(1.000, 0.000),
331
- new Vector2(0.966, -0.259),
332
- new Vector2(0.866, -0.500),
333
- new Vector2(0.707, -0.707),
334
- new Vector2(0.500, -0.866),
335
- new Vector2(0.259, -0.966),
336
- new Vector2(0.000, -1.000),
337
- new Vector2(-0.259, -0.966),
338
- new Vector2(-0.500, -0.866),
339
- new Vector2(-0.707, -0.707),
340
- new Vector2(-0.866, -0.500),
341
- new Vector2(-0.966, -0.259),
342
- new Vector2(-1.000, -0.000),
343
- new Vector2(-0.966, 0.259),
344
- new Vector2(-0.866, 0.500),
345
- new Vector2(-0.707, 0.707),
346
- new Vector2(-0.500, 0.866),
347
- new Vector2(-0.259, 0.966)
348
- ]
349
- }
350
- },
298
+ `,
299
+ blending: NoBlending,
300
+ depthTest: false,
301
+ depthWrite: false,
302
+ transparent: true
303
+ });
304
+ const strokeShader = new RawShaderMaterial({
305
+ uniforms: {
306
+ tDiffuse: { value: null },
307
+ color: { value: new Color("#0f0") },
308
+ width: { value: 1.0 },
309
+ opacity: { value: 1.0 },
310
+ resolution: { value: new Vector2(1 / 512, 1 / 512) },
311
+ offset: {
312
+ value: [
313
+ new Vector2(0.000, 1.000),
314
+ new Vector2(0.259, 0.966),
315
+ new Vector2(0.500, 0.866),
316
+ new Vector2(0.707, 0.707),
317
+ new Vector2(0.866, 0.500),
318
+ new Vector2(0.966, 0.259),
319
+ new Vector2(1.000, 0.000),
320
+ new Vector2(0.966, -0.259),
321
+ new Vector2(0.866, -0.500),
322
+ new Vector2(0.707, -0.707),
323
+ new Vector2(0.500, -0.866),
324
+ new Vector2(0.259, -0.966),
325
+ new Vector2(0.000, -1.000),
326
+ new Vector2(-0.259, -0.966),
327
+ new Vector2(-0.500, -0.866),
328
+ new Vector2(-0.707, -0.707),
329
+ new Vector2(-0.866, -0.500),
330
+ new Vector2(-0.966, -0.259),
331
+ new Vector2(-1.000, -0.000),
332
+ new Vector2(-0.966, 0.259),
333
+ new Vector2(-0.866, 0.500),
334
+ new Vector2(-0.707, 0.707),
335
+ new Vector2(-0.500, 0.866),
336
+ new Vector2(-0.259, 0.966)
337
+ ]
338
+ }
339
+ },
351
340
  vertexShader: `
352
341
  attribute vec3 position;
353
342
  attribute vec2 uv;
@@ -355,7 +344,7 @@ const strokeShader = new RawShaderMaterial({
355
344
  void main() {
356
345
  vUv = uv;
357
346
  gl_Position = vec4(position, 1.0);
358
- }`,
347
+ }`,
359
348
  fragmentShader: `
360
349
  #ifdef GL_ES
361
350
  precision highp float;
@@ -367,7 +356,7 @@ const strokeShader = new RawShaderMaterial({
367
356
  uniform vec2 resolution;
368
357
  uniform vec2 offset[24];
369
358
  varying vec2 vUv;
370
- vec2 piexl = resolution * width; // 描边厚度
359
+ vec2 piexl = resolution * width;
371
360
 
372
361
  vec4 stroke(){
373
362
  vec4 blurColor = vec4(0.0);
@@ -391,18 +380,63 @@ const strokeShader = new RawShaderMaterial({
391
380
  } else {
392
381
  gl_FragColor = stroke();
393
382
  }
394
- }`,
395
- blending: NoBlending, // 渲染时不与背景融合计算 直接替换
396
- depthTest: false,
397
- depthWrite: false,
398
- transparent: true
399
- });
400
- // 过滤着色器
401
- const filterSelectShader = new RawShaderMaterial({
402
- uniforms: {
403
- selectTexture: { value: null },
404
- blurTexture: { value: null }
405
- },
383
+ }`,
384
+ blending: NoBlending,
385
+ depthTest: false,
386
+ depthWrite: false,
387
+ transparent: true
388
+ });
389
+ // 深度 min-blur(最近深度,忽略背景 1.0):随描边一起把深度图向外扩,
390
+ // 外扩区 selD = 物体最近深度(<1.0) 而非清屏 1.0,depthTest 在外扩区才能正确判遮挡(不漏光),
391
+ // 同时本体区仍靠 depthTestShader 的 EPSILON 容差防自遮挡闪烁(无缝)。separable(direction 控制 H/V)。
392
+ const depthMinBlurShader = new ShaderMaterial({
393
+ uniforms: {
394
+ tDepth: { value: null },
395
+ resolution: { value: new Vector2(1 / 512, 1 / 512) },
396
+ radius: { value: 1.0 },
397
+ direction: { value: new Vector2(1, 0) },
398
+ },
399
+ vertexShader: `
400
+ ${ShaderChunk.common}
401
+ ${ShaderChunk.logdepthbuf_pars_vertex}
402
+ varying vec2 vUv;
403
+ void main() {
404
+ vUv = uv;
405
+ gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
406
+ ${ShaderChunk.logdepthbuf_vertex}
407
+ }
408
+ `,
409
+ fragmentShader: `
410
+ ${ShaderChunk.logdepthbuf_pars_fragment}
411
+ uniform sampler2D tDepth;
412
+ uniform vec2 resolution;
413
+ uniform float radius;
414
+ uniform vec2 direction;
415
+ varying vec2 vUv;
416
+ void main() {
417
+ float minD = 1.0;
418
+ for (int i = -10; i <= 10; i++) {
419
+ float x = float(i);
420
+ vec2 off = direction * (x * radius * resolution);
421
+ float d = texture2D(tDepth, vUv + off).r;
422
+ if (d < 0.9999) {
423
+ minD = min(minD, d);
424
+ }
425
+ }
426
+ gl_FragColor = vec4(minD, 0.0, 0.0, 1.0);
427
+ ${ShaderChunk.logdepthbuf_fragment}
428
+ }
429
+ `,
430
+ blending: NoBlending,
431
+ depthTest: false,
432
+ depthWrite: false,
433
+ transparent: true,
434
+ });
435
+ const filterSelectShader = new RawShaderMaterial({
436
+ uniforms: {
437
+ selectTexture: { value: null },
438
+ blurTexture: { value: null }
439
+ },
406
440
  vertexShader: `
407
441
  attribute vec3 position;
408
442
  attribute vec2 uv;
@@ -411,7 +445,7 @@ const filterSelectShader = new RawShaderMaterial({
411
445
  vUv = uv;
412
446
  gl_Position = vec4(position, 1.0);
413
447
  }
414
- `,
448
+ `,
415
449
  fragmentShader: `
416
450
  #ifdef GL_ES
417
451
  precision highp float;
@@ -424,28 +458,26 @@ const filterSelectShader = new RawShaderMaterial({
424
458
  gl_FragColor = texture2D(blurTexture, vUv);
425
459
  gl_FragColor.a -= (texture2D(selectTexture, vUv).a);
426
460
  }
427
- `,
428
- blending: NoBlending, // 渲染时不与背景融合计算 直接替换
429
- depthTest: false,
430
- depthWrite: false,
431
- transparent: true
432
- });
433
- const copyShader = new ShaderMaterial({
434
- uniforms: {
435
- map: { value: null }, // 贴图纹理
436
- },
461
+ `,
462
+ blending: NoBlending,
463
+ depthTest: false,
464
+ depthWrite: false,
465
+ transparent: true
466
+ });
467
+ const copyShader = new ShaderMaterial({
468
+ uniforms: {
469
+ map: { value: null },
470
+ },
437
471
  vertexShader: `
438
472
  ${ShaderChunk.common}
439
473
  ${ShaderChunk.logdepthbuf_pars_vertex}
440
474
  varying vec2 vUv;
441
475
  void main() {
442
476
  vUv = uv;
443
- // gl_Position = vec4(position, 1.0);
444
- // gl_Position = projectionMatrix * modelViewMatrix * instanceMatrix * vec4(position, 1.0);
445
477
  gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
446
478
  ${ShaderChunk.logdepthbuf_vertex}
447
479
  }
448
- `,
480
+ `,
449
481
  fragmentShader: `
450
482
  ${ShaderChunk.logdepthbuf_pars_fragment}
451
483
  uniform sampler2D map;
@@ -454,77 +486,116 @@ const copyShader = new ShaderMaterial({
454
486
  gl_FragColor = texture2D(map, vUv);
455
487
  ${ShaderChunk.logdepthbuf_fragment}
456
488
  }
457
- `,
458
- depthTest: true,
459
- depthWrite: true,
460
- transparent: true
461
- });
462
- // 场景对象
463
- const scene = new Scene();
464
- // 对象描边
465
- export default function stroke_pass(renderer, camera, object3d, baseDepthTexture, devicePixelRatio) {
466
- const { stroke_enable = false, stroke_color = "#04fa12", stroke_width = 1 } = object3d.userData;
467
- if (!stroke_enable || stroke_width === 0) {
468
- return;
469
- }
470
- // 保存原帧缓冲区
471
- const originRenderTarget = renderer.getRenderTarget();
472
- // 设置选中目标的帧缓冲区
473
- renderer.getSize(size);
474
- size.multiplyScalar(devicePixelRatio);
475
- selectTextureTarget.setSize(size.x, size.y);
476
- selectDethpTestTextureTarget.setSize(size.x, size.y);
477
- blur1TextureTarget.setSize(size.x, size.y);
478
- blur2TextureTarget.setSize(size.x, size.y);
479
- renderer.setRenderTarget(selectTextureTarget);
480
- scene.children = [object3d];
481
- renderer.clear();
482
- renderer.render(scene, camera);
483
- // 设置描边着色器的分辨率
484
- strokeShader.uniforms.resolution.value.set(1 / size.x, 1 / size.y);
485
- // 设置抗锯齿着色器的分辨率
486
- FXAAShaderMaterial.uniforms.resolution.value.set(1 / size.x, 1 / size.y);
487
- //描边颜色
488
- strokeShader.uniforms.color.value.set(stroke_color);
489
- strokeShader.uniforms.width.value = 1;
490
- //深度测试
491
- renderer.setRenderTarget(selectDethpTestTextureTarget);
492
- renderer.clear();
493
- depthTestShader.uniforms.map.value = selectTextureTarget.texture;
494
- depthTestShader.uniforms.baseDepth.value = baseDepthTexture;
495
- depthTestShader.uniforms.selectDepth.value = selectDepthTexture;
496
- fsQuad.render(renderer, depthTestShader);
497
- //一次描边
498
- renderer.setRenderTarget(blur1TextureTarget);
499
- strokeShader.uniforms.tDiffuse.value = selectDethpTestTextureTarget.texture;
500
- fsQuad.render(renderer, strokeShader);
501
- //二次描边
502
- renderer.setRenderTarget(blur2TextureTarget);
503
- strokeShader.uniforms.tDiffuse.value = blur1TextureTarget.texture;
504
- fsQuad.render(renderer, strokeShader);
505
- for (let i = 0; i < stroke_width - 2; i++) {
506
- //一次描边
507
- renderer.setRenderTarget(blur1TextureTarget);
508
- strokeShader.uniforms.tDiffuse.value = blur2TextureTarget.texture;
509
- fsQuad.render(renderer, strokeShader);
510
- //二次描边
511
- renderer.setRenderTarget(blur2TextureTarget);
512
- strokeShader.uniforms.tDiffuse.value = blur1TextureTarget.texture;
513
- fsQuad.render(renderer, strokeShader);
514
- }
515
- renderer.setRenderTarget(blur1TextureTarget);
516
- copyShader.uniforms.map.value = blur2TextureTarget.texture;
517
- fsQuad.render(renderer, copyShader);
518
- // 还原帧缓冲区 减去原始纹理保留描边
519
- renderer.setRenderTarget(originRenderTarget);
520
- filterSelectShader.uniforms.selectTexture.value = selectDethpTestTextureTarget.texture;
521
- filterSelectShader.uniforms.blurTexture.value = blur1TextureTarget.texture;
522
- filterSelectShader.blending = NormalBlending; // 与有的纹理融合计算 保留前面通道传递下来的纹理
523
- fsQuad.render(renderer, filterSelectShader);
524
- // 调试代码
525
- // renderer.setRenderTarget(null);
526
- // renderer.clearDepth();
527
- // copyShader.uniforms.tDiffuse.value = blur2TextureTarget.texture;
528
- // fsQuad.render(renderer, copyShader);
529
- // return;
530
- }
489
+ `,
490
+ depthTest: true,
491
+ depthWrite: true,
492
+ transparent: true
493
+ });
494
+ const scene = new Scene();
495
+ export default function stroke_pass(renderer, camera, object3d, baseDepthTexture, devicePixelRatio) {
496
+ const { stroke_enable = false, stroke_color = "#04fa12", stroke_width = 1 } = object3d.userData;
497
+ if (!stroke_enable || stroke_width === 0) {
498
+ return;
499
+ }
500
+ const originRenderTarget = renderer.getRenderTarget();
501
+ // 灰度图渲染目标跟随主画面尺寸(= width × effectiveRatio),与 baseRenderTarget 完全一致,
502
+ // 消除灰度图与主画面尺寸不一致导致的放大重采样摩尔纹
503
+ renderer.getSize(size);
504
+ size.multiplyScalar(devicePixelRatio);
505
+ selectTextureTarget.setSize(size.x, size.y);
506
+ selectDepthTextureTarget.setSize(size.x, size.y);
507
+ // 缺陷修复:three r167 的 WebGLRenderTarget.setSize 不会同步 depthTexture,
508
+ // 需手动把 selectDepthTexture 尺寸与全屏 baseDepth 对齐,否则深度比例错位导致描边被错误 discard
509
+ selectDepthTexture.image.width = size.x;
510
+ selectDepthTexture.image.height = size.y;
511
+ selectDepthTexture.needsUpdate = true;
512
+ selectDepthTestTextureTarget.setSize(size.x, size.y);
513
+ blur1TextureTarget.setSize(size.x, size.y);
514
+ blur2TextureTarget.setSize(size.x, size.y);
515
+ selectDepthBlurTmpTextureTarget.setSize(size.x, size.y);
516
+ selectDepthBlurTextureTarget.setSize(size.x, size.y);
517
+ blurDepthTestTextureTarget.setSize(size.x, size.y);
518
+ // 1. 渲染物体本体 mask(灰度)
519
+ renderer.setRenderTarget(selectTextureTarget);
520
+ scene.children = [object3d];
521
+ renderer.clear();
522
+ renderer.render(scene, camera);
523
+ // 2. 渲染物体本体深度(无 MSAA,供 depthTest 判定遮挡)
524
+ renderer.setRenderTarget(selectDepthTextureTarget);
525
+ scene.children = [object3d];
526
+ renderer.clear();
527
+ renderer.render(scene, camera);
528
+ // 调试:把本次渲染的选区深度记到全局调试状态,供面板「辉光深度比对」读取
529
+ debugDepthState.lastSelectDepth = selectDepthTexture;
530
+ // 3. 深度测试(用本体 mask):被真实更近物体挡住的「本体描边」部分 discard。
531
+ // 背景像素 baseDepth≈1.0(最远)永远不小于物体深度 → 不丢弃,浮空物体描边正常显示。
532
+ // 选中对象自身像素 baseD≈selD → 不丢弃,本体描边保留。
533
+ renderer.setRenderTarget(selectDepthTestTextureTarget);
534
+ renderer.clear();
535
+ depthTestShader.uniforms.map.value = selectTextureTarget.texture;
536
+ depthTestShader.uniforms.baseDepth.value = baseDepthTexture;
537
+ depthTestShader.uniforms.selectDepth.value = selectDepthTexture;
538
+ depthTestShader.uniforms.cameraFar.value = camera.far;
539
+ depthTestShader.uniforms.uDebugVis.value = (window.__STROKE_DEPTH_VIS) ? 1.0 : 0.0;
540
+ fsQuad.render(renderer, depthTestShader);
541
+ // 4. 从「深度测试后的本体描边」开始外扩(外扩环自动继承本体遮挡判定 → 不漏光),
542
+ // 描边粗细由 stroke_width 控制的迭代次数决定。
543
+ strokeShader.uniforms.resolution.value.set(1 / size.x, 1 / size.y);
544
+ FXAAShaderMaterial.uniforms.resolution.value.set(1 / size.x, 1 / size.y);
545
+ strokeShader.uniforms.color.value.set(stroke_color);
546
+ strokeShader.uniforms.width.value = 1;
547
+ renderer.setRenderTarget(blur1TextureTarget);
548
+ strokeShader.uniforms.tDiffuse.value = selectDepthTestTextureTarget.texture;
549
+ fsQuad.render(renderer, strokeShader);
550
+ renderer.setRenderTarget(blur2TextureTarget);
551
+ strokeShader.uniforms.tDiffuse.value = blur1TextureTarget.texture;
552
+ fsQuad.render(renderer, strokeShader);
553
+ // 迭代外扩(stroke_width 控制粗细)
554
+ for (let i = 0; i < stroke_width - 2; i++) {
555
+ renderer.setRenderTarget(blur1TextureTarget);
556
+ strokeShader.uniforms.tDiffuse.value = blur2TextureTarget.texture;
557
+ fsQuad.render(renderer, strokeShader);
558
+ renderer.setRenderTarget(blur2TextureTarget);
559
+ strokeShader.uniforms.tDiffuse.value = blur1TextureTarget.texture;
560
+ fsQuad.render(renderer, strokeShader);
561
+ }
562
+ // 5. 最后抗锯齿
563
+ renderer.setRenderTarget(blur1TextureTarget);
564
+ FXAAShaderMaterial.uniforms.tDiffuse.value = blur2TextureTarget.texture;
565
+ fsQuad.render(renderer, FXAAShaderMaterial);
566
+ // 5.5 ⭐ 外扩环深度测试(补齐此前只定义未调用的死代码):
567
+ // 本体深度随描边一起外扩(separable H/V,外扩区取邻域最近深度),
568
+ // 再用它对外扩后的描边做一次 depthTest。
569
+ // 缺了这一步,外扩环(描边的视觉主体)永远不参与遮挡判定 →
570
+ // 物体被挡住时描边依旧从遮挡物前方漏出来("深度测试看起来失效"的真根因之一)。
571
+ depthMinBlurShader.uniforms.resolution.value.set(1 / size.x, 1 / size.y);
572
+ depthMinBlurShader.uniforms.radius.value = Math.max(1, stroke_width);
573
+ // H:直接采 DepthTexture(selectDepthTexture),其 .r 即对数深度
574
+ depthMinBlurShader.uniforms.direction.value.set(1, 0);
575
+ depthMinBlurShader.uniforms.tDepth.value = selectDepthTexture;
576
+ renderer.setRenderTarget(selectDepthBlurTmpTextureTarget);
577
+ fsQuad.render(renderer, depthMinBlurShader);
578
+ // V
579
+ depthMinBlurShader.uniforms.direction.value.set(0, 1);
580
+ depthMinBlurShader.uniforms.tDepth.value = selectDepthBlurTmpTextureTarget.texture;
581
+ renderer.setRenderTarget(selectDepthBlurTextureTarget);
582
+ fsQuad.render(renderer, depthMinBlurShader);
583
+ // 5.6 对外扩后的描边判遮挡:被更近几何挡住的外扩环像素 discard。
584
+ // ⚠️ 输出到独立 target,绝不回写 blur1(历史回归 bug:blur1 被 depthTest 结果覆盖
585
+ // 会导致步骤 6 相减归零、描边全不显示)。
586
+ renderer.setRenderTarget(blurDepthTestTextureTarget);
587
+ renderer.clear();
588
+ depthTestShader.uniforms.map.value = blur1TextureTarget.texture;
589
+ depthTestShader.uniforms.baseDepth.value = baseDepthTexture;
590
+ depthTestShader.uniforms.selectDepth.value = selectDepthBlurTextureTarget.texture;
591
+ depthTestShader.uniforms.cameraFar.value = camera.far;
592
+ depthTestShader.uniforms.uDebugVis.value = 0.0;
593
+ fsQuad.render(renderer, depthTestShader);
594
+ // 6. 合成:最终外扩描边(blurDepthTest,已判遮挡) 减去 深度测试后的本体描边
595
+ // = 仅保留描边外扩环;本体被减掉。filterSelectShader 用 NormalBlending 叠到场景上。
596
+ renderer.setRenderTarget(originRenderTarget);
597
+ filterSelectShader.uniforms.selectTexture.value = selectDepthTestTextureTarget.texture;
598
+ filterSelectShader.uniforms.blurTexture.value = blurDepthTestTextureTarget.texture;
599
+ filterSelectShader.blending = NormalBlending;
600
+ fsQuad.render(renderer, filterSelectShader);
601
+ }