我正在研究2D头顶游戏的阴影。现在,阴影只是精灵,颜色(0,0,0,0.1)绘制在瓷砖上方的图层上。
问题:当许多实体或树木聚集在一起时,阴影重叠,形成不自然的黑暗区域。
我尝试将阴影绘制到帧缓冲区并使用简单的着色器来防止重叠,但这会导致其他问题,包括分层问题。 是否可以为防止“堆叠”的阴影启用某种混合功能,或者更好的方式来使用着色器?
答案 0 :(得分:0)
使用禁用的混合将阴影绘制到fbo。
绘制背景,例如草 从fbo绘制阴影纹理 绘制所有其他精灵
答案 1 :(得分:0)
如果您不想处理排序问题,我认为您可以使用着色器执行此操作。但是每个物体都必须受到阴影的影响。因此,高大的树木可以被标记为不是阴影接收,而地面,草地和角色将是阴影接收。
首先制作一个白色为清晰的帧缓冲区。将它上面的所有阴影都画成纯黑色。
然后制作阴影贴图着色器以绘制您世界中的所有内容。这依赖于你不需要精灵颜色的所有四个通道,因为我们需要其中一个通道将每个精灵标记为阴影接收与否。例如,如果您没有使用RGB来为您的精灵着色,我们可以使用R通道。或者,如果你没有淡入淡出它们,我们可以使用A.我会假设后者:
顶点着色器:
attribute vec4 a_position;
attribute vec4 a_color;
attribute vec2 a_texCoord0;
varying vec2 v_texCoords;
varying vec2 v_texCoordsShadowmap;
varying vec4 v_color;
uniform mat4 u_projTrans;
void main()
{
v_texCoords = a_texCoord0;
v_color = a_color;
v_color.a = v_color.a * (255.0/254.0); //this is a correction due to color float precision (see SpriteBatch's default shader)
vec3 screenPosition = u_projTrans * a_position;
v_texCoordsShadowmap = (screenPosition.xy * 0.5) + 0.5;
gl_Position = screenPosition;
}
片段着色器:
#ifdef GL_ES
precision mediump float;
#endif
varying vec2 v_texCoords;
varying vec2 v_texCoordsShadowmap;
varying vec4 v_color;
uniform sampler2D u_texture;
uniform sampler2D u_textureShadowmap;
void main()
{
vec4 textureColor = texture2D(u_texture, v_texCoords);
float shadowColor = texture2D(u_textureShadowmap, v_texCoordsShadowmap).r;
shadowColor = mix(shadowColor, 1.0, v_color.a);
textureColor.rgb *= shadowColor * v_color.rgb;
gl_FragColor = textureColor;
}
这些都是完全未经测试的,可能还有错误。确保将帧缓冲区的颜色纹理分配给“u_textureShadowmap”。对于你所有的精灵,根据你希望它们投射多少阴影来设置它们的颜色alpha,它通常总是0或0.1(基于你之前使用的亮度)。