2016-03-08 61 views
1

我正在使用自定義着色器來曲面化平面。我的自定義着色器擴展了Lambert着色器,因此它支持燈光和陰影。這一切都按預期工作,但是當vertexShader更改平面的幾何圖形時,陰影不會更新。有什麼我失蹤標記幾何更新在我的vertexShader和陰影需要改變?當使用VertexShader更改幾何體時,陰影不會更新

[這是問題的截圖。這架飛機是彎曲的一個vertexShader,但陰影不更新] [1] [1]:http://i.stack.imgur.com/6kfCF.png

這裏是演示/代碼:http://dev.cartelle.nl/curve/ 如果拖動「bendAngle」滑塊,你可以看到,陰影不會更新。

我認爲的一種解決方法是獲得我的彎曲平面的邊界框。然後使用這些點並創建一個新的Mesh/Box並使用該對象來投射陰影。但後來我不確定如何獲得新的曲面幾何體的座標。當我在應用着色器後檢查geometry.boundingBox時,它每次都會給我原始座標。

感謝 約翰尼

+0

請將相關的代碼片段添加到您的問題。鏈接可以中斷。 – WestLangley

回答

1

如果要修改的頂點着色器的幾何位置,而你投下陰影,你需要指定一個定製的深度材料所以陰影將修改後的位置做出迴應。

在您的自定義深度材質的頂點着色器中,可以按照在材質的頂點着色器中修改頂點位置的方式修改頂點位置。

自定義深度材質的示例可以在this three.js example中看到(儘管在該示例中,頂點着色器中的頂點未經過修改;它們在CPU上進行了修改)。

在你的情況,你會創建一個頂點着色器使用的模式,像這樣的自定義深度材料:片段着色器

<script type="x-shader/x-vertex" id="vertexShaderDepth"> 

    uniform float bendAngle; 
    uniform vec2 bounds; 
    uniform float bendOffset; 
    uniform float bendAxisAngle; 

    vec3 bendIt(vec3 ip, float ba, vec2 b, float o, float a) { 
     // your code here 
     return ip; 
    } 

    void main() { 

     vec3 p = bendIt(position, bendAngle, bounds, bendOffset, bendAxisAngle); 

     vec4 mvPosition = modelViewMatrix * vec4(p, 1.0); 

     gl_Position = projectionMatrix * mvPosition; 

    } 

</script> 

而像這樣:

<script type="x-shader/x-fragment" id="fragmentShaderDepth"> 

    vec4 pack_depth(const in float depth) { 

     const vec4 bit_shift = vec4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0); 
     const vec4 bit_mask = vec4(0.0, 1.0/256.0, 1.0/256.0, 1.0/256.0); 
     vec4 res = fract(depth * bit_shift); 
     res -= res.xxyz * bit_mask; 
     return res; 

    } 

    void main() { 

     gl_FragData[ 0 ] = pack_depth(gl_FragCoord.z); 

    } 
</script> 

然後,在JavaScript,您指定了自定義深度材質:

uniforms = {}; 
uniforms.bendAngle = { type: "f", value: properties.bendAngle }; 
uniforms.bendOffset = { type: "f", value: properties.offset }; 
uniforms.bendAxisAngle = { type: "f", value: properties.bendAxisAngle }; 
uniforms.bounds = { type: "v2", value: new THREE.Vector2(- 8, 16) }; 

var vertexShader = document.getElementById('vertexShaderDepth').textContent; 
var fragmentShader = document.getElementById('fragmentShaderDepth').textContent; 

myObject.customDepthMaterial = new THREE.ShaderMaterial({ 
    uniforms: uniforms, 
    vertexShader: vertexShader, 
    fragmentShader: fragmentShader 
}); 

three.js r.74

+0

真棒。謝謝! –

+0

因此,在r.84中看起來應該將customDepthMaterial分配給材質而不是網格。我有一個替代頂點的自定義ShaderMaterial,並且我還爲其分配了一個customDepthMaterial。如果我在其fragmentShader中輸入一個拼寫錯誤,深度材質沒有任何效果,並且出乎意料地不會拋出錯誤。 console.log(myMaterial.customDepthMaterial.fragmentShader)顯示所需的深度片段着色器。任何猜測爲什麼我不能插入customDepthMaterial? (我也做了myObject.castShadow = myObject.receiveShadow = true) –

相關問題