three-base 2.0.21 → 2.0.23

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.
@@ -0,0 +1,248 @@
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
+
10
+
11
+ // 抗锯齿着色器
12
+ const FXAAShaderMaterial = new ShaderMaterial({
13
+ uniforms: {
14
+ tDiffuse: { value: null }, // 贴图纹理
15
+ resolution: { value: new Vector2(1 / 1024, 1 / 1024) }
16
+ },
17
+ vertexShader: `
18
+ ${ShaderChunk.common}
19
+ ${ShaderChunk.logdepthbuf_pars_vertex}
20
+ varying vec2 vUv;
21
+ void main() {
22
+ vUv = uv;
23
+ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
24
+ ${ShaderChunk.logdepthbuf_vertex}
25
+ }
26
+ `,
27
+ fragmentShader: `
28
+ ${ShaderChunk.logdepthbuf_pars_fragment}
29
+ precision highp float;
30
+
31
+ uniform sampler2D tDiffuse;
32
+
33
+ uniform vec2 resolution;
34
+
35
+ varying vec2 vUv;
36
+
37
+ #ifndef FXAA_DISCARD
38
+ //
39
+ // Only valid for PC OpenGL currently.
40
+ // Probably will not work when FXAA_GREEN_AS_LUMA = 1.
41
+ //
42
+ // 1 = Use discard on pixels which don't need AA.
43
+ // For APIs which enable concurrent TEX+ROP from same surface.
44
+ // 0 = Return unchanged color on pixels which don't need AA.
45
+ //
46
+ #define FXAA_DISCARD 0
47
+ #endif
48
+
49
+ /*--------------------------------------------------------------------------*/
50
+ #define FxaaTexTop(t, p) texture2D(t, p, -100.0)
51
+ #define FxaaTexOff(t, p, o, r) texture2D(t, p + (o * r), -100.0)
52
+ /*--------------------------------------------------------------------------*/
53
+
54
+ #define NUM_SAMPLES 5
55
+
56
+ // assumes colors have premultipliedAlpha, so that the calculated color contrast is scaled by alpha
57
+ float contrast( vec4 a, vec4 b ) {
58
+ vec4 diff = abs( a - b );
59
+ return max( max( max( diff.r, diff.g ), diff.b ), diff.a );
60
+ }
61
+
62
+ /*============================================================================
63
+
64
+ FXAA3 QUALITY - PC
65
+
66
+ ============================================================================*/
67
+
68
+ /*--------------------------------------------------------------------------*/
69
+ vec4 FxaaPixelShader(
70
+ vec2 posM,
71
+ sampler2D tex,
72
+ vec2 fxaaQualityRcpFrame,
73
+ float fxaaQualityEdgeThreshold,
74
+ float fxaaQualityinvEdgeThreshold
75
+ ) {
76
+ vec4 rgbaM = FxaaTexTop(tex, posM);
77
+ vec4 rgbaS = FxaaTexOff(tex, posM, vec2( 0.0, 1.0), fxaaQualityRcpFrame.xy);
78
+ vec4 rgbaE = FxaaTexOff(tex, posM, vec2( 1.0, 0.0), fxaaQualityRcpFrame.xy);
79
+ vec4 rgbaN = FxaaTexOff(tex, posM, vec2( 0.0,-1.0), fxaaQualityRcpFrame.xy);
80
+ vec4 rgbaW = FxaaTexOff(tex, posM, vec2(-1.0, 0.0), fxaaQualityRcpFrame.xy);
81
+ // . S .
82
+ // W M E
83
+ // . N .
84
+
85
+ bool earlyExit = max( max( max(
86
+ contrast( rgbaM, rgbaN ),
87
+ contrast( rgbaM, rgbaS ) ),
88
+ contrast( rgbaM, rgbaE ) ),
89
+ contrast( rgbaM, rgbaW ) )
90
+ < fxaaQualityEdgeThreshold;
91
+ // . 0 .
92
+ // 0 0 0
93
+ // . 0 .
94
+
95
+ #if (FXAA_DISCARD == 1)
96
+ if(earlyExit) FxaaDiscard;
97
+ #else
98
+ if(earlyExit) return rgbaM;
99
+ #endif
100
+
101
+ float contrastN = contrast( rgbaM, rgbaN );
102
+ float contrastS = contrast( rgbaM, rgbaS );
103
+ float contrastE = contrast( rgbaM, rgbaE );
104
+ float contrastW = contrast( rgbaM, rgbaW );
105
+
106
+ float relativeVContrast = ( contrastN + contrastS ) - ( contrastE + contrastW );
107
+ relativeVContrast *= fxaaQualityinvEdgeThreshold;
108
+
109
+ bool horzSpan = relativeVContrast > 0.;
110
+ // . 1 .
111
+ // 0 0 0
112
+ // . 1 .
113
+
114
+ // 45 deg edge detection and corners of objects, aka V/H contrast is too similar
115
+ if( abs( relativeVContrast ) < .3 ) {
116
+ // locate the edge
117
+ vec2 dirToEdge;
118
+ dirToEdge.x = contrastE > contrastW ? 1. : -1.;
119
+ dirToEdge.y = contrastS > contrastN ? 1. : -1.;
120
+ // . 2 . . 1 .
121
+ // 1 0 2 ~= 0 0 1
122
+ // . 1 . . 0 .
123
+
124
+ // tap 2 pixels and see which ones are "outside" the edge, to
125
+ // determine if the edge is vertical or horizontal
126
+
127
+ vec4 rgbaAlongH = FxaaTexOff(tex, posM, vec2( dirToEdge.x, -dirToEdge.y ), fxaaQualityRcpFrame.xy);
128
+ float matchAlongH = contrast( rgbaM, rgbaAlongH );
129
+ // . 1 .
130
+ // 0 0 1
131
+ // . 0 H
132
+
133
+ vec4 rgbaAlongV = FxaaTexOff(tex, posM, vec2( -dirToEdge.x, dirToEdge.y ), fxaaQualityRcpFrame.xy);
134
+ float matchAlongV = contrast( rgbaM, rgbaAlongV );
135
+ // V 1 .
136
+ // 0 0 1
137
+ // . 0 .
138
+
139
+ relativeVContrast = matchAlongV - matchAlongH;
140
+ relativeVContrast *= fxaaQualityinvEdgeThreshold;
141
+
142
+ if( abs( relativeVContrast ) < .3 ) { // 45 deg edge
143
+ // 1 1 .
144
+ // 0 0 1
145
+ // . 0 1
146
+
147
+ // do a simple blur
148
+ return mix(
149
+ rgbaM,
150
+ (rgbaN + rgbaS + rgbaE + rgbaW) * .25,
151
+ .4
152
+ );
153
+ }
154
+
155
+ horzSpan = relativeVContrast > 0.;
156
+ }
157
+
158
+ if(!horzSpan) rgbaN = rgbaW;
159
+ if(!horzSpan) rgbaS = rgbaE;
160
+ // . 0 . 1
161
+ // 1 0 1 -> 0
162
+ // . 0 . 1
163
+
164
+ bool pairN = contrast( rgbaM, rgbaN ) > contrast( rgbaM, rgbaS );
165
+ if(!pairN) rgbaN = rgbaS;
166
+
167
+ vec2 offNP;
168
+ offNP.x = (!horzSpan) ? 0.0 : fxaaQualityRcpFrame.x;
169
+ offNP.y = ( horzSpan) ? 0.0 : fxaaQualityRcpFrame.y;
170
+
171
+ bool doneN = false;
172
+ bool doneP = false;
173
+
174
+ float nDist = 0.;
175
+ float pDist = 0.;
176
+
177
+ vec2 posN = posM;
178
+ vec2 posP = posM;
179
+
180
+ int iterationsUsed = 0;
181
+ int iterationsUsedN = 0;
182
+ int iterationsUsedP = 0;
183
+ for( int i = 0; i < NUM_SAMPLES; i++ ) {
184
+ iterationsUsed = i;
185
+
186
+ float increment = float(i + 1);
187
+
188
+ if(!doneN) {
189
+ nDist += increment;
190
+ posN = posM + offNP * nDist;
191
+ vec4 rgbaEndN = FxaaTexTop(tex, posN.xy);
192
+ doneN = contrast( rgbaEndN, rgbaM ) > contrast( rgbaEndN, rgbaN );
193
+ iterationsUsedN = i;
194
+ }
195
+
196
+ if(!doneP) {
197
+ pDist += increment;
198
+ posP = posM - offNP * pDist;
199
+ vec4 rgbaEndP = FxaaTexTop(tex, posP.xy);
200
+ doneP = contrast( rgbaEndP, rgbaM ) > contrast( rgbaEndP, rgbaN );
201
+ iterationsUsedP = i;
202
+ }
203
+
204
+ if(doneN || doneP) break;
205
+ }
206
+
207
+
208
+ if ( !doneP && !doneN ) return rgbaM; // failed to find end of edge
209
+
210
+ float dist = min(
211
+ doneN ? float( iterationsUsedN ) / float( NUM_SAMPLES - 1 ) : 1.,
212
+ doneP ? float( iterationsUsedP ) / float( NUM_SAMPLES - 1 ) : 1.
213
+ );
214
+
215
+ // hacky way of reduces blurriness of mostly diagonal edges
216
+ // but reduces AA quality
217
+ dist = pow(dist, .5);
218
+
219
+ dist = 1. - dist;
220
+
221
+ return mix(
222
+ rgbaM,
223
+ rgbaN,
224
+ dist * .5
225
+ );
226
+ }
227
+
228
+ void main() {
229
+ const float edgeDetectionQuality = .2;
230
+ const float invEdgeDetectionQuality = 1. / edgeDetectionQuality;
231
+
232
+ gl_FragColor = FxaaPixelShader(
233
+ vUv,
234
+ tDiffuse,
235
+ resolution,
236
+ edgeDetectionQuality, // [0,1] contrast needed, otherwise early discard
237
+ invEdgeDetectionQuality
238
+ );
239
+ ${ShaderChunk.logdepthbuf_fragment}
240
+ }
241
+ `,
242
+ blending: NoBlending, // 渲染时不与背景融合计算 直接替换
243
+ depthTest: false,
244
+ depthWrite: false,
245
+ transparent: true
246
+ });
247
+
248
+ export default FXAAShaderMaterial;