在绿色表面LWJGL

时间:2018-10-27 21:34:44

标签: glsl lwjgl

嘿,我在2D Tile Based游戏中使用照明的每个人都遇到了照明计算问题,在我的游戏中,我拍摄灰度图像,然后使用着色器为它们着色,无论我喜欢哪种颜色,是否为绿色(rgb =(0,1,0))或红色(rgb =(1,0,0))或任何颜色。因此,然后将照明计算应用于该纹理和彩色像素。当光线为白色(rgb =(1,1,1))时,照明工作正常,但是当说红色或绿色时,则不会显示我想要的方式。我知道为什么会这样,因为在纯绿色的房间中现实的纯红色光不会反射任何红色的光,因此房间会保持黑暗。我真正想要的是看到绿色表面上出现红光。所以我的问题是我怎么能在绿色表面上清晰地显示红光?(或者在任何表面上实际上是任何其他颜色)

这是我的片段着色器的代码,其中衰减仅是灯光的衰减,lightColor显然是灯光的rgb值,distance是从给定矢量到该灯光的距离(在顶点着色器中计算),最后颜色是应用于纹理的rgb值。

在此先感谢您的帮助!

vec3 totalDiffuse = vec3(0.0);

for(int i = 0; i < 4; i++)
{
    float attFactor = attenuation[i].x + (attenuation[i].y * distance[i]) + (attenuation[i].z * distance[i] * distance[i]);
    totalDiffuse = totalDiffuse + (lightColor[i])/attFactor;
}
totalDiffuse = max(totalDiffuse,0.2);

out_Color = texture(textureSampler, pass_textureCoords)*vec4(color,alpha)*vec4(totalDiffuse,1);

这是当前表面上纯红色光的图像,它应该在白色圆圈内,您可能会看到它对水有一点影响,因为我给了水一点点红色成分 Light Demo Image

1 个答案:

答案 0 :(得分:0)

一种可能是更改光照计算。

计算浅色和表面色的灰度。将表面颜色乘以浅色的灰度,然后将颜色乘以表面色的灰度,最后求和:

vec4  texCol  = texture(textureSampler, pass_textureCoords);
float grayTex = dot(texCol.rgb,  vec3(0.2126, 0.7152, 0.0722));
float grayCol = dot(colGray.rgb, vec3(0.2126, 0.7152, 0.0722));

vec3  mixCol  = texCol.rgb * grayCol + color.rgb * grayTex;

out_Color     = vec4(mixCol * totalDiffuse, texCol.a * alpha); 

请注意,此算法强调光的颜色,但会牺牲表面的颜色。但这就是您想要的,将绿色区域浸入红光中。当然,这与以其自身的颜色照亮区域的愿望相矛盾。如果灯是白色,则表面也会发白。

如果您希望某些光源具有上述效果,而另一些光源却具有问题的原始效果,那么我建议您引入一个参数来混合两种效果:

uniform float u_lightTint;

void main()
{
    .....

    vec3 mixCol = texCol.rgb * grayCol + color.rgb * grayTex;

    mixCol      = mix(texCol.rgb * color.rgb, mixCol.rgb, u_lightTint);

    out_Color   = vec4(mixCol * totalDiffuse, texCol.a * alpha); 
} 

如果将u_lightTint设置为1.0,则使用“新”光计算,将其设置为0.0,然后使用原始光计算。两种算法都可以通过u_lightTint进行线性插值。
另外,可以在浅色的Alpha通道中对u_lightTint参数进行编码:

mixCol = mix(texCol.rgb * color.rgb, mixCol.rgb, color.a);