首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何确保三角形边上存在屏幕空间导数?

如何确保三角形边上存在屏幕空间导数?
EN

Stack Overflow用户
提问于 2022-09-30 02:57:09
回答 1查看 69关注 0票数 3

我画了一个反锯齿状四边形作为地面平面,供模型坐在顶部使用以下顶点着色器:

代码语言:javascript
复制
#version 330
out vec2 tex;
uniform mat4 mvp;

const vec2 pos[4] = vec2[](
    vec2(-1.0, 1.0),
    vec2(1.0, 1.0),
    vec2(1.0, -1.0),
    vec2(-1.0, -1.0));

void main()
{
    tex = pos[gl_VertexID];
    /* setup camera */
    gl_Position = mvp * vec4(pos[gl_VertexID], 0.0, 1.0);
}

和以下片段着色器:

代码语言:javascript
复制
#version 330
in vec2 tex;
out vec4 Out_Color;

float roundedBoxSDF(vec2 uv, float Size, float Radius)
{
    return length(max(abs(uv) - Size + Radius, 0.0)) - Radius;
}

void main()
{
    /* 95% to make sure there is a screen space derivative present to
    calculate against. */
    float dist = roundedBoxSDF(tex, 0.95, 0.5);
    float smoothedAlpha = dist / length(vec2(dFdx(dist), dFdy(dist)));

    Out_Color = vec4(vec3(1, 1, 1), 1.0 - smoothedAlpha);
}

如果我把纹理坐标直接画到四边形的边缘,沿四边形边的非圆边总是别名,因为有符号距离场没有屏幕空间导数来计算距离1远离原点的边。

似乎是一个简单的修复:就像上面的片段着色器一样,我只是将纹理坐标缩小到95% roundedBoxSDF(tex, 0.95, 0.5);,所以有一个没有边缘的四边形来收集屏幕空间导数。很好地防止了.

...until,我放大,远出或以斜角度观看。然后,5%的保证金是不够的,我再次得到混叠,因为屏幕空间上没有像素存在,以获得上述导数。

我怎么解释这种事?继续缩小纹理坐标和增长顶点作为距离的一个函数与相机?还有什么比这更聪明的吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-09-30 08:15:58

问题不在于衍生品--与你所相信的相反,它们在边缘上有很好的定义。也不是缺少各向异性滤波,因为它也发生在非斜角度。

就像你自己说的,问题是,从某些角度来说,缩小0.95是不够的。这是因为你的形状的分析边缘与四边的距离小于一个像素。在这种情况下,不需要一个不透明像素的情况下,就没有任何像素光栅化了:

如果你走收缩路线,你的收缩量取决于衍生产品--你需要在屏幕空间上缩小一个像素。一个等价但更简单的方法是计算SDF在您的非收缩箱的内部,然后设置out_Color.a = -smoothedAlpha

在任何一种情况下,收缩都是解决问题的一种相当麻烦的方法,因为它会改变形状的有效大小。

更正确的方法是用像素来扩展网格化的三角形。有一个NVidia扩展就是这样做的:扩容。在未扩展的OpenGL中,您可以使用几何着色器获得类似的结果。在这两种情况下,膨胀的三角形将操作,这需要额外的措施,如果你的形状将是部分透明。

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

https://stackoverflow.com/questions/73903568

复制
相关文章

相似问题

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