【问题标题】:2D Ambient lighting in OpenGLOpenGL 中的 2D 环境光照
【发布时间】:2013-08-14 04:20:53
【问题描述】:

我正在制作一个 2D 横向卷轴游戏,我目前正在实现灯光。灯光只是在地形顶部渲染的灯光渐变纹理,相乘以使其照亮该区域。但是,我不知道怎么做,也不知道怎么做环境光。下图总结了我所拥有的,底部是我想要的。

我愿意接受有关着色器的答案,因为我知道如何使用它们。

【问题讨论】:

  • 环境光很简单,它是在没有任何光源的情况下的基础照明颜色。它在您的整个材质中是均匀的,并且由于它没有方向,您可以将它与光照模型中累积的漫反射项结合起来。如果您要进行多通道照明,您将首先执行一个通道,其中地形由您的恒定环境项调制,然后为每个附加光的漫反射/镜面反射贡献进行加法混合。
  • 所以当我渲染地形原始纹理的三角形时,我需要将它通过环境光照着色器?
  • 有点。实际上,您想要做的是累积每个灯光的所有光照项(加上全局环境项),然后在最后用这个值调制基础纹理颜色。所以你真的会按照这个顺序进行加法混合:环境、Light0、Light1、Light2、...、Light N,然后是使用基础纹理颜色的最后一次乘法混合。它是:(Ambient + Diffuse)* Base Color
  • 只是为了澄清术语。环境光是间接照明的粗略近似。由于间接光只能增加亮度,因此您不希望它达到底部图像。要使图像中的某个区域变暗,您可以简单地减少光照图中的相应因子
  • 非常好,这很有帮助。

标签: c++ opengl 2d lighting


【解决方案1】:

我最终创建了一个屏幕大小的 FBO 纹理,用环境颜色清除它并绘制所有附近的灯光。然后,我将它通过我制作的着色器,该着色器包含 2 个用于制服的纹理。要绘制的纹理和灯光 FBO 本身。着色器将使用 FBO 绘制的纹理相乘,效果很好。

ambience.frag

uniform sampler2D texture1;
uniform sampler2D texture2;
varying vec2 texCoord;

void main( void ) {
    vec4 color1 = vec4(texture2D(texture1, gl_TexCoord[0].st));
    vec4 color2 = vec4(texture2D(texture2, texCoord));
    gl_FragColor = color1*vec4(color2.r,color2.g,color2.b,1.0);
}

氛围.vs

varying vec2 texCoord;
uniform vec2 screen;
uniform vec2 camera;

void main(){
    gl_Position = ftransform();
    gl_TexCoord[0] = gl_MultiTexCoord0;
    vec2 temp = vec2(gl_Vertex.x,gl_Vertex.y)-camera;
    texCoord = temp/screen;
}

【讨论】:

  • 你应该学会在 GLSL 中使用 swizzling。而不是 vec4 (color2.r, color2.g, color2.b, 1.0) 您实际上可以这样做:vec4 (color2.rgb, 1.0)。同样,在您的顶点着色器中,您可以使用gl_Vertex.xy 而不是 vec2 (gl_Vertex.x, gl_Vertex.y)。此外,如果纹理 2 是 3 通道纹理格式,则当您对其进行采样时,GLSL 会自动为第 4 个组件分配值 1.0。
  • 在另一个相关说明中,如果您打算以这种方式进行照明,请确保在将 FBO 纹理拉伸到屏幕上时使用orthographic 投影。你需要你的像素中心与纹理中心对齐,否则你会遇到纹理过滤问题模糊(线性)或混叠(最近)。透视校正通常会错误对齐您的纹理坐标。我在这里回答了一个类似的问题:stackoverflow.com/questions/18152963/… 最近。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-08
  • 1970-01-01
  • 2012-01-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多