我正在尝试为粒子系统生成深度图,但如果我使用 MeshDepthMaterial 渲染粒子系统,则每个粒子仅被渲染为每个顶点的单个点 - 不覆盖纹理映射粒子显示的整个区域.
我需要使用 MeshDepthMaterial 来生成深度图,还是有其他选择?
现在没有办法让 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,使用基于深度的灰度值,就像 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 演示。