我正在尝试为粒子系统生成深度贴图,但如果我使用MeshDepthMaterial渲染粒子系统,那么每个粒子只会渲染为每个顶点的单个点 - 而不是覆盖纹理映射的整个区域粒子被显示出来。
我是否需要使用MeshDepthMaterial生成深度贴图,还是有其他选项?
答案 0 :(得分:4)
现在没有办法让MeshDepthMaterial尊重ParticleSystem的大小或纹理。但是,实现这样做的自定义ShaderMaterial并不难。首先,您需要一个顶点着色器和片段着色器。
<script type="x-shader/x-vertex" id="vertexShader">
uniform float size;
void main() {
gl_PointSize = size;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position , 1.0 );
}
</script>
<script type = "x-shader/x-fragment" id="fragmentShader">
uniform sampler2D map;
uniform float near;
uniform float far;
void main() {
float depth = gl_FragCoord.z / gl_FragCoord.w;
float depthColor = 1.0 - smoothstep( near, far, depth );
vec4 texColor = texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) );
gl_FragColor = vec4( vec3(depthColor), texColor.a);
}
</script>
顶点着色器完全是标准的,片段着色器采用纹理(sampler2D map
),但不是将其用于颜色值,而是使用alpha级别texColor.a
。对于rgb,使用基于深度的灰度值just like the MeshDepthMaterial。现在使用这个着色器你只需要抓取html并创建一个THREE.ShaderMaterial,如下所示:
var material = new THREE.ShaderMaterial({
uniforms : {
size : { type: 'f', value : 20.0 },
near : { type: 'f', value : camera.near },
far : { type: 'f', value : camera.far },
map : { type: "t", value : THREE.ImageUtils.loadTexture( url ) }
},
attributes : {},
vertexShader: vertShader,
fragmentShader: fragShader,
transparent: true
});
在这里,您为着色器提供了所需的所有信息:相机的近/远范围,粒子的大小以及需要映射的纹理。
您可以看到jsFiddle demo of it here。