Просмотр исходного кода

Line2: Add support for Alpha To Coverage (#21451)

* Update line material to support alpha to coverage

* Update example to demonstrate alpha to coverage

* revert max size increase

* Update fwidth use

* Smoothen line

* Supper webgl1 derivatives

* Fix end cap edge artifacts (hopefully)

* Update smoothstep

* Fix artifacts
Garrett Johnson 4 лет назад
Родитель
Сommit
4ef312e7ff

+ 56 - 2
examples/js/lines/LineMaterial.js

@@ -213,6 +213,24 @@ THREE.ShaderLib[ 'line' ] = {
 
 			#endif
 
+			float alpha = opacity;
+
+			#ifdef ALPHA_TO_COVERAGE
+
+			// artifacts appear on some hardware if a derivative is taken within a conditional
+			float a = vUv.x;
+			float b = ( vUv.y > 0.0 ) ? vUv.y - 1.0 : vUv.y + 1.0;
+			float len2 = a * a + b * b;
+			float dlen = fwidth( len2 );
+
+			if ( abs( vUv.y ) > 1.0 ) {
+
+				alpha = 1.0 - smoothstep( 1.0 - dlen, 1.0 + dlen, len2 );
+
+			}
+
+			#else
+
 			if ( abs( vUv.y ) > 1.0 ) {
 
 				float a = vUv.x;
@@ -223,12 +241,14 @@ THREE.ShaderLib[ 'line' ] = {
 
 			}
 
-			vec4 diffuseColor = vec4( diffuse, opacity );
+			#endif
+
+			vec4 diffuseColor = vec4( diffuse, alpha );
 
 			#include <logdepthbuf_fragment>
 			#include <color_fragment>
 
-			gl_FragColor = vec4( diffuseColor.rgb, diffuseColor.a );
+			gl_FragColor = vec4( diffuseColor.rgb, alpha );
 
 			#include <tonemapping_fragment>
 			#include <encodings_fragment>
@@ -400,6 +420,40 @@ THREE.LineMaterial = function ( parameters ) {
 
 			}
 
+		},
+
+		alphaToCoverage: {
+
+			enumerable: true,
+
+			get: function () {
+
+				return Boolean( 'ALPHA_TO_COVERAGE' in this.defines );
+
+			},
+
+			set: function ( value ) {
+
+				if ( Boolean( value ) !== Boolean( 'ALPHA_TO_COVERAGE' in this.defines ) ) {
+
+					this.needsUpdate = true;
+
+				}
+
+				if ( value ) {
+
+					this.defines.ALPHA_TO_COVERAGE = '';
+					this.extensions.derivatives = true;
+
+				} else {
+
+					delete this.defines.ALPHA_TO_COVERAGE;
+					this.extensions.derivatives = false;
+
+				}
+
+			}
+
 		}
 
 	} );

+ 56 - 2
examples/jsm/lines/LineMaterial.js

@@ -221,6 +221,24 @@ ShaderLib[ 'line' ] = {
 
 			#endif
 
+			float alpha = opacity;
+
+			#ifdef ALPHA_TO_COVERAGE
+
+			// artifacts appear on some hardware if a derivative is taken within a conditional
+			float a = vUv.x;
+			float b = ( vUv.y > 0.0 ) ? vUv.y - 1.0 : vUv.y + 1.0;
+			float len2 = a * a + b * b;
+			float dlen = fwidth( len2 );
+
+			if ( abs( vUv.y ) > 1.0 ) {
+
+				alpha = 1.0 - smoothstep( 1.0 - dlen, 1.0 + dlen, len2 );
+
+			}
+
+			#else
+
 			if ( abs( vUv.y ) > 1.0 ) {
 
 				float a = vUv.x;
@@ -231,12 +249,14 @@ ShaderLib[ 'line' ] = {
 
 			}
 
-			vec4 diffuseColor = vec4( diffuse, opacity );
+			#endif
+
+			vec4 diffuseColor = vec4( diffuse, alpha );
 
 			#include <logdepthbuf_fragment>
 			#include <color_fragment>
 
-			gl_FragColor = vec4( diffuseColor.rgb, diffuseColor.a );
+			gl_FragColor = vec4( diffuseColor.rgb, alpha );
 
 			#include <tonemapping_fragment>
 			#include <encodings_fragment>
@@ -408,6 +428,40 @@ var LineMaterial = function ( parameters ) {
 
 			}
 
+		},
+
+		alphaToCoverage: {
+
+			enumerable: true,
+
+			get: function () {
+
+				return Boolean( 'ALPHA_TO_COVERAGE' in this.defines );
+
+			},
+
+			set: function ( value ) {
+
+				if ( Boolean( value ) !== Boolean( 'ALPHA_TO_COVERAGE' in this.defines ) ) {
+
+					this.needsUpdate = true;
+
+				}
+
+				if ( value ) {
+
+					this.defines.ALPHA_TO_COVERAGE = '';
+					this.extensions.derivatives = true;
+
+				} else {
+
+					delete this.defines.ALPHA_TO_COVERAGE;
+					this.extensions.derivatives = false;
+
+				}
+
+			}
+
 		}
 
 	} );

+ 9 - 1
examples/webgl_lines_fat.html

@@ -97,7 +97,8 @@
 					linewidth: 5, // in pixels
 					vertexColors: true,
 					//resolution:  // to be set by renderer, eventually
-					dashed: false
+					dashed: false,
+					alphaToCoverage: true,
 
 				} );
 
@@ -198,6 +199,7 @@
 				const param = {
 					'line type': 0,
 					'width (px)': 5,
+					'alphaToCoverage': true,
 					'dashed': false,
 					'dash scale': 1,
 					'dash / gap': 1
@@ -231,6 +233,12 @@
 
 				} );
 
+				gui.add( param, 'alphaToCoverage' ).onChange( function ( val ) { 
+
+					matLine.alphaToCoverage = val;
+
+				} );
+
 				gui.add( param, 'dashed' ).onChange( function ( val ) {
 
 					matLine.dashed = val;