three-base 2.0.137 → 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 (307) 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 -78
  14. package/FPScontrol.js +1799 -617
  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 -111
  153. package/ThreeBase.js +1202 -656
  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 +99 -25
  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 -13
  256. package/pass/ssao_pass.js +802 -366
  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/pass/emissive_ao_pass.d.ts +0 -13
  305. package/pass/emissive_ao_pass.js +0 -370
  306. package/shaders.d.ts +0 -5
  307. package/shaders.js +0 -93
@@ -1,16 +1,15 @@
1
- /*
2
- * @Author: xiaosihan
3
- * @Date: 2024-01-20 05:10:37
4
- * @Last Modified by: xiaosihan
5
- * @Last Modified time: 2024-01-20 05:10:57
6
- */
7
- import { NoBlending, ShaderChunk, ShaderMaterial, Vector2 } from "three";
8
- // 抗锯齿着色器
9
- const FXAAShaderMaterial = new ShaderMaterial({
10
- uniforms: {
11
- tDiffuse: { value: null }, // 贴图纹理
12
- resolution: { value: new Vector2(1 / 1024, 1 / 1024) }
13
- },
1
+ /*
2
+ * @Author: xiaosihan
3
+ * @Date: 2024-01-20 05:10:37
4
+ * @Last Modified by: xiaosihan
5
+ * @Last Modified time: 2024-01-20 05:10:57
6
+ */
7
+ import { NoBlending, ShaderChunk, ShaderMaterial, Vector2 } from "three";
8
+ const FXAAShaderMaterial = new ShaderMaterial({
9
+ uniforms: {
10
+ tDiffuse: { value: null },
11
+ resolution: { value: new Vector2(1 / 1024, 1 / 1024) }
12
+ },
14
13
  vertexShader: `
15
14
  ${ShaderChunk.common}
16
15
  ${ShaderChunk.logdepthbuf_pars_vertex}
@@ -20,7 +19,7 @@ const FXAAShaderMaterial = new ShaderMaterial({
20
19
  gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
21
20
  ${ShaderChunk.logdepthbuf_vertex}
22
21
  }
23
- `,
22
+ `,
24
23
  fragmentShader: `
25
24
  ${ShaderChunk.logdepthbuf_pars_fragment}
26
25
  precision highp float;
@@ -32,14 +31,6 @@ const FXAAShaderMaterial = new ShaderMaterial({
32
31
  varying vec2 vUv;
33
32
 
34
33
  #ifndef FXAA_DISCARD
35
- //
36
- // Only valid for PC OpenGL currently.
37
- // Probably will not work when FXAA_GREEN_AS_LUMA = 1.
38
- //
39
- // 1 = Use discard on pixels which don't need AA.
40
- // For APIs which enable concurrent TEX+ROP from same surface.
41
- // 0 = Return unchanged color on pixels which don't need AA.
42
- //
43
34
  #define FXAA_DISCARD 0
44
35
  #endif
45
36
 
@@ -50,7 +41,6 @@ const FXAAShaderMaterial = new ShaderMaterial({
50
41
 
51
42
  #define NUM_SAMPLES 5
52
43
 
53
- // assumes colors have premultipliedAlpha, so that the calculated color contrast is scaled by alpha
54
44
  float contrast( vec4 a, vec4 b ) {
55
45
  vec4 diff = abs( a - b );
56
46
  return max( max( max( diff.r, diff.g ), diff.b ), diff.a );
@@ -75,9 +65,6 @@ const FXAAShaderMaterial = new ShaderMaterial({
75
65
  vec4 rgbaE = FxaaTexOff(tex, posM, vec2( 1.0, 0.0), fxaaQualityRcpFrame.xy);
76
66
  vec4 rgbaN = FxaaTexOff(tex, posM, vec2( 0.0,-1.0), fxaaQualityRcpFrame.xy);
77
67
  vec4 rgbaW = FxaaTexOff(tex, posM, vec2(-1.0, 0.0), fxaaQualityRcpFrame.xy);
78
- // . S .
79
- // W M E
80
- // . N .
81
68
 
82
69
  bool earlyExit = max( max( max(
83
70
  contrast( rgbaM, rgbaN ),
@@ -85,9 +72,6 @@ const FXAAShaderMaterial = new ShaderMaterial({
85
72
  contrast( rgbaM, rgbaE ) ),
86
73
  contrast( rgbaM, rgbaW ) )
87
74
  < fxaaQualityEdgeThreshold;
88
- // . 0 .
89
- // 0 0 0
90
- // . 0 .
91
75
 
92
76
  #if (FXAA_DISCARD == 1)
93
77
  if(earlyExit) FxaaDiscard;
@@ -104,44 +88,22 @@ const FXAAShaderMaterial = new ShaderMaterial({
104
88
  relativeVContrast *= fxaaQualityinvEdgeThreshold;
105
89
 
106
90
  bool horzSpan = relativeVContrast > 0.;
107
- // . 1 .
108
- // 0 0 0
109
- // . 1 .
110
91
 
111
- // 45 deg edge detection and corners of objects, aka V/H contrast is too similar
112
92
  if( abs( relativeVContrast ) < .3 ) {
113
- // locate the edge
114
93
  vec2 dirToEdge;
115
94
  dirToEdge.x = contrastE > contrastW ? 1. : -1.;
116
95
  dirToEdge.y = contrastS > contrastN ? 1. : -1.;
117
- // . 2 . . 1 .
118
- // 1 0 2 ~= 0 0 1
119
- // . 1 . . 0 .
120
-
121
- // tap 2 pixels and see which ones are "outside" the edge, to
122
- // determine if the edge is vertical or horizontal
123
96
 
124
97
  vec4 rgbaAlongH = FxaaTexOff(tex, posM, vec2( dirToEdge.x, -dirToEdge.y ), fxaaQualityRcpFrame.xy);
125
98
  float matchAlongH = contrast( rgbaM, rgbaAlongH );
126
- // . 1 .
127
- // 0 0 1
128
- // . 0 H
129
99
 
130
100
  vec4 rgbaAlongV = FxaaTexOff(tex, posM, vec2( -dirToEdge.x, dirToEdge.y ), fxaaQualityRcpFrame.xy);
131
101
  float matchAlongV = contrast( rgbaM, rgbaAlongV );
132
- // V 1 .
133
- // 0 0 1
134
- // . 0 .
135
102
 
136
103
  relativeVContrast = matchAlongV - matchAlongH;
137
104
  relativeVContrast *= fxaaQualityinvEdgeThreshold;
138
105
 
139
- if( abs( relativeVContrast ) < .3 ) { // 45 deg edge
140
- // 1 1 .
141
- // 0 0 1
142
- // . 0 1
143
-
144
- // do a simple blur
106
+ if( abs( relativeVContrast ) < .3 ) {
145
107
  return mix(
146
108
  rgbaM,
147
109
  (rgbaN + rgbaS + rgbaE + rgbaW) * .25,
@@ -154,9 +116,6 @@ const FXAAShaderMaterial = new ShaderMaterial({
154
116
 
155
117
  if(!horzSpan) rgbaN = rgbaW;
156
118
  if(!horzSpan) rgbaS = rgbaE;
157
- // . 0 . 1
158
- // 1 0 1 -> 0
159
- // . 0 . 1
160
119
 
161
120
  bool pairN = contrast( rgbaM, rgbaN ) > contrast( rgbaM, rgbaS );
162
121
  if(!pairN) rgbaN = rgbaS;
@@ -202,15 +161,13 @@ const FXAAShaderMaterial = new ShaderMaterial({
202
161
  }
203
162
 
204
163
 
205
- if ( !doneP && !doneN ) return rgbaM; // failed to find end of edge
164
+ if ( !doneP && !doneN ) return rgbaM;
206
165
 
207
166
  float dist = min(
208
167
  doneN ? float( iterationsUsedN ) / float( NUM_SAMPLES - 1 ) : 1.,
209
168
  doneP ? float( iterationsUsedP ) / float( NUM_SAMPLES - 1 ) : 1.
210
169
  );
211
170
 
212
- // hacky way of reduces blurriness of mostly diagonal edges
213
- // but reduces AA quality
214
171
  dist = pow(dist, .5);
215
172
 
216
173
  dist = 1. - dist;
@@ -230,15 +187,15 @@ const FXAAShaderMaterial = new ShaderMaterial({
230
187
  vUv,
231
188
  tDiffuse,
232
189
  resolution,
233
- edgeDetectionQuality, // [0,1] contrast needed, otherwise early discard
190
+ edgeDetectionQuality,
234
191
  invEdgeDetectionQuality
235
192
  );
236
193
  ${ShaderChunk.logdepthbuf_fragment}
237
194
  }
238
- `,
239
- blending: NoBlending, // 渲染时不与背景融合计算 直接替换
240
- depthTest: false,
241
- depthWrite: false,
242
- transparent: true
243
- });
244
- export default FXAAShaderMaterial;
195
+ `,
196
+ blending: NoBlending,
197
+ depthTest: false,
198
+ depthWrite: false,
199
+ transparent: true
200
+ });
201
+ export default FXAAShaderMaterial;
@@ -0,0 +1,201 @@
1
+ /*
2
+ * @Author: xiaosihan
3
+ * @Date: 2024-01-20 05:10:37
4
+ * @Last Modified by: xiaosihan
5
+ * @Last Modified time: 2024-01-20 05:10:57
6
+ */
7
+ import { NoBlending, ShaderChunk, ShaderMaterial, Vector2 } from "three";
8
+ const FXAAShaderMaterial = new ShaderMaterial({
9
+ uniforms: {
10
+ tDiffuse: { value: null },
11
+ resolution: { value: new Vector2(1 / 1024, 1 / 1024) }
12
+ },
13
+ vertexShader: `
14
+ ${ShaderChunk.common}
15
+ ${ShaderChunk.logdepthbuf_pars_vertex}
16
+ varying vec2 vUv;
17
+ void main() {
18
+ vUv = uv;
19
+ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
20
+ ${ShaderChunk.logdepthbuf_vertex}
21
+ }
22
+ `,
23
+ fragmentShader: `
24
+ ${ShaderChunk.logdepthbuf_pars_fragment}
25
+ precision highp float;
26
+
27
+ uniform sampler2D tDiffuse;
28
+
29
+ uniform vec2 resolution;
30
+
31
+ varying vec2 vUv;
32
+
33
+ #ifndef FXAA_DISCARD
34
+ #define FXAA_DISCARD 0
35
+ #endif
36
+
37
+ /*--------------------------------------------------------------------------*/
38
+ #define FxaaTexTop(t, p) texture2D(t, p, -100.0)
39
+ #define FxaaTexOff(t, p, o, r) texture2D(t, p + (o * r), -100.0)
40
+ /*--------------------------------------------------------------------------*/
41
+
42
+ #define NUM_SAMPLES 5
43
+
44
+ float contrast( vec4 a, vec4 b ) {
45
+ vec4 diff = abs( a - b );
46
+ return max( max( max( diff.r, diff.g ), diff.b ), diff.a );
47
+ }
48
+
49
+ /*============================================================================
50
+
51
+ FXAA3 QUALITY - PC
52
+
53
+ ============================================================================*/
54
+
55
+ /*--------------------------------------------------------------------------*/
56
+ vec4 FxaaPixelShader(
57
+ vec2 posM,
58
+ sampler2D tex,
59
+ vec2 fxaaQualityRcpFrame,
60
+ float fxaaQualityEdgeThreshold,
61
+ float fxaaQualityinvEdgeThreshold
62
+ ) {
63
+ vec4 rgbaM = FxaaTexTop(tex, posM);
64
+ vec4 rgbaS = FxaaTexOff(tex, posM, vec2( 0.0, 1.0), fxaaQualityRcpFrame.xy);
65
+ vec4 rgbaE = FxaaTexOff(tex, posM, vec2( 1.0, 0.0), fxaaQualityRcpFrame.xy);
66
+ vec4 rgbaN = FxaaTexOff(tex, posM, vec2( 0.0,-1.0), fxaaQualityRcpFrame.xy);
67
+ vec4 rgbaW = FxaaTexOff(tex, posM, vec2(-1.0, 0.0), fxaaQualityRcpFrame.xy);
68
+
69
+ bool earlyExit = max( max( max(
70
+ contrast( rgbaM, rgbaN ),
71
+ contrast( rgbaM, rgbaS ) ),
72
+ contrast( rgbaM, rgbaE ) ),
73
+ contrast( rgbaM, rgbaW ) )
74
+ < fxaaQualityEdgeThreshold;
75
+
76
+ #if (FXAA_DISCARD == 1)
77
+ if(earlyExit) FxaaDiscard;
78
+ #else
79
+ if(earlyExit) return rgbaM;
80
+ #endif
81
+
82
+ float contrastN = contrast( rgbaM, rgbaN );
83
+ float contrastS = contrast( rgbaM, rgbaS );
84
+ float contrastE = contrast( rgbaM, rgbaE );
85
+ float contrastW = contrast( rgbaM, rgbaW );
86
+
87
+ float relativeVContrast = ( contrastN + contrastS ) - ( contrastE + contrastW );
88
+ relativeVContrast *= fxaaQualityinvEdgeThreshold;
89
+
90
+ bool horzSpan = relativeVContrast > 0.;
91
+
92
+ if( abs( relativeVContrast ) < .3 ) {
93
+ vec2 dirToEdge;
94
+ dirToEdge.x = contrastE > contrastW ? 1. : -1.;
95
+ dirToEdge.y = contrastS > contrastN ? 1. : -1.;
96
+
97
+ vec4 rgbaAlongH = FxaaTexOff(tex, posM, vec2( dirToEdge.x, -dirToEdge.y ), fxaaQualityRcpFrame.xy);
98
+ float matchAlongH = contrast( rgbaM, rgbaAlongH );
99
+
100
+ vec4 rgbaAlongV = FxaaTexOff(tex, posM, vec2( -dirToEdge.x, dirToEdge.y ), fxaaQualityRcpFrame.xy);
101
+ float matchAlongV = contrast( rgbaM, rgbaAlongV );
102
+
103
+ relativeVContrast = matchAlongV - matchAlongH;
104
+ relativeVContrast *= fxaaQualityinvEdgeThreshold;
105
+
106
+ if( abs( relativeVContrast ) < .3 ) {
107
+ return mix(
108
+ rgbaM,
109
+ (rgbaN + rgbaS + rgbaE + rgbaW) * .25,
110
+ .4
111
+ );
112
+ }
113
+
114
+ horzSpan = relativeVContrast > 0.;
115
+ }
116
+
117
+ if(!horzSpan) rgbaN = rgbaW;
118
+ if(!horzSpan) rgbaS = rgbaE;
119
+
120
+ bool pairN = contrast( rgbaM, rgbaN ) > contrast( rgbaM, rgbaS );
121
+ if(!pairN) rgbaN = rgbaS;
122
+
123
+ vec2 offNP;
124
+ offNP.x = (!horzSpan) ? 0.0 : fxaaQualityRcpFrame.x;
125
+ offNP.y = ( horzSpan) ? 0.0 : fxaaQualityRcpFrame.y;
126
+
127
+ bool doneN = false;
128
+ bool doneP = false;
129
+
130
+ float nDist = 0.;
131
+ float pDist = 0.;
132
+
133
+ vec2 posN = posM;
134
+ vec2 posP = posM;
135
+
136
+ int iterationsUsed = 0;
137
+ int iterationsUsedN = 0;
138
+ int iterationsUsedP = 0;
139
+ for( int i = 0; i < NUM_SAMPLES; i++ ) {
140
+ iterationsUsed = i;
141
+
142
+ float increment = float(i + 1);
143
+
144
+ if(!doneN) {
145
+ nDist += increment;
146
+ posN = posM + offNP * nDist;
147
+ vec4 rgbaEndN = FxaaTexTop(tex, posN.xy);
148
+ doneN = contrast( rgbaEndN, rgbaM ) > contrast( rgbaEndN, rgbaN );
149
+ iterationsUsedN = i;
150
+ }
151
+
152
+ if(!doneP) {
153
+ pDist += increment;
154
+ posP = posM - offNP * pDist;
155
+ vec4 rgbaEndP = FxaaTexTop(tex, posP.xy);
156
+ doneP = contrast( rgbaEndP, rgbaM ) > contrast( rgbaEndP, rgbaN );
157
+ iterationsUsedP = i;
158
+ }
159
+
160
+ if(doneN || doneP) break;
161
+ }
162
+
163
+
164
+ if ( !doneP && !doneN ) return rgbaM;
165
+
166
+ float dist = min(
167
+ doneN ? float( iterationsUsedN ) / float( NUM_SAMPLES - 1 ) : 1.,
168
+ doneP ? float( iterationsUsedP ) / float( NUM_SAMPLES - 1 ) : 1.
169
+ );
170
+
171
+ dist = pow(dist, .5);
172
+
173
+ dist = 1. - dist;
174
+
175
+ return mix(
176
+ rgbaM,
177
+ rgbaN,
178
+ dist * .5
179
+ );
180
+ }
181
+
182
+ void main() {
183
+ const float edgeDetectionQuality = .2;
184
+ const float invEdgeDetectionQuality = 1. / edgeDetectionQuality;
185
+
186
+ gl_FragColor = FxaaPixelShader(
187
+ vUv,
188
+ tDiffuse,
189
+ resolution,
190
+ edgeDetectionQuality,
191
+ invEdgeDetectionQuality
192
+ );
193
+ ${ShaderChunk.logdepthbuf_fragment}
194
+ }
195
+ `,
196
+ blending: NoBlending,
197
+ depthTest: false,
198
+ depthWrite: false,
199
+ transparent: true
200
+ });
201
+ export default FXAAShaderMaterial;
@@ -0,0 +1,11 @@
1
+ import { ShaderMaterial } from "three";
2
+ /**
3
+ * 调试用:把 baseDepthTexture(可见深度图)直接以灰度输出到屏幕。
4
+ * 对数深度:近=0(黑) 远=1(白)。
5
+ * - 全屏纯白 → 深度图为空(全 clear 1.0),说明 renderAoDepthPass 没把深度写进 baseDepthTexture;
6
+ * 此时所有依赖深度遮挡的后处理(stroke/glow/cover/frosted)都会"一律显示在前"。
7
+ * - 有灰阶/明暗 → 深度图正常,问题在比对侧(selectDepth / depthTestShader)。
8
+ * 触发:在控制台执行 `window.__BASE_DEPTH_VIS = true` 后画面即切到该视图。
9
+ */
10
+ declare const baseDepthVisShader: ShaderMaterial;
11
+ export default baseDepthVisShader;
@@ -0,0 +1,36 @@
1
+ import { ShaderChunk, ShaderMaterial } from "three";
2
+ /**
3
+ * 调试用:把 baseDepthTexture(可见深度图)直接以灰度输出到屏幕。
4
+ * 对数深度:近=0(黑) 远=1(白)。
5
+ * - 全屏纯白 → 深度图为空(全 clear 1.0),说明 renderAoDepthPass 没把深度写进 baseDepthTexture;
6
+ * 此时所有依赖深度遮挡的后处理(stroke/glow/cover/frosted)都会"一律显示在前"。
7
+ * - 有灰阶/明暗 → 深度图正常,问题在比对侧(selectDepth / depthTestShader)。
8
+ * 触发:在控制台执行 `window.__BASE_DEPTH_VIS = true` 后画面即切到该视图。
9
+ */
10
+ const baseDepthVisShader = new ShaderMaterial({
11
+ uniforms: {
12
+ tDepth: { value: null },
13
+ },
14
+ vertexShader: `
15
+ ${ShaderChunk.common}
16
+ ${ShaderChunk.logdepthbuf_pars_vertex}
17
+ varying vec2 vUv;
18
+ void main() {
19
+ vUv = uv;
20
+ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
21
+ ${ShaderChunk.logdepthbuf_vertex}
22
+ }
23
+ `,
24
+ fragmentShader: `
25
+ uniform sampler2D tDepth;
26
+ varying vec2 vUv;
27
+ void main() {
28
+ float d = texture2D(tDepth, vUv).r;
29
+ gl_FragColor = vec4(d, d, d, 1.0);
30
+ }
31
+ `,
32
+ depthTest: false,
33
+ depthWrite: false,
34
+ transparent: true,
35
+ });
36
+ export default baseDepthVisShader;
@@ -0,0 +1,36 @@
1
+ import { ShaderChunk, ShaderMaterial } from "three";
2
+ /**
3
+ * 调试用:把 baseDepthTexture(可见深度图)直接以灰度输出到屏幕。
4
+ * 对数深度:近=0(黑) 远=1(白)。
5
+ * - 全屏纯白 → 深度图为空(全 clear 1.0),说明 renderAoDepthPass 没把深度写进 baseDepthTexture;
6
+ * 此时所有依赖深度遮挡的后处理(stroke/glow/cover/frosted)都会"一律显示在前"。
7
+ * - 有灰阶/明暗 → 深度图正常,问题在比对侧(selectDepth / depthTestShader)。
8
+ * 触发:在控制台执行 `window.__BASE_DEPTH_VIS = true` 后画面即切到该视图。
9
+ */
10
+ const baseDepthVisShader = new ShaderMaterial({
11
+ uniforms: {
12
+ tDepth: { value: null as unknown as import("three").Texture },
13
+ },
14
+ vertexShader: `
15
+ ${ShaderChunk.common}
16
+ ${ShaderChunk.logdepthbuf_pars_vertex}
17
+ varying vec2 vUv;
18
+ void main() {
19
+ vUv = uv;
20
+ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
21
+ ${ShaderChunk.logdepthbuf_vertex}
22
+ }
23
+ `,
24
+ fragmentShader: `
25
+ uniform sampler2D tDepth;
26
+ varying vec2 vUv;
27
+ void main() {
28
+ float d = texture2D(tDepth, vUv).r;
29
+ gl_FragColor = vec4(d, d, d, 1.0);
30
+ }
31
+ `,
32
+ depthTest: false,
33
+ depthWrite: false,
34
+ transparent: true,
35
+ });
36
+ export default baseDepthVisShader;
@@ -1,2 +1,2 @@
1
- import { ShaderMaterial } from "three";
2
- export declare const baseTextureToRenderShader: ShaderMaterial;
1
+ import { ShaderMaterial } from "three";
2
+ export declare const baseTextureToRenderShader: ShaderMaterial;
@@ -1,10 +1,11 @@
1
- import { ShaderMaterial, Vector2, ShaderChunk, NoBlending } from "three";
2
- // 渲染目标绘制到渲染器着色器
3
- export const baseTextureToRenderShader = new ShaderMaterial({
4
- uniforms: {
5
- tDiffuse: { value: null }, // 贴图纹理
6
- resolution: { value: new Vector2(1 / 1024, 1 / 1024) }
7
- },
1
+ import { ShaderMaterial, Vector2, ShaderChunk, NoBlending } from "three";
2
+ export const baseTextureToRenderShader = new ShaderMaterial({
3
+ uniforms: {
4
+ tDiffuse: { value: null },
5
+ resolution: { value: new Vector2(1 / 1024, 1 / 1024) },
6
+ /** 抖动强度:1.0 = 标准 ±0.5 LSB(总跨度 1/255),0 = 关闭(A/B 对比用) */
7
+ uDitherStrength: { value: 1.0 }
8
+ },
8
9
  vertexShader: `
9
10
  ${ShaderChunk.common}
10
11
  ${ShaderChunk.logdepthbuf_pars_vertex}
@@ -14,7 +15,7 @@ export const baseTextureToRenderShader = new ShaderMaterial({
14
15
  gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
15
16
  ${ShaderChunk.logdepthbuf_vertex}
16
17
  }
17
- `,
18
+ `,
18
19
  fragmentShader: `
19
20
  ${ShaderChunk.logdepthbuf_pars_fragment}
20
21
  precision highp float;
@@ -23,17 +24,30 @@ export const baseTextureToRenderShader = new ShaderMaterial({
23
24
 
24
25
  uniform vec2 resolution;
25
26
 
27
+ /** 抖动强度(1.0 = ±0.5 LSB;0 = 关闭) */
28
+ uniform float uDitherStrength;
29
+
26
30
  varying vec2 vUv;
27
31
 
32
+ /**
33
+ * 交错梯度噪声 Interleaved Gradient Noise,返回 [0,1)。
34
+ *
35
+ * 为什么不用 Bayer 有序矩阵(2026-09-06 皇上反馈「辉光透明度不对」后改):
36
+ * Bayer 是 8×8 块状循环图案,在大面积柔和渐变(外辉光/天空/雾)上会形成**肉眼可见的规则
37
+ * 网格/点阵**,把自然的透明度渐变打成"脏"的质感;辉光暗部(R 仅 16~47)一个码值就是
38
+ * 2%~6% 跳变,网格尤其明显。IGN 是高频交错梯度,没有块状结构,人眼几乎察觉不到。
39
+ *
40
+ * 为什么不用 sin()/大数 fract() 版哈希(如 hash12):它依赖 fract(4531.99) 这类大数的
41
+ * 小数位精度,在不同 GPU / 驱动 / 精度限定符(mediump vs highp)下行为不一致,
42
+ * 存在退化成常数的风险(一旦退化,抖动就变成恒定偏移,色带一根没少)。
43
+ * IGN 内部最大值约 52.98,精度安全边际大得多。
44
+ * ⚠️ 澄清:Bayer 被替换**不是**因为精度(实测大坐标下不退化),纯粹是块状网格的观感问题。
45
+ */
46
+ float ign(vec2 p) {
47
+ return fract(52.9829189 * fract(0.06711056 * p.x + 0.00583715 * p.y));
48
+ }
49
+
28
50
  #ifndef FXAA_DISCARD
29
- //
30
- // Only valid for PC OpenGL currently.
31
- // Probably will not work when FXAA_GREEN_AS_LUMA = 1.
32
- //
33
- // 1 = Use discard on pixels which don't need AA.
34
- // For APIs which enable concurrent TEX+ROP from same surface.
35
- // 0 = Return unchanged color on pixels which don't need AA.
36
- //
37
51
  #define FXAA_DISCARD 0
38
52
  #endif
39
53
 
@@ -44,7 +58,6 @@ export const baseTextureToRenderShader = new ShaderMaterial({
44
58
 
45
59
  #define NUM_SAMPLES 5
46
60
 
47
- // assumes colors have premultipliedAlpha, so that the calculated color contrast is scaled by alpha
48
61
  float contrast( vec4 a, vec4 b ) {
49
62
  vec4 diff = abs( a - b );
50
63
  return max( max( max( diff.r, diff.g ), diff.b ), diff.a );
@@ -69,9 +82,6 @@ export const baseTextureToRenderShader = new ShaderMaterial({
69
82
  vec4 rgbaE = FxaaTexOff(tex, posM, vec2( 1.0, 0.0), fxaaQualityRcpFrame.xy);
70
83
  vec4 rgbaN = FxaaTexOff(tex, posM, vec2( 0.0,-1.0), fxaaQualityRcpFrame.xy);
71
84
  vec4 rgbaW = FxaaTexOff(tex, posM, vec2(-1.0, 0.0), fxaaQualityRcpFrame.xy);
72
- // . S .
73
- // W M E
74
- // . N .
75
85
 
76
86
  bool earlyExit = max( max( max(
77
87
  contrast( rgbaM, rgbaN ),
@@ -79,9 +89,6 @@ export const baseTextureToRenderShader = new ShaderMaterial({
79
89
  contrast( rgbaM, rgbaE ) ),
80
90
  contrast( rgbaM, rgbaW ) )
81
91
  < fxaaQualityEdgeThreshold;
82
- // . 0 .
83
- // 0 0 0
84
- // . 0 .
85
92
 
86
93
  #if (FXAA_DISCARD == 1)
87
94
  if(earlyExit) FxaaDiscard;
@@ -98,44 +105,22 @@ export const baseTextureToRenderShader = new ShaderMaterial({
98
105
  relativeVContrast *= fxaaQualityinvEdgeThreshold;
99
106
 
100
107
  bool horzSpan = relativeVContrast > 0.;
101
- // . 1 .
102
- // 0 0 0
103
- // . 1 .
104
108
 
105
- // 45 deg edge detection and corners of objects, aka V/H contrast is too similar
106
109
  if( abs( relativeVContrast ) < .3 ) {
107
- // locate the edge
108
110
  vec2 dirToEdge;
109
111
  dirToEdge.x = contrastE > contrastW ? 1. : -1.;
110
112
  dirToEdge.y = contrastS > contrastN ? 1. : -1.;
111
- // . 2 . . 1 .
112
- // 1 0 2 ~= 0 0 1
113
- // . 1 . . 0 .
114
-
115
- // tap 2 pixels and see which ones are "outside" the edge, to
116
- // determine if the edge is vertical or horizontal
117
113
 
118
114
  vec4 rgbaAlongH = FxaaTexOff(tex, posM, vec2( dirToEdge.x, -dirToEdge.y ), fxaaQualityRcpFrame.xy);
119
115
  float matchAlongH = contrast( rgbaM, rgbaAlongH );
120
- // . 1 .
121
- // 0 0 1
122
- // . 0 H
123
116
 
124
117
  vec4 rgbaAlongV = FxaaTexOff(tex, posM, vec2( -dirToEdge.x, dirToEdge.y ), fxaaQualityRcpFrame.xy);
125
118
  float matchAlongV = contrast( rgbaM, rgbaAlongV );
126
- // V 1 .
127
- // 0 0 1
128
- // . 0 .
129
119
 
130
120
  relativeVContrast = matchAlongV - matchAlongH;
131
121
  relativeVContrast *= fxaaQualityinvEdgeThreshold;
132
122
 
133
- if( abs( relativeVContrast ) < .3 ) { // 45 deg edge
134
- // 1 1 .
135
- // 0 0 1
136
- // . 0 1
137
-
138
- // do a simple blur
123
+ if( abs( relativeVContrast ) < .3 ) {
139
124
  return mix(
140
125
  rgbaM,
141
126
  (rgbaN + rgbaS + rgbaE + rgbaW) * .25,
@@ -148,9 +133,6 @@ export const baseTextureToRenderShader = new ShaderMaterial({
148
133
 
149
134
  if(!horzSpan) rgbaN = rgbaW;
150
135
  if(!horzSpan) rgbaS = rgbaE;
151
- // . 0 . 1
152
- // 1 0 1 -> 0
153
- // . 0 . 1
154
136
 
155
137
  bool pairN = contrast( rgbaM, rgbaN ) > contrast( rgbaM, rgbaS );
156
138
  if(!pairN) rgbaN = rgbaS;
@@ -196,15 +178,13 @@ export const baseTextureToRenderShader = new ShaderMaterial({
196
178
  }
197
179
 
198
180
 
199
- if ( !doneP && !doneN ) return rgbaM; // failed to find end of edge
181
+ if ( !doneP && !doneN ) return rgbaM;
200
182
 
201
183
  float dist = min(
202
184
  doneN ? float( iterationsUsedN ) / float( NUM_SAMPLES - 1 ) : 1.,
203
185
  doneP ? float( iterationsUsedP ) / float( NUM_SAMPLES - 1 ) : 1.
204
186
  );
205
187
 
206
- // hacky way of reduces blurriness of mostly diagonal edges
207
- // but reduces AA quality
208
188
  dist = pow(dist, .5);
209
189
 
210
190
  dist = 1. - dist;
@@ -220,18 +200,33 @@ export const baseTextureToRenderShader = new ShaderMaterial({
220
200
  const float edgeDetectionQuality = .2;
221
201
  const float invEdgeDetectionQuality = 1. / edgeDetectionQuality;
222
202
 
223
- gl_FragColor = sRGBTransferOETF(FxaaPixelShader(
203
+ vec4 srgbColor = sRGBTransferOETF(FxaaPixelShader(
224
204
  vUv,
225
205
  tDiffuse,
226
206
  resolution,
227
- edgeDetectionQuality, // [0,1] contrast needed, otherwise early discard
207
+ edgeDetectionQuality,
228
208
  invEdgeDetectionQuality
229
209
  ));
210
+
211
+ // ---- 终处理抖动(dither):消除 8bit 输出量化的色带 ----
212
+ // 屏幕 framebuffer 只有 8bit,柔和渐变(外辉光/天空/雾/bloom 衰减)在此被量化成
213
+ // 肉眼可见的"一层一层"台阶。叠加 ±0.5 LSB(总跨度 1/255)的屏幕空间随机噪声后,
214
+ // 台阶被打散成高频颗粒——人眼对高频噪声极不敏感,色带随即消失(2026-09-06 修)。
215
+ // 注意:dither 只补偿「最终 8bit 输出」这一步;中间 RT 的线性量化色带由
216
+ // ThreeBase 的 baseRenderTarget/screenRenderTarget 改 HalfFloatType 根治。
217
+ // 二者缺一不可:半浮点恢复渐变连续性,dither 消除「源数据动态范围不足」型色带
218
+ // (如 SpriteText3 外辉光 R 通道在源图只有 39~46 共 8 个码值,34px 上必然每 5px 一跳)。
219
+ float dither = (ign(gl_FragCoord.xy) - 0.5) * (1.0 / 255.0) * uDitherStrength;
220
+ gl_FragColor = vec4(srgbColor.rgb + dither, srgbColor.a);
230
221
  ${ShaderChunk.logdepthbuf_fragment}
231
222
  }
232
- `,
233
- blending: NoBlending, // 渲染时不与背景融合计算 直接替换
234
- depthTest: false,
235
- depthWrite: false,
236
- transparent: true
237
- });
223
+ `,
224
+ blending: NoBlending,
225
+ depthTest: false,
226
+ depthWrite: false,
227
+ transparent: true,
228
+ // 终处理:手写 sRGBTransferOETF 已是唯一一次 sRGB 编码;关闭 three 的自动 tonemap/colorspace 注入,
229
+ // 防止渲染到屏幕时被 three 再编码一次(本 ShaderMaterial 不写 include 块,three 本就不会注入,
230
+ // 这里显式置 false 仅是防御,保证颜色空间语义单一可控)。
231
+ toneMapped: false,
232
+ });