我正在使用纹理图集来保存一系列图像。使用MeshLambertMaterial
映射到网格时,使用Texture.offset
和Texture.repeat
可以很好地剪切整个图像中的子纹理。
然而,对PointCloudMaterial
使用完全相同的纹理实例会使粒子与整个图集呈现,而不仅仅是选定的子图像。
我尝试遵循three.js源代码,但文档很少。
是否有比使用画布切割图像更好的解决方法?
修改:根据要求,http://jnm2.com/minesweeper/可以使用正在进行的工作。
答案 0 :(得分:5)
THREE.PointCloudMaterial
已重命名为THREE.PointsMaterial
。
THREE.PointCloud
已重命名为THREE.Points
。
您希望在点云中使用精灵表。
您可以改为创建自定义PointsMaterial
,而不是将Points
与ShaderMaterial
一起使用。
自定义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>
如此设置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;
}
你的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 );
小提琴:http://jsfiddle.net/myy7x4zd/10/
three.js r.84