1

我正在尝试为粒子系统生成深度图,但如果我使用 MeshDepthMaterial 渲染粒子系统,则每个粒子仅被渲染为每个顶点的单个点 - 不覆盖纹理映射粒子显示的整个区域.

我需要使用 MeshDepthMaterial 来生成深度图,还是有其他选择?

4

1 回答 1

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,使用基于深度的灰度值,就像 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 演示。

于 2012-12-05T08:53:09.883 回答