首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >递延MSAA工件

递延MSAA工件
EN

Stack Overflow用户
提问于 2018-03-02 06:30:40
回答 1查看 389关注 0票数 4

这就是我渲染场景的过程:

  • 绑定MSAA x4 GBuffer (4种颜色附件、位置、正常颜色、颜色和未亮颜色(仅限天空盒)。我也有一个深度组件/纹理)。
  • 绘制SkyBox
  • 绘制地质图
  • 将所有颜色和深度组件混合到单个样本FBO中
  • 应用照明(我使用深度纹理来检查它是否应该被点燃,检查深度纹理值是否小于1)。
  • 渲染四

这就是正在发生的事情:

正如你所看到的,我把这些白色和黑色的工艺品围绕在边缘,而不是光滑的边缘。(值得注意的是,如果我删除照明,只是渲染纹理没有照明,我没有得到这个和它平滑的正确)。

这是我的着色器(它已经实现了SSAO,但这似乎不会影响到这一点)。

代码语言:javascript
复制
#version 410 core
in vec2 Texcoord;
out vec4 outColor;
uniform sampler2D texFramebuffer;
uniform sampler2D ssaoTex;

uniform sampler2D gPosition;
uniform sampler2D gNormal;
uniform sampler2D gAlbedo;
uniform sampler2D gAlbedoUnlit;
uniform sampler2D gDepth;

uniform mat4 View;
struct Light {
    vec3 Pos;
    vec3 Color;
    float Linear;
    float Quadratic;
    float Radius;
 };

 const int MAX_LIGHTS = 32;
 uniform Light lights[MAX_LIGHTS];
 uniform vec3 viewPos;

 uniform bool SSAO;

 void main()
 {
    vec3 color = texture(gAlbedo, Texcoord).rgb;
    vec3 colorUnlit = texture(gAlbedoUnlit, Texcoord).rgb;
    vec3 pos = texture(gPosition, Texcoord).rgb;
    vec3 norm = normalize(texture( gNormal, Texcoord)).rgb;
    vec3 depth = texture(gDepth, Texcoord).rgb;
    float ssaoValue = texture(ssaoTex, Texcoord).r;

    // then calculate lighting as usual
    vec3 lighting;
    if(SSAO)
    {
        lighting = vec3(0.3 * color.rgb * ssaoValue); // hard-coded ambient component
    }
    else
    {
        lighting = vec3(0.3 * color.rgb); // hard-coded ambient component
    }
    vec3 posWorld = pos.rgb;

    vec3 viewDir = normalize(viewPos - posWorld);

    for(int i = 0; i < MAX_LIGHTS; ++i)
    {

        vec4 lightPos = View * vec4(lights[i].Pos,1.0);
        vec3 normLight = normalize(lightPos.xyz);
        float distance = length(lightPos.xyz - posWorld);
        if(distance < lights[i].Radius)
        {
            // diffuse
            vec3 lightDir = normalize(lightPos.xyz - posWorld);
            vec3 diffuse = max(dot(norm.rgb, lightDir), 0.0) * color.rgb * 
lights[i].Color;

        float attenuation = 1.0 / (1.0 + lights[i].Linear * distance + lights[i].Quadratic * distance * distance);
        lighting += (diffuse*attenuation);
        }
    }

    if(depth.r >= 1)
    {
        outColor = vec4(colorUnlit, 1.0);
    }
    else
    {
        outColor = vec4(lighting, 1.0);
    }

}

因此,最后一个if语句检查它是否在深度纹理中,如果它是应用光照,如果不是,则只绘制天框(这样就不会将光线应用到天空框中)。

我花了几天时间试图解决这个问题,通过比较法线、位置和深度,改变检查是否应该是轻量级的方法,将格式改为更高的分辨率(例如使用RGB16F而不是RGB8等)。但我不知道是什么原因造成的,每个样本做照明(使用texel提取)将是一种密集的方式。

有什么想法吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-11-12 21:18:21

这个问题现在有点老了,但我想我应该说我是如何解决问题的。

我运行基本Sobel过滤器在我的着色器,我用来做屏幕空间轮廓,但除此之外,我还检查是否启用了MSAA,如果是,如果是计算每个纹理周围的边缘像素照明!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49063871

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档