纹理图集偏移/重复适用于网格,但忽略点系统粒子

jnm*_*nm2 1 textures webgl three.js

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

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

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

有没有比使用画布切割图像更好的解决方法?

编辑:根据要求,可在http://jnm2.com/minesweeper/上获取正在进行的工作.

Wes*_*ley 6

THREE.PointCloudMaterial已重命名THREE.PointsMaterial.

THREE.PointCloud已重命名THREE.Points.


你想在你的点云中使用精灵表.

您可以创建自定义,而不是PointsMaterial与您一起使用.PointsShaderMaterial

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

为此,请使用如下着色器:

<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 texture;
uniform vec2 repeat;

varying vec2 vOffset;

void main() {

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

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

    if ( tex.a < 0.5 ) discard;

    gl_FragColor = tex;

}

</script>
Run Code Online (Sandbox Code Playgroud)

设置你的BufferGeometry喜欢:

// vertices
var geometry = new THREE.SphereGeometry( 100, 16, 12 );
geometry.mergeVertices(); // to remove duplicate vertices at the poles
var vertices = geometry.vertices;

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

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

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

// populate positions
geometry.attributes.position.copyVector3sArray( vertices );

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

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;

}
Run Code Online (Sandbox Code Playgroud)

ShaderMaterial喜欢这样:

// uniforms
uniforms = {

    texture:    { 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 );
Run Code Online (Sandbox Code Playgroud)

小提琴:http://jsfiddle.net/myy7x4zd/10/

three.js r.84