Skip to content

Commit f5bcaa2

Browse files
authored
Merge pull request mrdoob#21383 from Mugen87/dev48
Material: Add alphaToCoverage.
2 parents 2b661c8 + 703e61b commit f5bcaa2

File tree

8 files changed

+116
-31
lines changed

8 files changed

+116
-31
lines changed

docs/api/en/materials/Material.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ <h3>[property:Float alphaTest]</h3>
3636
Default is *0*.
3737
</p>
3838

39+
<h3>[property:Float alphaToCoverage]</h3>
40+
<p>
41+
Enables alpha to coverage. Can only be used with MSAA-enabled contexts (meaning when the renderer was created with *antialias* parameter set to *true*).
42+
Default is *false*.
43+
</p>
44+
3945
<h3>[property:Integer blendDst]</h3>
4046
<p>
4147
Blending destination. Default is [page:CustomBlendingEquation OneMinusSrcAlphaFactor].

docs/api/zh/materials/Material.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ <h3>[property:Float alphaTest]</h3>
2828
<p>设置运行alphaTest时要使用的alpha值。如果不透明度低于此值,则不会渲染材质。默认值为*0*。
2929
</p>
3030

31+
<h3>[property:Float alphaToCoverage]</h3>
32+
<p>
33+
Enables alpha to coverage. Can only be used with MSAA-enabled contexts (meaning when the renderer was created with *antialias* parameter set to *true*).
34+
Default is *false*.
35+
</p>
36+
3137
<h3>[property:Integer blendDst]</h3>
3238
<p> 混合目标。默认值为[page:CustomBlendingEquation OneMinusSrcAlphaFactor]。
3339
目标因子所有可能的取值请参阅[page:CustomBlendingEquation constants]。
Loading

examples/webgl_materials_wireframe.html

Lines changed: 91 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313

1414
<script type="x-shader/x-vertex" id="vertexShader">
1515

16-
attribute vec3 center;
17-
varying vec3 vCenter;
16+
in vec3 center;
17+
out vec3 vCenter;
1818

1919
void main() {
2020

@@ -28,15 +28,16 @@
2828

2929
<script type="x-shader/x-fragment" id="fragmentShader">
3030

31-
uniform float widthFactor;
31+
uniform float thickness;
3232

33-
varying vec3 vCenter;
33+
in vec3 vCenter;
34+
out vec4 outColor;
3435

3536
float edgeFactorTri() {
3637

3738
vec3 d = fwidth( vCenter.xyz );
3839

39-
vec3 a3 = smoothstep( vec3( 0.0 ), d * widthFactor, vCenter.xyz );
40+
vec3 a3 = smoothstep( vec3( 0.0 ), d * thickness, vCenter.xyz );
4041

4142
return min( min( a3.x, a3.y ), a3.z );
4243

@@ -46,7 +47,49 @@
4647

4748
if ( edgeFactorTri() > 0.99 ) discard;
4849

49-
gl_FragColor = gl_FrontFacing ? vec4( 0.9, 0.9, 1.0, 1.0 ) : vec4( 0.4, 0.4, 0.5, 1.0 );
50+
outColor = gl_FrontFacing ? vec4( 0.9, 0.9, 1.0, 1.0 ) : vec4( 0.4, 0.4, 0.5, 1.0 );
51+
52+
}
53+
54+
</script>
55+
56+
<script type="x-shader/x-vertex" id="vertexShaderATC">
57+
58+
in vec3 center;
59+
out vec3 vCenter;
60+
61+
void main() {
62+
63+
vCenter = center;
64+
65+
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
66+
67+
}
68+
69+
</script>
70+
71+
<script type="x-shader/x-fragment" id="fragmentShaderATC">
72+
73+
uniform float thickness;
74+
75+
in vec3 vCenter;
76+
out vec4 outColor;
77+
78+
float aastep( float threshold, float dist ) {
79+
80+
float afwidth = fwidth( dist ) * 0.5;
81+
return smoothstep( threshold - afwidth, threshold + afwidth, dist );
82+
83+
}
84+
85+
void main() {
86+
87+
float d = min( min( vCenter.x, vCenter.y ), vCenter.z );
88+
89+
float edge = 1.0 - aastep( thickness, d );
90+
91+
outColor.rgb = gl_FrontFacing ? vec3( 0.9, 0.9, 1.0 ) : vec3( 0.4, 0.4, 0.5 );
92+
outColor.a = edge;
5093

5194
}
5295

@@ -56,13 +99,15 @@
5699

57100
import * as THREE from '../build/three.module.js';
58101

102+
import { OrbitControls } from './jsm/controls/OrbitControls.js';
103+
59104
import { GUI } from './jsm/libs/dat.gui.module.js';
60105

61106
const API = {
62-
widthFactor: 1
107+
thickness: 1
63108
};
64109

65-
let renderer, scene, camera, mesh1, mesh2;
110+
let renderer, scene, camera, mesh2, mesh3;
66111

67112
init();
68113

@@ -76,11 +121,20 @@
76121
scene = new THREE.Scene();
77122

78123
camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 500 );
79-
camera.position.z = 150;
124+
camera.position.z = 200;
125+
126+
const controls = new OrbitControls( camera, renderer.domElement );
127+
controls.enablePan = false;
128+
controls.enableZoom = false;
80129

81130
new THREE.BufferGeometryLoader().load( 'models/json/WaltHeadLo_buffergeometry.json', function ( geometry ) {
82131

83-
// on the left
132+
geometry.deleteAttribute( 'normal' );
133+
geometry.deleteAttribute( 'uv' );
134+
135+
setupAttributes( geometry );
136+
137+
// left
84138

85139
const material1 = new THREE.MeshBasicMaterial( {
86140

@@ -89,35 +143,45 @@
89143

90144
} );
91145

92-
mesh1 = new THREE.Mesh( geometry, material1 );
93-
mesh1.position.set( - 40, 0, 0 );
146+
const mesh1 = new THREE.Mesh( geometry, material1 );
147+
mesh1.position.set( - 60, 0, 0 );
94148

95149
scene.add( mesh1 );
96150

97-
// on the right
98-
99-
const uniforms = { 'widthFactor': { value: API.widthFactor } };
151+
// middle
100152

101153
const material2 = new THREE.ShaderMaterial( {
102154

103-
uniforms: uniforms,
155+
uniforms: { 'thickness': { value: API.thickness } },
104156
vertexShader: document.getElementById( 'vertexShader' ).textContent,
105157
fragmentShader: document.getElementById( 'fragmentShader' ).textContent,
106-
side: THREE.DoubleSide
158+
side: THREE.DoubleSide,
159+
glslVersion: THREE.GLSL3
107160

108161
} );
109162

110-
material2.extensions.derivatives = true;
163+
mesh2 = new THREE.Mesh( geometry, material2 );
164+
mesh2.position.set( 0, 0, 0 );
165+
166+
scene.add( mesh2 );
111167

112-
geometry.deleteAttribute( 'normal' );
113-
geometry.deleteAttribute( 'uv' );
168+
// right
114169

115-
setupAttributes( geometry );
170+
const material3 = new THREE.ShaderMaterial( {
116171

117-
mesh2 = new THREE.Mesh( geometry, material2 );
118-
mesh2.position.set( 40, 0, 0 );
172+
uniforms: { 'thickness': { value: API.thickness * 0.01 } },
173+
vertexShader: document.getElementById( 'vertexShaderATC' ).textContent,
174+
fragmentShader: document.getElementById( 'fragmentShaderATC' ).textContent,
175+
side: THREE.DoubleSide,
176+
glslVersion: THREE.GLSL3,
177+
alphaToCoverage: true // only works when WebGLRenderer's "antialias" is set to "true"
119178

120-
scene.add( mesh2 );
179+
} );
180+
181+
mesh3 = new THREE.Mesh( geometry, material3 );
182+
mesh3.position.set( 60, 0, 0 );
183+
184+
scene.add( mesh3 );
121185

122186
//
123187

@@ -129,9 +193,10 @@
129193

130194
const gui = new GUI();
131195

132-
gui.add( API, 'widthFactor', 0.4, 4 ).onChange( function () {
196+
gui.add( API, 'thickness', 0.4, 4 ).onChange( function () {
133197

134-
mesh2.material.uniforms.widthFactor.value = API.widthFactor;
198+
mesh2.material.uniforms.thickness.value = API.thickness;
199+
mesh3.material.uniforms.thickness.value = API.thickness * 0.01;
135200

136201
} );
137202

@@ -177,10 +242,6 @@
177242

178243
requestAnimationFrame( animate );
179244

180-
mesh1.rotation.y += 0.01;
181-
182-
mesh2.rotation.y += 0.01;
183-
184245
renderer.render( scene, camera );
185246

186247
}

src/loaders/MaterialLoader.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,9 @@ class MaterialLoader extends Loader {
122122
if ( json.morphNormals !== undefined ) material.morphNormals = json.morphNormals;
123123
if ( json.dithering !== undefined ) material.dithering = json.dithering;
124124

125+
if ( json.alphaToCoverage !== undefined ) material.alphaToCoverage = json.alphaToCoverage;
126+
if ( json.premultipliedAlpha !== undefined ) material.premultipliedAlpha = json.premultipliedAlpha;
127+
125128
if ( json.vertexTangents !== undefined ) material.vertexTangents = json.vertexTangents;
126129

127130
if ( json.visible !== undefined ) material.visible = json.visible;

src/materials/Material.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ function Material() {
5959
this.dithering = false;
6060

6161
this.alphaTest = 0;
62+
this.alphaToCoverage = false;
6263
this.premultipliedAlpha = false;
6364

6465
this.visible = true;
@@ -298,6 +299,7 @@ Material.prototype = Object.assign( Object.create( EventDispatcher.prototype ),
298299
if ( this.dithering === true ) data.dithering = true;
299300

300301
if ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest;
302+
if ( this.alphaToCoverage === true ) data.alphaToCoverage = this.alphaToCoverage;
301303
if ( this.premultipliedAlpha === true ) data.premultipliedAlpha = this.premultipliedAlpha;
302304

303305
if ( this.wireframe === true ) data.wireframe = this.wireframe;
@@ -421,6 +423,7 @@ Material.prototype = Object.assign( Object.create( EventDispatcher.prototype ),
421423
this.dithering = source.dithering;
422424

423425
this.alphaTest = source.alphaTest;
426+
this.alphaToCoverage = source.alphaToCoverage;
424427
this.premultipliedAlpha = source.premultipliedAlpha;
425428

426429
this.visible = source.visible;

src/renderers/webgl/WebGLState.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,10 @@ function WebGLState( gl, extensions, capabilities ) {
642642

643643
setPolygonOffset( material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits );
644644

645+
material.alphaToCoverage === true
646+
? enable( gl.SAMPLE_ALPHA_TO_COVERAGE )
647+
: disable( gl.SAMPLE_ALPHA_TO_COVERAGE );
648+
645649
}
646650

647651
//
@@ -885,6 +889,7 @@ function WebGLState( gl, extensions, capabilities ) {
885889
gl.disable( gl.POLYGON_OFFSET_FILL );
886890
gl.disable( gl.SCISSOR_TEST );
887891
gl.disable( gl.STENCIL_TEST );
892+
gl.disable( gl.SAMPLE_ALPHA_TO_COVERAGE );
888893

889894
gl.blendEquation( gl.FUNC_ADD );
890895
gl.blendFunc( gl.ONE, gl.ZERO );

utils/build/rollup.config.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,8 @@ function glconstants() {
152152
UNPACK_SKIP_IMAGES: 32877,
153153
MAX_SAMPLES: 36183,
154154
READ_FRAMEBUFFER: 36008,
155-
DRAW_FRAMEBUFFER: 36009
155+
DRAW_FRAMEBUFFER: 36009,
156+
SAMPLE_ALPHA_TO_COVERAGE: 32926
156157
};
157158

158159
return {

0 commit comments

Comments
 (0)