繁体   English   中英

如何在three.js中动画网格的绘制

[英]How to animate the drawing of a mesh in three.js

我有一个由缓冲几何体制成的带状网格,其面是不可见的。 我为此使用了自定义着色器 - gl_FragColor = vec4(1.0,1.0,1.0,0.0)

当 3DObject 沿着功能区移动时,我会对其所在面的索引进行光线投射,并更新生成它们的着色器。

我对效果不满意,因为它产生了一个非常矮胖的动画。 如果我添加更多面孔,那么我的性能会受到严重影响。

有什么方法可以让我根据 3DObject 位置更新片段的 alpha 而不必求助于整个面部?

附带说明:我还尝试根据 x/z 像素位置从视图中剪下色带。 效果完美,性能好,但是当色带急转弯时会出现不良效果。

您可以通过如下设置drawRange来仅渲染BufferGeometry的一部分:

mesh.geometry.setDrawRange( startIndex, count );

有关更多信息和现场示例,请参阅此答案


编辑 - 正如下面的评论中提到的,另一种方法是向几何图形添加一个属性,它表示每个顶点沿几何图形定位的分数距离。 这种方法需要一个自定义的ShaderMaterial ,但您将能够平滑地为您的网格绘制动画。

这是一个示例顶点着色器和片段着色器

<script id="vertex_shader" type="x-shader/x-vertex">

attribute float distance;

varying float vDistance;
varying vec3 vNormal;
varying vec3 vViewPosition;

void main() {

    vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );

    vDistance = distance;
    vNormal = normalize( normalMatrix * normal );
    vViewPosition = - mvPosition.xyz;

    gl_Position = projectionMatrix * mvPosition;

}

</script>

<script id="fragment_shader" type="x-shader/x-fragment">

uniform float fraction;

varying float vDistance;
varying vec3 vNormal;
varying vec3 vViewPosition;

void main() {

    if ( vDistance > fraction ) discard;

    vec3 color = vec3( 0.25, 0.5, 1.0 );

    // hack in a fake pointlight at camera location, plus ambient
    vec3 normal = normalize( vNormal );
    vec3 lightDir = normalize( vViewPosition );

    float dotProduct = max( dot( normal, lightDir ), 0.0 ) + 0.2;

    // trick to make the clipped ends appear solid
    gl_FragColor = ( gl_FrontFacing ) ? vec4( color * dotProduct, 1.0 ) : vec4( color, 1.0 );

}

</script>

以下是如何向BufferGeometry添加属性并实例化材质。

// new attribute
var numVertices = geometry.attributes.position.count;
var distance = new Float32Array( numVertices * 1 ); // 1 value per vertex
geometry.addAttribute( 'distance', new THREE.BufferAttribute( distance, 1 ) );

// populate attribute
for ( var i = 0, l = numVertices; i < l; i ++ ) {

    // set new attribute
    distance[ i ] = ( geometry.attributes.position.getY( i ) + 10 ) / 20;

    // wiggle geometry a bit while we're at it
    var x = geometry.attributes.position.getX( i )
    var y = geometry.attributes.position.getY( i );
    geometry.attributes.position.setX( i, x + 2 * Math.sin( y ) );

}

// uniforms
var uniforms = {
    "fraction" : { value: 0 }
};

// material
var material = new THREE.ShaderMaterial( {
    uniforms        : uniforms,
    vertexShader    : document.getElementById( 'vertex_shader' ).textContent,
    fragmentShader  : document.getElementById( 'fragment_shader' ).textContent,
    side: THREE.DoubleSide
} );

// mesh
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );

然后,在您的渲染循环中,设置要渲染的所需分数:

mesh.material.uniforms.fraction.value = 0.5 * ( 1 + Math.cos( t ) );

小提琴: http : //jsfiddle.net/m99aj10b/

小提琴快照

三.js r.76

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM