本文介绍了纹理图集偏移/重复适用于网格,但对于点系统粒子会被忽略的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用纹理图集来保存一系列图像.当使用 MeshLambertMaterial 映射到网格时,使用 Texture.offsetTexture.repeat 可以很好地从整个图像中切出子纹理.

I am using a texture atlas to hold a sequence of images. When mapping to a mesh with MeshLambertMaterial, using Texture.offset and Texture.repeat works beautifully to cut the subtexture out of the entire image.

但是,对 PointCloudMaterial 使用完全相同的纹理实例会使用整个图集渲染粒子,而不仅仅是选定的子图像.

However, using the exact same texture instance for a PointCloudMaterial renders the particles with the entire atlas, not just the selected subimage.

我试图遵循three.js源代码,但文档很少.

I tried to follow the three.js source code, but the documentation is scarce.

是否有比使用画布切碎图像更好的解决方法?

Is there a workaround for this better than using canvases to chop up the image?

根据要求,在 http://jnm2.com/minesweeper/.

推荐答案

THREE.PointCloudMaterial 已更名为 THREE.PointsMaterial.

THREE.PointCloud 已更名为 THREE.Points.

您想对点云使用精灵表.

You want to use a sprite sheet with your point cloud.

您可以创建一个自定义的 ShaderMaterial 而不是将 PointsMaterial 与您的 Points 一起使用.

Instead of using PointsMaterial with your Points, you can create a custom ShaderMaterial instead.

自定义ShaderMaterial 可以访问您的精灵表并为每个粒子使用不同的子图像.

The custom ShaderMaterial can access your sprite sheet and use a different sub-image for each particle.

为此,请使用像这样的着色器:

To do so, use a shader like this one:

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

attribute vec2 offset;

varying vec2 vOffset;

void main() {

    vOffset = offset;

    gl_PointSize = 25.0;

    gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );

}
</script>

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

uniform sampler2D spriteSheet;
uniform vec2 repeat;

varying vec2 vOffset;

void main() {

    vec2 uv = vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y );

    vec4 tex = texture2D( spriteSheet, uv * repeat + vOffset );

    if ( tex.a < 0.5 ) discard;

    gl_FragColor = tex;

}

</script>

然后

   // geometry
    geometry = new THREE.BufferGeometry();

    // attributes
    var numVertices = 20;
    var positions = new Float32Array( numVertices * 3 ); // 3 coordinates per point
    var offsets = new Float32Array( numVertices * 2 ); // 2 coordinates per point

    geometry.setAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
    geometry.setAttribute( 'offset', new THREE.BufferAttribute( offsets, 2 ) );

    // populate offsets
    var offset = new THREE.Vector2();

    for ( var i = 0, index = 0, l = numVertices; i < l; i ++, index += 3 ) {

        positions[ index ] = 100 * Math.random() - 50;
        positions[ index + 1 ] = 100 * Math.random() - 50;
        positions[ index + 2 ] = 100 * Math.random() - 50;

    }

   for ( var i = 0, index = 0, l = numVertices; i < l; i ++, index += 2 ) {

        offset.set( THREE.Math.randInt( 1, 3 ), THREE.Math.randInt( 2, 3 ) ).multiplyScalar( 0.25 ); // sprite sheet: 4 rows x 4 cols

        offsets[ index ] = offset.x;
        offsets[ index + 1 ] = offset.y;

    }

    // image
    image = document.createElement( 'img' );
    image.addEventListener( 'load', function ( event ) { texture.needsUpdate = true; } );

    // texture
    var texture = new THREE.Texture( image );

    // uniforms
    uniforms = {

        spriteSheet: { value: texture },
        repeat: { value: new THREE.Vector2( 0.25, 0.25 ) }

    };

    // material
    var material = new THREE.ShaderMaterial( {

        uniforms:       uniforms,
        vertexShader:   document.getElementById( 'vertexshader' ).textContent,
        fragmentShader: document.getElementById( 'fragmentshader' ).textContent,
        transparent:    true

    } );

    // point cloud
    pointCloud = new THREE.Points( geometry, material );

    scene.add( pointCloud );

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

three.js r.126

three.js r.126

这篇关于纹理图集偏移/重复适用于网格,但对于点系统粒子会被忽略的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 13:24