未验证 提交 1d6d3c77 编写于 作者: M Mr.doob 提交者: GitHub

Merge pull request #13584 from WestLangley/dev-dashed

Fat lines example: add support for dashed lines
......@@ -4,6 +4,10 @@
* parameters = {
* color: <hex>,
* linewidth: <float>,
* dashed: <boolean>,
* dashScale: <float>,
* dashSize: <float>,
* gapSize: <float>,
* resolution: <Vector2>, // to be set by renderer
* }
*/
......@@ -11,7 +15,10 @@
THREE.UniformsLib.line = {
linewidth: { value: 1 },
resolution: { value: new THREE.Vector2( 1, 1 ) }
resolution: { value: new THREE.Vector2( 1, 1 ) },
dashScale: { value: 1 },
dashSize: { value: 1 },
gapSize: { value: 1 } // todo FIX - maybe change to totalSize
};
......@@ -42,6 +49,15 @@ THREE.ShaderLib[ 'line' ] = {
varying vec2 vUv;
#ifdef USE_DASH
uniform float dashScale;
attribute float instanceDistanceStart;
attribute float instanceDistanceEnd;
varying float vLineDistance;
#endif
void trimSegment( const in vec4 start, inout vec4 end ) {
// trim end segment so it terminates between the camera plane and the near plane
......@@ -60,7 +76,15 @@ THREE.ShaderLib[ 'line' ] = {
void main() {
#ifdef USE_COLOR
vColor.xyz = ( position.y < 0.5 ) ? instanceColorStart : instanceColorEnd;
#endif
#ifdef USE_DASH
vLineDistance = ( position.y < 0.5 ) ? dashScale * instanceDistanceStart : dashScale * instanceDistanceEnd;
#endif
float aspect = resolution.x / resolution.y;
......@@ -158,18 +182,35 @@ THREE.ShaderLib[ 'line' ] = {
uniform vec3 diffuse;
uniform float opacity;
#ifdef USE_DASH
uniform float dashSize;
uniform float gapSize;
#endif
varying float vLineDistance;
#include <common>
#include <color_pars_fragment>
#include <fog_pars_fragment>
#include <logdepthbuf_pars_fragment>
#include <clipping_planes_pars_fragment>
varying vec2 vUv;
varying vec2 vUv;
void main() {
#include <clipping_planes_fragment>
#ifdef USE_DASH
if ( vUv.y < 0.5 || vUv.y > 0.5 ) discard; // discard endcaps
if ( mod( vLineDistance, dashSize + gapSize ) > dashSize ) discard; // todo - FIX
#endif
if ( vUv.y < 0.5 || vUv.y > 0.5 ) {
float a = vUv.x - 0.5;
......@@ -209,6 +250,8 @@ THREE.LineMaterial = function ( parameters ) {
} );
this.dashed = false;
Object.defineProperties( this, {
color: {
......@@ -247,6 +290,60 @@ THREE.LineMaterial = function ( parameters ) {
},
dashScale: {
enumerable: true,
get: function () {
return this.uniforms.dashScale.value;
},
set: function ( value ) {
this.uniforms.dashScale.value = value;
}
},
dashSize: {
enumerable: true,
get: function () {
return this.uniforms.dashSize.value;
},
set: function ( value ) {
this.uniforms.dashSize.value = value;
}
},
gapSize: {
enumerable: true,
get: function () {
return this.uniforms.gapSize.value;
},
set: function ( value ) {
this.uniforms.gapSize.value = value;
}
},
resolution: {
enumerable: true,
......
......@@ -20,6 +20,40 @@ THREE.LineSegments2.prototype = Object.assign( Object.create( THREE.Mesh.prototy
isLineSegments2: true,
computeLineDistances: ( function () { // for backwards-compatability, but could be a method of LineSegmentsGeometry...
var start = new THREE.Vector3();
var end = new THREE.Vector3();
return function computeLineDistances() {
var geometry = this.geometry;
var instanceStart = geometry.attributes.instanceStart;
var instanceEnd = geometry.attributes.instanceEnd;
var lineDistances = new Float32Array( 2 * instanceStart.data.count );
for ( var i = 0, j = 0, l = instanceStart.data.count; i < l; i ++, j += 2 ) {
start.fromBufferAttribute( instanceStart, i );
end.fromBufferAttribute( instanceEnd, i );
lineDistances[ j ] = ( j === 0 ) ? 0 : lineDistances[ j - 1 ];
lineDistances[ j + 1 ] = lineDistances[ j ] + start.distanceTo( end );
}
var instanceDistanceBuffer = new THREE.InstancedInterleavedBuffer( lineDistances, 2, 1 ); // d0, d1
geometry.addAttribute( 'instanceDistanceStart', new THREE.InterleavedBufferAttribute( instanceDistanceBuffer, 1, 0 ) ); // d0
geometry.addAttribute( 'instanceDistanceEnd', new THREE.InterleavedBufferAttribute( instanceDistanceBuffer, 1, 1 ) ); // d1
return this;
};
}() ),
copy: function ( source ) {
// todo
......
......@@ -20,6 +20,40 @@ THREE.Wireframe.prototype = Object.assign( Object.create( THREE.Mesh.prototype )
isWireframe: true,
computeLineDistances: ( function () { // for backwards-compatability, but could be a method of LineSegmentsGeometry...
var start = new THREE.Vector3();
var end = new THREE.Vector3();
return function computeLineDistances() {
var geometry = this.geometry;
var instanceStart = geometry.attributes.instanceStart;
var instanceEnd = geometry.attributes.instanceEnd;
var lineDistances = new Float32Array( 2 * instanceStart.data.count );
for ( var i = 0, j = 0, l = instanceStart.data.count; i < l; i ++, j += 2 ) {
start.fromBufferAttribute( instanceStart, i );
end.fromBufferAttribute( instanceEnd, i );
lineDistances[ j ] = ( j === 0 ) ? 0 : lineDistances[ j - 1 ];
lineDistances[ j + 1 ] = lineDistances[ j ] + start.distanceTo( end );
}
var instanceDistanceBuffer = new THREE.InstancedInterleavedBuffer( lineDistances, 2, 1 ); // d0, d1
geometry.addAttribute( 'instanceDistanceStart', new THREE.InterleavedBufferAttribute( instanceDistanceBuffer, 1, 0 ) ); // d0
geometry.addAttribute( 'instanceDistanceEnd', new THREE.InterleavedBufferAttribute( instanceDistanceBuffer, 1, 1 ) ); // d1
return this;
};
}() ),
copy: function ( source ) {
// todo
......
......@@ -57,8 +57,9 @@
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var line, wireframe, renderer, scene, camera, controls;
var line1, wireframe1;
var line, renderer, scene, camera, controls;
var line1;
var matLine, matLineBasic, matLineDashed;
var stats;
var gui;
......@@ -80,7 +81,7 @@
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.set( -40, 0, 60 );
camera.position.set( - 40, 0, 60 );
controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.minDistance = 10;
......@@ -115,16 +116,18 @@
geometry.setPositions( positions );
geometry.setColors( colors );
var material = new THREE.LineMaterial( {
matLine = new THREE.LineMaterial( {
color: 0xffffff,
linewidth: 10, // in pixels
linewidth: 5, // in pixels
vertexColors: THREE.VertexColors,
//resolution: // to be set by renderer, eventually
dashed: false
} );
line = new THREE.Line2( geometry, material );
line = new THREE.Line2( geometry, matLine );
line.computeLineDistances();
line.scale.set( 1, 1, 1 );
scene.add( line );
......@@ -135,44 +138,14 @@
geo.addAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) );
geo.addAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) );
var mat = new THREE.LineBasicMaterial( { vertexColors: THREE.VertexColors } );
matLineBasic = new THREE.LineBasicMaterial( { vertexColors: THREE.VertexColors } );
matLineDashed = new THREE.LineDashedMaterial( { vertexColors: THREE.VertexColors, scale: 2, dashSize: 1, gapSize: 1 } );
line1 = new THREE.Line( geo, mat );
line1 = new THREE.Line( geo, matLineBasic );
line1.computeLineDistances();
line1.visible = false;
scene.add( line1 );
// THREE.Wireframe ( WireframeGeometry2, LineMaterial )
//var geo = new THREE.BoxBufferGeometry( 16, 16, 4, 2, 2, 1 );
//var geo = new THREE.IcosahedronBufferGeometry( 8, 0 );
var geo = new THREE.PlaneBufferGeometry( 16, 16, 2, 2 );
var geometry = new THREE.WireframeGeometry2( geo );
var material = new THREE.LineMaterial( {
color: 0x4080ff,
linewidth: 10, // in pixels
//resolution: // to be set by renderer, eventually
} );
wireframe = new THREE.Wireframe( geometry, material );
wireframe.scale.set( 1, 1, 1 );
scene.add( wireframe );
// THREE.Line ( WireframeGeometry, LineBasicMaterial ) - rendered with gl.LINE
geo = new THREE.WireframeGeometry( geo );
var mat = new THREE.LineBasicMaterial( { color: 0x4080ff } );
wireframe1 = new THREE.LineSegments( geo, mat );
wireframe1.visible = false;
scene.add( wireframe1 );
//
window.addEventListener( 'resize', onWindowResize, false );
......@@ -203,13 +176,10 @@
stats.update();
wireframe.geometry.maxInstancedCount = Math.floor( Date.now() / 1000 ) % wireframe.geometry.index.count - 1; // why - 1 needed ?
// main scene
// renderer will set this eventually
line.material.resolution.set( window.innerWidth, window.innerHeight );
wireframe.material.resolution.set( window.innerWidth, window.innerHeight );
matLine.resolution.set( window.innerWidth, window.innerHeight );
renderer.setViewport( 0, 0, window.innerWidth, window.innerHeight );
......@@ -218,8 +188,7 @@
// inset scene
// renderer will set this eventually
//line.material.resolution.set( insetWidth, insetHeight );
//wireframe.material.resolution.set( insetWidth, insetHeight );
//matLine.resolution.set( insetWidth, insetHeight ); // not sure what behavior we want here...
renderer.clearDepth(); // important!
......@@ -243,7 +212,10 @@
var param = {
'line type': 0,
'line width': 10
'width (px)': 5,
'dashed': false,
'dash scale': 1,
'dash / gap': 1
};
......@@ -253,19 +225,15 @@
case '0':
line.visible = true;
wireframe.visible = true;
line1.visible = false;
wireframe1.visible = false;
break;
case '1':
line.visible = false;
wireframe.visible = false;
line1.visible = true;
wireframe1.visible = true;
break;
......@@ -273,10 +241,65 @@
} );
gui.add( param, 'line width', 1, 40, 1 ).onChange( function ( val ) {
gui.add( param, 'width (px)', 1, 10, 1 ).onChange( function ( val ) {
matLine.linewidth = val;
} );
gui.add( param, 'dashed' ).onChange( function ( val ) {
matLine.dashed = val;
line.material.linewidth = val;
wireframe.material.linewidth = val;
// dashed is implemented as a defines -- not as a uniform. this could be changed.
// ... or LineDashedMaterial could be implemented as a separate material
// temporary hack - renderer should do this eventually
if ( val ) matLine.defines.USE_DASH = ""; else delete matLine.defines.USE_DASH;
matLine.needsUpdate = true;
line1.material = val ? matLineDashed : matLineBasic;
} );
gui.add( param, 'dash scale', 0.5, 2, 0.1 ).onChange( function ( val ) {
matLine.dashScale = val;
matLineDashed.scale = val;
} );
gui.add( param, 'dash / gap', { '2 : 1': 0, '1 : 1': 1, '1 : 2': 2 } ).onChange( function ( val ) {
switch ( val ) {
case '0':
matLine.dashSize = 2;
matLine.gapSize = 1;
matLineDashed.dashSize = 2;
matLineDashed.gapSize = 1;
break;
case '1':
matLine.dashSize = 1;
matLine.gapSize = 1;
matLineDashed.dashSize = 1;
matLineDashed.gapSize = 1;
break;
case '2':
matLine.dashSize = 1;
matLine.gapSize = 2;
matLineDashed.dashSize = 1;
matLineDashed.gapSize = 2;
break;
}
} );
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册