2012-12-05 55 views
1

我正在嘗試爲粒子系統生成深度貼圖,但是如果使用MeshDepthMaterial渲染粒子系統,則每個粒子僅呈現爲每個頂點的粒子系統的單個點 - - 不覆蓋紋理映射粒子顯示的整個區域。使用紋理貼圖的粒子系統的深度圖

我是否需要使用MeshDepthMaterial生成深度圖,或者是否有其他選項?

回答

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),但代替使用它的顏色值它只是使用的α水平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

+0

謝謝,保羅。偉大的迴應。實際上,我甚至不需要生成深度貼圖,一旦我發現着色器中使用的深度信息在片段着色器中可用(gl_FragCoord.z/gl_FragCoord.w),我可以通過一次完成整個效果。 – Someone