SMAAShader.js 14.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
/**
 * @author mpk / http://polko.me/
 *
 * WebGL port of Subpixel Morphological Antialiasing (SMAA) v2.8
 * Preset: SMAA 1x Medium (with color edge detection)
 * https://github.com/iryoku/smaa/releases/tag/v2.8
 */

import {
	Vector2
} from "../../../build/three.module.js";

var SMAAEdgesShader = {

	defines: {

		"SMAA_THRESHOLD": "0.1"

	},

	uniforms: {

		"tDiffuse": { value: null },
		"resolution": { value: new Vector2( 1 / 1024, 1 / 512 ) }

	},

	vertexShader: [

		"uniform vec2 resolution;",

		"varying vec2 vUv;",
		"varying vec4 vOffset[ 3 ];",

		"void SMAAEdgeDetectionVS( vec2 texcoord ) {",
G
Garrett Johnson 已提交
36 37 38
		"	vOffset[ 0 ] = texcoord.xyxy + resolution.xyxy * vec4( -1.0, 0.0, 0.0,  1.0 );", // WebGL port note: Changed sign in W component
		"	vOffset[ 1 ] = texcoord.xyxy + resolution.xyxy * vec4(  1.0, 0.0, 0.0, -1.0 );", // WebGL port note: Changed sign in W component
		"	vOffset[ 2 ] = texcoord.xyxy + resolution.xyxy * vec4( -2.0, 0.0, 0.0,  2.0 );", // WebGL port note: Changed sign in W component
39 40 41 42
		"}",

		"void main() {",

G
Garrett Johnson 已提交
43
		"	vUv = uv;",
44

G
Garrett Johnson 已提交
45
		"	SMAAEdgeDetectionVS( vUv );",
46

G
Garrett Johnson 已提交
47
		"	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
48 49 50 51 52 53 54 55 56 57 58 59 60

		"}"

	].join( "\n" ),

	fragmentShader: [

		"uniform sampler2D tDiffuse;",

		"varying vec2 vUv;",
		"varying vec4 vOffset[ 3 ];",

		"vec4 SMAAColorEdgeDetectionPS( vec2 texcoord, vec4 offset[3], sampler2D colorTex ) {",
G
Garrett Johnson 已提交
61
		"	vec2 threshold = vec2( SMAA_THRESHOLD, SMAA_THRESHOLD );",
62

G
Garrett Johnson 已提交
63 64 65
		// Calculate color deltas:
		"	vec4 delta;",
		"	vec3 C = texture2D( colorTex, texcoord ).rgb;",
66

G
Garrett Johnson 已提交
67 68 69
		"	vec3 Cleft = texture2D( colorTex, offset[0].xy ).rgb;",
		"	vec3 t = abs( C - Cleft );",
		"	delta.x = max( max( t.r, t.g ), t.b );",
70

G
Garrett Johnson 已提交
71 72 73
		"	vec3 Ctop = texture2D( colorTex, offset[0].zw ).rgb;",
		"	t = abs( C - Ctop );",
		"	delta.y = max( max( t.r, t.g ), t.b );",
74

G
Garrett Johnson 已提交
75 76
		// We do the usual threshold:
		"	vec2 edges = step( threshold, delta.xy );",
77

G
Garrett Johnson 已提交
78 79 80
		// Then discard if there is no edge:
		"	if ( dot( edges, vec2( 1.0, 1.0 ) ) == 0.0 )",
		"		discard;",
81

G
Garrett Johnson 已提交
82 83 84 85
		// Calculate right and bottom deltas:
		"	vec3 Cright = texture2D( colorTex, offset[1].xy ).rgb;",
		"	t = abs( C - Cright );",
		"	delta.z = max( max( t.r, t.g ), t.b );",
86

G
Garrett Johnson 已提交
87 88 89
		"	vec3 Cbottom  = texture2D( colorTex, offset[1].zw ).rgb;",
		"	t = abs( C - Cbottom );",
		"	delta.w = max( max( t.r, t.g ), t.b );",
90

G
Garrett Johnson 已提交
91 92
		// Calculate the maximum delta in the direct neighborhood:
		"	float maxDelta = max( max( max( delta.x, delta.y ), delta.z ), delta.w );",
93

G
Garrett Johnson 已提交
94 95 96 97
		// Calculate left-left and top-top deltas:
		"	vec3 Cleftleft  = texture2D( colorTex, offset[2].xy ).rgb;",
		"	t = abs( C - Cleftleft );",
		"	delta.z = max( max( t.r, t.g ), t.b );",
98

G
Garrett Johnson 已提交
99 100 101
		"	vec3 Ctoptop = texture2D( colorTex, offset[2].zw ).rgb;",
		"	t = abs( C - Ctoptop );",
		"	delta.w = max( max( t.r, t.g ), t.b );",
102

G
Garrett Johnson 已提交
103 104
		// Calculate the final maximum delta:
		"	maxDelta = max( max( maxDelta, delta.z ), delta.w );",
105

G
Garrett Johnson 已提交
106 107
		// Local contrast adaptation in action:
		"	edges.xy *= step( 0.5 * maxDelta, delta.xy );",
108

G
Garrett Johnson 已提交
109
		"	return vec4( edges, 0.0, 0.0 );",
110 111 112 113
		"}",

		"void main() {",

G
Garrett Johnson 已提交
114
		"	gl_FragColor = SMAAColorEdgeDetectionPS( vUv, vOffset, tDiffuse );",
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150

		"}"

	].join( "\n" )

};

