three.js: 如何让透明的png精灵投射和接收阴影?

three.js: how to let transparent png sprites cast and receive shadows?

我不确定这是否可行,但我认为值得一问:是否有允许精灵投射和接收阴影的功能、选项或某些着色器?还包括该精灵的 alpha 通道未渲染为阴影。

我的所有资产都是透明的 PNG,我在 three.js 中使用精灵将纹理映射到精灵上。除了阴影问题之外,这非常有效。理想情况下,精灵投射的阴影不包括 PNG 的 alpha 通道*,这样光线会穿过 png 的 alpha 通道,尽管我在 threejs 的文档中发现对此的研究很少。

也许这在 threejs 下是不可能的,或者根本不可能,这是可以理解的,但在此先感谢。

*我正在考虑与说唱歌手 PaRappa 或 Adventure Xpress 类似的风格。

three.js 中的精灵不投射阴影。

一种解决方法是使用 PlaneBufferGeometry 并像这样使其朝向相机:

scene.add( plane );

然后在渲染循环中,

plane.lookAt( camera.position );

如果您希望平面不在平面纹理透明的任何地方投射阴影,则需要创建自定义深度 material。在 this three.js 示例中可以看到这样做的示例。

在不创建自定义深度的情况下 material,从灯光的角度来看,该平面将呈现为实体。

three.js r.76

这些是我最终使用的着色器。

片段着色器。您可以更改 pixel.a 这是像素的 alpha 值。如果 alpha 值低于 0.5(从而使其看起来透明),则片段着色器将在此像素上丢弃。

#include <packing>

uniform sampler2D texture;
varying vec2 vUV;

void main() {

    vec4 pixel = texture2D( texture, vUV );
    if ( pixel.a < 0.5 ) discard;
    gl_FragData[ 0 ] = packDepthToRGBA( gl_FragCoord.z );

}

顶点着色器。这没什么特别的,我想我会把它留在这里以防万一你的顶点着色器导致问题,我可以确认这个与上面的片段着色器兼容。

varying vec2 vUV;

void main() {

    vUV = uv;
    vec4 mvPosition = modelViewMatrix * vec4( position, 1 );
    gl_Position = projectionMatrix * mvPosition;

}