问题描述
我正在使用纹理图集来保存一系列图像.当使用 MeshLambertMaterial
映射到网格时,使用 Texture.offset
和 Texture.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
这篇关于纹理图集偏移/重复适用于网格,但对于点系统粒子会被忽略的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!