var SMAAWeightsShader = {

	defines: {

		"SMAA_MAX_SEARCH_STEPS": "8",
		"SMAA_AREATEX_MAX_DISTANCE": "16",
		"SMAA_AREATEX_PIXEL_SIZE": "( 1.0 / vec2( 160.0, 560.0 ) )",
		"SMAA_AREATEX_SUBTEX_SIZE": "( 1.0 / 7.0 )"

	},

	uniforms: {

		"tDiffuse": { value: null },
		"tArea": { value: null },
		"tSearch": { value: null },
		"resolution": { value: new Vector2( 1 / 1024, 1 / 512 ) }

	},

	vertexShader: [

		"uniform vec2 resolution;",

		"varying vec2 vUv;",
		"varying vec4 vOffset[ 3 ];",
		"varying vec2 vPixcoord;",

		"void SMAABlendingWeightCalculationVS( vec2 texcoord ) {",
G
Garrett Johnson 已提交
151
		"	vPixcoord = texcoord / resolution;",
152

G
Garrett Johnson 已提交
153 154 155
		// We will use these offsets for the searches later on (see @PSEUDO_GATHER4):
		"	vOffset[ 0 ] = texcoord.xyxy + resolution.xyxy * vec4( -0.25, 0.125, 1.25, 0.125 );", // WebGL port note: Changed sign in Y and W components
		"	vOffset[ 1 ] = texcoord.xyxy + resolution.xyxy * vec4( -0.125, 0.25, -0.125, -1.25 );", // WebGL port note: Changed sign in Y and W components
156

G
Garrett Johnson 已提交
157 158
		// And these for the searches, they indicate the ends of the loops:
		"	vOffset[ 2 ] = vec4( vOffset[ 0 ].xz, vOffset[ 1 ].yw ) + vec4( -2.0, 2.0, -2.0, 2.0 ) * resolution.xxyy * float( SMAA_MAX_SEARCH_STEPS );",
159 160 161 162 163

		"}",

		"void main() {",

G
Garrett Johnson 已提交
164
		"	vUv = uv;",
165

G
Garrett Johnson 已提交
166
		"	SMAABlendingWeightCalculationVS( vUv );",
167

G
Garrett Johnson 已提交
168
		"	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186

		"}"

	].join( "\n" ),

	fragmentShader: [

		"#define SMAASampleLevelZeroOffset( tex, coord, offset ) texture2D( tex, coord + float( offset ) * resolution, 0.0 )",

		"uniform sampler2D tDiffuse;",
		"uniform sampler2D tArea;",
		"uniform sampler2D tSearch;",
		"uniform vec2 resolution;",

		"varying vec2 vUv;",
		"varying vec4 vOffset[3];",
		"varying vec2 vPixcoord;",

A
aardgoose 已提交
187
		"#if __VERSION__ == 100",
188
		"vec2 round( vec2 x ) {",
G
Garrett Johnson 已提交
189
		"	return sign( x ) * floor( abs( x ) + 0.5 );",
190
		"}",
A
aardgoose 已提交
191
		"#endif",
192 193

		"float SMAASearchLength( sampler2D searchTex, vec2 e, float bias, float scale ) {",
G
Garrett Johnson 已提交
194 195 196 197 198 199
		// Not required if searchTex accesses are set to point:
		// float2 SEARCH_TEX_PIXEL_SIZE = 1.0 / float2(66.0, 33.0);
		// e = float2(bias, 0.0) + 0.5 * SEARCH_TEX_PIXEL_SIZE +
		//     e * float2(scale, 1.0) * float2(64.0, 32.0) * SEARCH_TEX_PIXEL_SIZE;
		"	e.r = bias + e.r * scale;",
		"	return 255.0 * texture2D( searchTex, e, 0.0 ).r;",
200 201 202
		"}",

		"float SMAASearchXLeft( sampler2D edgesTex, sampler2D searchTex, vec2 texcoord, float end ) {",
G
Garrett Johnson 已提交
203
		/**
204 205 206 207 208 209
			* @PSEUDO_GATHER4
			* This texcoord has been offset by (-0.25, -0.125) in the vertex shader to
			* sample between edge, thus fetching four edges in a row.
			* Sampling with different offsets in each direction allows to disambiguate
			* which edges are active from the four fetched ones.
			*/
G
Garrett Johnson 已提交
210
		"	vec2 e = vec2( 0.0, 1.0 );",
211

G
Garrett Johnson 已提交
212 213 214 215 216
		"	for ( int i = 0; i < SMAA_MAX_SEARCH_STEPS; i ++ ) {", // WebGL port note: Changed while to for
		"		e = texture2D( edgesTex, texcoord, 0.0 ).rg;",
		"		texcoord -= vec2( 2.0, 0.0 ) * resolution;",
		"		if ( ! ( texcoord.x > end && e.g > 0.8281 && e.r == 0.0 ) ) break;",
		"	}",
217

G
Garrett Johnson 已提交
218 219
		// We correct the previous (-0.25, -0.125) offset we applied:
		"	texcoord.x += 0.25 * resolution.x;",
220

G
Garrett Johnson 已提交
221 222
		// The searches are bias by 1, so adjust the coords accordingly:
		"	texcoord.x += resolution.x;",
223

G
Garrett Johnson 已提交
224 225 226
		// Disambiguate the length added by the last step:
		"	texcoord.x += 2.0 * resolution.x;", // Undo last step
		"	texcoord.x -= resolution.x * SMAASearchLength(searchTex, e, 0.0, 0.5);",
227

G
Garrett Johnson 已提交
228
		"	return texcoord.x;",
229 230 231
		"}",

		"float SMAASearchXRight( sampler2D edgesTex, sampler2D searchTex, vec2 texcoord, float end ) {",
G
Garrett Johnson 已提交
232
		"	vec2 e = vec2( 0.0, 1.0 );",
233

G
Garrett Johnson 已提交
234 235 236 237 238
		"	for ( int i = 0; i < SMAA_MAX_SEARCH_STEPS; i ++ ) {", // WebGL port note: Changed while to for
		"		e = texture2D( edgesTex, texcoord, 0.0 ).rg;",
		"		texcoord += vec2( 2.0, 0.0 ) * resolution;",
		"		if ( ! ( texcoord.x < end && e.g > 0.8281 && e.r == 0.0 ) ) break;",
		"	}",
239

G
Garrett Johnson 已提交
240 241 242 243
		"	texcoord.x -= 0.25 * resolution.x;",
		"	texcoord.x -= resolution.x;",
		"	texcoord.x -= 2.0 * resolution.x;",
		"	texcoord.x += resolution.x * SMAASearchLength( searchTex, e, 0.5, 0.5 );",
244

G
Garrett Johnson 已提交
245
		"	return texcoord.x;",
246 247 248
		"}",

		"float SMAASearchYUp( sampler2D edgesTex, sampler2D searchTex, vec2 texcoord, float end ) {",
G
Garrett Johnson 已提交
249
		"	vec2 e = vec2( 1.0, 0.0 );",
250

G
Garrett Johnson 已提交
251 252 253 254 255
		"	for ( int i = 0; i < SMAA_MAX_SEARCH_STEPS; i ++ ) {", // WebGL port note: Changed while to for
		"		e = texture2D( edgesTex, texcoord, 0.0 ).rg;",
		"		texcoord += vec2( 0.0, 2.0 ) * resolution;", // WebGL port note: Changed sign
		"		if ( ! ( texcoord.y > end && e.r > 0.8281 && e.g == 0.0 ) ) break;",
		"	}",
256

G
Garrett Johnson 已提交
257 258 259 260
		"	texcoord.y -= 0.25 * resolution.y;", // WebGL port note: Changed sign
		"	texcoord.y -= resolution.y;", // WebGL port note: Changed sign
		"	texcoord.y -= 2.0 * resolution.y;", // WebGL port note: Changed sign
		"	texcoord.y += resolution.y * SMAASearchLength( searchTex, e.gr, 0.0, 0.5 );", // WebGL port note: Changed sign
261

G
Garrett Johnson 已提交
262
		"	return texcoord.y;",
263 264 265
		"}",

		"float SMAASearchYDown( sampler2D edgesTex, sampler2D searchTex, vec2 texcoord, float end ) {",
G
Garrett Johnson 已提交
266
		"	vec2 e = vec2( 1.0, 0.0 );",
267

G
Garrett Johnson 已提交
268 269 270 271 272
		"	for ( int i = 0; i < SMAA_MAX_SEARCH_STEPS; i ++ ) {", // WebGL port note: Changed while to for
		"		e = texture2D( edgesTex, texcoord, 0.0 ).rg;",
		"		texcoord -= vec2( 0.0, 2.0 ) * resolution;", // WebGL port note: Changed sign
		"		if ( ! ( texcoord.y < end && e.r > 0.8281 && e.g == 0.0 ) ) break;",
		"	}",
273

G
Garrett Johnson 已提交
274 275 276 277
		"	texcoord.y += 0.25 * resolution.y;", // WebGL port note: Changed sign
		"	texcoord.y += resolution.y;", // WebGL port note: Changed sign
		"	texcoord.y += 2.0 * resolution.y;", // WebGL port note: Changed sign
		"	texcoord.y -= resolution.y * SMAASearchLength( searchTex, e.gr, 0.5, 0.5 );", // WebGL port note: Changed sign
278

G
Garrett Johnson 已提交
279
		"	return texcoord.y;",
280 281 282
		"}",

		"vec2 SMAAArea( sampler2D areaTex, vec2 dist, float e1, float e2, float offset ) {",
G
Garrett Johnson 已提交
283 284
		// Rounding prevents precision errors of bilinear filtering:
		"	vec2 texcoord = float( SMAA_AREATEX_MAX_DISTANCE ) * round( 4.0 * vec2( e1, e2 ) ) + dist;",
285

G
Garrett Johnson 已提交
286 287
		// We do a scale and bias for mapping to texel space:
		"	texcoord = SMAA_AREATEX_PIXEL_SIZE * texcoord + ( 0.5 * SMAA_AREATEX_PIXEL_SIZE );",
288

G
Garrett Johnson 已提交
289 290
		// Move to proper place, according to the subpixel offset:
		"	texcoord.y += SMAA_AREATEX_SUBTEX_SIZE * offset;",
291

G
Garrett Johnson 已提交
292
		"	return texture2D( areaTex, texcoord, 0.0 ).rg;",
293 294 295
		"}",

		"vec4 SMAABlendingWeightCalculationPS( vec2 texcoord, vec2 pixcoord, vec4 offset[ 3 ], sampler2D edgesTex, sampler2D areaTex, sampler2D searchTex, ivec4 subsampleIndices ) {",
G
Garrett Johnson 已提交
296
		"	vec4 weights = vec4( 0.0, 0.0, 0.0, 0.0 );",
297

G
Garrett Johnson 已提交
298
		"	vec2 e = texture2D( edgesTex, texcoord ).rg;",
299

G
Garrett Johnson 已提交
300 301
		"	if ( e.g > 0.0 ) {", // Edge at north
		"		vec2 d;",
302

G
Garrett Johnson 已提交
303 304 305 306 307
		// Find the distance to the left:
		"		vec2 coords;",
		"		coords.x = SMAASearchXLeft( edgesTex, searchTex, offset[ 0 ].xy, offset[ 2 ].x );",
		"		coords.y = offset[ 1 ].y;", // offset[1].y = texcoord.y - 0.25 * resolution.y (@CROSSING_OFFSET)
		"		d.x = coords.x;",
308

G
Garrett Johnson 已提交
309 310 311 312
		// Now fetch the left crossing edges, two at a time using bilinear
		// filtering. Sampling at -0.25 (see @CROSSING_OFFSET) enables to
		// discern what value each edge has:
		"		float e1 = texture2D( edgesTex, coords, 0.0 ).r;",
313

G
Garrett Johnson 已提交
314 315 316
		// Find the distance to the right:
		"		coords.x = SMAASearchXRight( edgesTex, searchTex, offset[ 0 ].zw, offset[ 2 ].y );",
		"		d.y = coords.x;",
317

G
Garrett Johnson 已提交
318 319 320
		// We want the distances to be in pixel units (doing this here allow to
		// better interleave arithmetic and memory accesses):
		"		d = d / resolution.x - pixcoord.x;",
321

G
Garrett Johnson 已提交
322 323 324
		// SMAAArea below needs a sqrt, as the areas texture is compressed
		// quadratically:
		"		vec2 sqrt_d = sqrt( abs( d ) );",
325

G
Garrett Johnson 已提交
326 327 328
		// Fetch the right crossing edges:
		"		coords.y -= 1.0 * resolution.y;", // WebGL port note: Added
		"		float e2 = SMAASampleLevelZeroOffset( edgesTex, coords, ivec2( 1, 0 ) ).r;",
329

G
Garrett Johnson 已提交
330 331 332 333
		// Ok, we know how this pattern looks like, now it is time for getting
		// the actual area:
		"		weights.rg = SMAAArea( areaTex, sqrt_d, e1, e2, float( subsampleIndices.y ) );",
		"	}",
334

G
Garrett Johnson 已提交
335 336
		"	if ( e.r > 0.0 ) {", // Edge at west
		"		vec2 d;",
337

G
Garrett Johnson 已提交
338 339
		// Find the distance to the top:
		"		vec2 coords;",
340

G
Garrett Johnson 已提交
341 342 343
		"		coords.y = SMAASearchYUp( edgesTex, searchTex, offset[ 1 ].xy, offset[ 2 ].z );",
		"		coords.x = offset[ 0 ].x;", // offset[1].x = texcoord.x - 0.25 * resolution.x;
		"		d.x = coords.y;",
344

G
Garrett Johnson 已提交
345 346
		// Fetch the top crossing edges:
		"		float e1 = texture2D( edgesTex, coords, 0.0 ).g;",
347

G
Garrett Johnson 已提交
348 349 350
		// Find the distance to the bottom:
		"		coords.y = SMAASearchYDown( edgesTex, searchTex, offset[ 1 ].zw, offset[ 2 ].w );",
		"		d.y = coords.y;",
351

G
Garrett Johnson 已提交
352 353
		// We want the distances to be in pixel units:
		"		d = d / resolution.y - pixcoord.y;",
354

G
Garrett Johnson 已提交
355 356 357
		// SMAAArea below needs a sqrt, as the areas texture is compressed
		// quadratically:
		"		vec2 sqrt_d = sqrt( abs( d ) );",
358

G
Garrett Johnson 已提交
359 360 361
		// Fetch the bottom crossing edges:
		"		coords.y -= 1.0 * resolution.y;", // WebGL port note: Added
		"		float e2 = SMAASampleLevelZeroOffset( edgesTex, coords, ivec2( 0, 1 ) ).g;",
362

G
Garrett Johnson 已提交
363 364 365
		// Get the area for this direction:
		"		weights.ba = SMAAArea( areaTex, sqrt_d, e1, e2, float( subsampleIndices.x ) );",
		"	}",
366

G
Garrett Johnson 已提交
367
		"	return weights;",
368 369 370 371
		"}",

		"void main() {",

G
Garrett Johnson 已提交
372
		"	gl_FragColor = SMAABlendingWeightCalculationPS( vUv, vPixcoord, vOffset, tDiffuse, tArea, tSearch, ivec4( 0.0 ) );",
373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397

		"}"

	].join( "\n" )

};

