2016-03-08 40 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) –

相关问题