1

最近我在我的引擎中添加了延迟着色支持;但是我遇到了一些衰减问题:在此处输入图像描述

如您所见,当我渲染光量(球体)时,它与图像的环境部分不能很好地融合!

以下是我声明我的点光源的方式:

PointLight pointlight;
pointlight.SetPosition(glm::vec3(0.0, 6.0, 0.0));
pointlight.SetIntensity(glm::vec3(1.0f, 1.0f, 1.0f));

这是我计算光球半径的方法:

Attenuation attenuation = pointLights[i].GetAttenuation();
    float lightMax = std::fmaxf(std::fmax(pointLights[i].GetIntensity().r, pointLights[i].GetIntensity().g),
        pointLights[i].GetIntensity().b);

    float pointLightRadius = (-attenuation.linear +
        std::sqrtf(std::pow(attenuation.linear, 2.0f) - 4.0f * attenuation.exponential *
            (attenuation.constant - (256.0f / 5.0f) * lightMax))) / (2.0f * attenuation.exponential);

最后,这是我的 PointLightPass 片段着色器:

#version 450 core

struct BaseLight
{
    vec3 intensities;//a.k.a color of light
    float ambientCoeff;
};

struct Attenuation
{
    float constant;
    float linear;
    float exponential;
};

struct PointLight
{
    BaseLight base;
    Attenuation attenuation;
    vec3 position;
};

struct Material
{
    float shininess;
    vec3  specularColor;
    float ambientCoeff;
};


layout (std140) uniform Viewport
{
    uniform mat4 Projection;
    uniform mat4 View;
    uniform mat4 ViewProjection;
    uniform vec2 scrResolution;
};

layout(binding = 0) uniform sampler2D gPositionMap;
layout(binding = 1) uniform sampler2D gAlbedoMap;
layout(binding = 2) uniform sampler2D gNormalMap;
layout(binding = 3) uniform sampler2D gSpecularMap;

uniform vec3 cameraPosition;
uniform PointLight pointLight;

out vec4 fragmentColor;

vec2 FetchTexCoord()
{
      return gl_FragCoord.xy / scrResolution;
}

void main()
{
      vec2 texCoord = FetchTexCoord();
      vec3 gPosition =      texture(gPositionMap, texCoord).xyz;
      vec3 gSurfaceColor =  texture(gAlbedoMap, texCoord).xyz;
      vec3 gNormal =        texture(gNormalMap, texCoord).xyz;
    vec3 gSpecColor =   texture(gSpecularMap, texCoord).xyz;
    float gSpecPower =  texture(gSpecularMap, texCoord).a;

    vec3 totalLight = gSurfaceColor * 0.1; //TODO remove hardcoded ambient light
    vec3 viewDir = normalize(cameraPosition - gPosition);

    vec3 lightDir = normalize(pointLight.position - gPosition);
    vec3 diffuse = max(dot(gNormal, lightDir), 0.0f) * gSurfaceColor *
                    pointLight.base.intensities;

    vec3 halfWayDir = normalize(lightDir + viewDir);
    float spec = pow(max(dot(gNormal, halfWayDir), 0.0f), 1.0f);
    vec3 specular = pointLight.base.intensities * spec /** gSpecColor*/;

    float distance = length(pointLight.position - gPosition);
    float attenuation = 1.0f / (1.0f + pointLight.attenuation.linear * distance
                    + pointLight.attenuation.exponential * distance * distance +
                     pointLight.attenuation.constant);



    diffuse *= attenuation;
    specular *= attenuation;
    totalLight += diffuse + specular;

    fragmentColor = vec4(totalLight, 1.0f);
}

那么你有什么建议来处理这个问题呢?

编辑:这里有更多细节:

对于延迟着色,

  • 我填充了我的 GBuffer;
  • 我制作了一个环境光通道,在其中我用环境颜色渲染了一个全屏四边形:

    #版本 420 核心

    layout (std140) uniform Viewport
    {
        uniform mat4 Projection;
        uniform mat4 View;
        uniform mat4 ViewProjection;
        uniform vec2 scrResolution;
    };
    
    layout(binding = 1) uniform sampler2D gAlbedoMap;
    out vec4 fragmentColor;
    
    vec2 FetchTexCoord()
    {
          return gl_FragCoord.xy / scrResolution;
    }
    
    void main()
    {
        vec2 texCoord = FetchTexCoord();
        vec3 gSurfaceColor =    texture(gAlbedoMap, texCoord).xyz;
    
        vec3 totalLight = gSurfaceColor * 1.2; //TODO remove hardcoded ambient light
        fragmentColor = vec4(totalLight, 1.0f);
    }
    

然后我通过我的点灯(见上面的代码);

4

1 回答 1

1

您遇到此问题的原因是您使用的是“轻量级”(您在这个问题中没有完全清楚地说明这一事实,但在您的另一个问题中提出了这一事实)。

您正在使用正常的光衰减方程。好吧,你会注意到这个方程不会神奇地停在某个任意半径上。它是为从 0 到无穷大的所有距离定义的。

光量的目的是防止照明贡献超出一定距离。好吧,如果你的光衰减在那个距离没有变为零,那么你会在光体积的边缘看到不连续性。

如果要使用光体积,则需要使用实际上保证在体积边缘达到零的光衰减方程。否则,您应该为您的体积选择一个半径,以使光的衰减强度几乎为零。你的半径太小了。

继续扩大你的半径,直到你不能告诉它在那里。

于 2015-12-06T22:13:35.603 回答