var SMAABlendShader = {

	uniforms: {

		"tDiffuse": { value: null },
		"tColor": { value: null },
		"resolution": { value: new Vector2( 1 / 1024, 1 / 512 ) }

	},

	vertexShader: [

		"uniform vec2 resolution;",

		"varying vec2 vUv;",
		"varying vec4 vOffset[ 2 ];",

		"void SMAANeighborhoodBlendingVS( vec2 texcoord ) {",
G
Garrett Johnson 已提交
398 399
		"	vOffset[ 0 ] = texcoord.xyxy + resolution.xyxy * vec4( -1.0, 0.0, 0.0, 1.0 );", // WebGL port note: Changed sign in W component
		"	vOffset[ 1 ] = texcoord.xyxy + resolution.xyxy * vec4( 1.0, 0.0, 0.0, -1.0 );", // WebGL port note: Changed sign in W component
400 401 402 403
		"}",

		"void main() {",

G
Garrett Johnson 已提交
404
		"	vUv = uv;",
405

G
Garrett Johnson 已提交
406
		"	SMAANeighborhoodBlendingVS( vUv );",
407

G
Garrett Johnson 已提交
408
		"	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
409 410 411 412 413 414 415 416 417 418 419 420 421 422 423

		"}"

	].join( "\n" ),

	fragmentShader: [

		"uniform sampler2D tDiffuse;",
		"uniform sampler2D tColor;",
		"uniform vec2 resolution;",

		"varying vec2 vUv;",
		"varying vec4 vOffset[ 2 ];",

		"vec4 SMAANeighborhoodBlendingPS( vec2 texcoord, vec4 offset[ 2 ], sampler2D colorTex, sampler2D blendTex ) {",
G
Garrett Johnson 已提交
424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461
		// Fetch the blending weights for current pixel:
		"	vec4 a;",
		"	a.xz = texture2D( blendTex, texcoord ).xz;",
		"	a.y = texture2D( blendTex, offset[ 1 ].zw ).g;",
		"	a.w = texture2D( blendTex, offset[ 1 ].xy ).a;",

		// Is there any blending weight with a value greater than 0.0?
		"	if ( dot(a, vec4( 1.0, 1.0, 1.0, 1.0 )) < 1e-5 ) {",
		"		return texture2D( colorTex, texcoord, 0.0 );",
		"	} else {",
		// Up to 4 lines can be crossing a pixel (one through each edge). We
		// favor blending by choosing the line with the maximum weight for each
		// direction:
		"		vec2 offset;",
		"		offset.x = a.a > a.b ? a.a : -a.b;", // left vs. right
		"		offset.y = a.g > a.r ? -a.g : a.r;", // top vs. bottom // WebGL port note: Changed signs

		// Then we go in the direction that has the maximum weight:
		"		if ( abs( offset.x ) > abs( offset.y )) {", // horizontal vs. vertical
		"			offset.y = 0.0;",
		"		} else {",
		"			offset.x = 0.0;",
		"		}",

		// Fetch the opposite color and lerp by hand:
		"		vec4 C = texture2D( colorTex, texcoord, 0.0 );",
		"		texcoord += sign( offset ) * resolution;",
		"		vec4 Cop = texture2D( colorTex, texcoord, 0.0 );",
		"		float s = abs( offset.x ) > abs( offset.y ) ? abs( offset.x ) : abs( offset.y );",

		// WebGL port note: Added gamma correction
		"		C.xyz = pow(C.xyz, vec3(2.2));",
		"		Cop.xyz = pow(Cop.xyz, vec3(2.2));",
		"		vec4 mixed = mix(C, Cop, s);",
		"		mixed.xyz = pow(mixed.xyz, vec3(1.0 / 2.2));",

		"		return mixed;",
		"	}",
462 463 464 465
		"}",

		"void main() {",

G
Garrett Johnson 已提交
466
		"	gl_FragColor = SMAANeighborhoodBlendingPS( vUv, vOffset, tColor, tDiffuse );",
467 468 469 470 471 472 473 474

		"}"

	].join( "\n" )

};

export { SMAAEdgesShader, SMAAWeightsShader, SMAABlendShader };