多重采样和片段着色器

2023-12-28

多重采样似乎不适用于片段着色器生成的片段。 在下面的示例中,片段着色器用于生成棋盘程序纹理。 正方形的外边缘已正确抗锯齿,但程序纹理的内边缘却未正确抗锯齿。

片段着色器是否仅针对每个像素进行评估? 或者给定像素的每个片段的纹理坐标是否相同?

下面是代码和image https://i.stack.imgur.com/l1T6D.png显示其输出(请注意,程序边缘(白色和灰色方块之间)没有抗锯齿,而几何边缘(黑色和白色/灰色之间)是抗锯齿的):

#!/usr/bin/env python3
# -*- coding: utf-8 -*-


# imports ####################################################################

import sys

from OpenGL.GLUT import *
from OpenGL.GL import *


# display ####################################################################

def reshape(width, height):
    """window reshape callback."""
    glViewport(0, 0, width, height)

    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    r = float(min(width, height))
    w, h = 2*width/r, 2*height/r
    glOrtho(-w, w, -h, h, -1, 1)

    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()
    glRotate(45, 0, 0, 1)

def display():
    """window redisplay callback."""
    glClear(GL_COLOR_BUFFER_BIT)
    glBegin(GL_TRIANGLE_STRIP)
    for x in [-1, 1]:
        for y in [-1, 1]:
            glTexCoord(x, y)
            glVertex(x, y)
    glEnd()
    glutSwapBuffers()


# setup ######################################################################

glutInit(sys.argv)
glutInitDisplayString(b"rgba double samples=4")
glutInitWindowSize(100, 100)
glutCreateWindow(sys.argv[0].encode())

glutReshapeFunc(reshape)
glutDisplayFunc(display)

glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

shader = glCreateShader(GL_FRAGMENT_SHADER)
glShaderSource(shader, """
    void main() {
        vec2 c = gl_TexCoord[0].xy;
        vec4 color = gl_Color;
        if(c.x*c.y < 0.) color.a *= .5;
        gl_FragColor = color;
    }
""")
glCompileShader(shader)
program = glCreateProgram()
glAttachShader(program, shader)
glLinkProgram(program)
glUseProgram(program)

glutMainLoop()  

这就是MSAA(多重采样抗锯齿)的基本思想。仅执行片段着色器每个片段一次。然后使用样本掩码来控制将结果片段写入哪些样本。

假设您使用 4x MSAA,其中每个片段由 2x2 样本组成。如果三角形的边穿过片段,则仅将边内部的样本更新为新颜色。因此,如果片段仅部分位于三角形内,则可以更新 4 个样本中的 1、2 或 3 个。但样品are已更新全部更新为相同颜色。因此,片段着色器只需要评估一次。

这种方法的一大优点是非常高效。与不使用 MSAA 的渲染相比,它通常只会增加非常少量的开销。正如已经确定的,着色器执行的数量没有变化。渲染目标理论上会变大 4 倍,这可能会大幅增加内存使用量。但该内存通常可以被有效压缩,因此它并不像听起来那么糟糕。显然,在渲染帧的最后有一个下采样步骤,这确实增加了开销。

缺点是 MSAA 仅有助于平滑三角形边界和交叉点。如果三角形内有急剧的过渡,例如由于纹理内容或程序纹理,它根本没有帮助。 Mipmapping 可以减少纹理中的锯齿状边缘,而程序纹理可以通过考虑梯度来减少尖锐的过渡。但 MSAA 没有帮助。

如果您希望抗锯齿能够解决锐过渡造成的所有锯齿源问题,您可以全力以赴并使用超级采样。这意味着您可以以更高的分辨率渲染整个场景。例如,如果最终渲染目标的大小是w times h,您渲染到具有尺寸的表面2 * w times 2 * h,最后进行下采样。这是实质上更昂贵,因为您现在执行片段着色器的频率是原来的 4 倍,并且较大表面上的压缩也不会像 MSAA 表面上那样有效。

我没用过ARB_sample_shading 扩展 https://www.opengl.org/registry/specs/ARB/sample_shading.txt你发现了。但据我了解,它试图接近超级采样的视觉质量,同时至少保持 MSAA 的一些性能优势。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

多重采样和片段着色器 的相关文章

  • 在 QML 中控制纹理 3D 对象的不透明度

    我对 QML 中的 Qt 3D 有点陌生 我正在尝试控制 Qt 3D 的不透明度textured3D 对象 我正在使用简单qml3d https github com tripolskypetr simpleqml3d测试项目来做到这一点
  • OpenGL:VAO 和 VBO 对于大型多边形渲染任务是否实用?

    如果您想渲染一次在视锥体中包含数千个多边形的大型景观 并且用户的视点不断变化 那么使用 VAO 或 VBO 是否实用 我的意思是 每次玩家的位置或摄像机旋转发生变化时 您都必须重新计算顶点数据 以便正确剔除不再可见的任何顶点或场景 以保持良
  • Windows下使用GLEW使用OpenGL扩展

    我一直在 Windows 上使用 OpenGL 扩展痛苦的方式 https stackoverflow com questions 14413 using opengl extensions on windows GLEW 是更简单的方法吗
  • GLSL聚光投影体积

    在我的开源项目中 我使用 Qt3D 设置了延迟渲染管道 到目前为止一切顺利 但现在我想通过添加聚光灯投影量来继续前进 例如场景中好像有烟雾 像这样 我正在使用的片段着色器位于问题的末尾 我读过 对于每个片段 我应该从光位置进行光线行进并找到
  • 渲染缓冲区大于窗口大小 - OpenGL

    我正在尝试绘制大于屏幕尺寸 即 320x480 的渲染缓冲区 512x512 执行 glReadPixels 后 图像看起来是正确的 除非图像的尺寸超过了屏幕尺寸 在本例中 超过了水平 320 和垂直 480 是什么原因导致这种异常现象呢
  • 实例着色器矩阵的设置

    我想绘制实例立方体 我可以打电话GL DrawArraysInstanced PrimitiveType Triangles 0 36 2 成功地 我的问题是所有立方体都绘制在相同的位置和相同的旋转 我如何为每个立方体单独更改它 要创建不同
  • 如何在多采样纹理上渲染帧缓冲区对象?

    我目前有一个使用多个通道的渲染引擎 其中图像的各个部分在纹理上渲染 然后使用着色器进行组合 它有效 现在我想激活多重采样 我在这里读到 http www opengl org wiki Framebuffer Object Examples
  • Qt 5.5 QOpenGLWidget 链接错误未链接任何 openGL 调用

    我尝试使用 Qt 5 5 1 构建一个简单的 OpenGL 应用程序 一切都很好 直到我尝试使用 glClearColor 等 openGL 本机函数调用 该小部件实际上编译并产生黑屏 但在我尝试使用任何 openGL 本机函数后 它甚至不
  • 为什么 cudaGLSetGLDevice 失败,即使它是在 main 函数的第一行中调用的

    我想使用 OpenGL 和 CUDA 之间的互操作性 我知道 正如一些教程所说 第一步是选择设备 但是 当我在主函数的第一行中调用 cudaGLSetGLDevice 0 时 程序退出并显示信息 cudaSafeCall 运行时 API 错
  • 在着色器中旋转法线

    我有一个场景 其中有多个具有各自位置和旋转的模型 给定法线 着色器对每个像素应用简单的双向照明 那是我的顶点着色器 version 150 in vec3 position in vec3 normal in vec2 texcoord o
  • 带有 std::vector 的 VBO

    我用 C 和 OpenGL 编写了一个模型加载器 我用过std vectors 来存储我的顶点数据 但现在我想将其传递给glBufferData 但是数据类型却截然不同 我想知道是否有办法可以相互转换std vector至已记录的const
  • OpenSceneGraph 将相机设置在初始位置

    我是第一次使用 OpenSceneGraph 我有点迷失 因为文档确实不太清楚 所以 我有这段代码加载一个带有房子的 obj 文件 并且我在我想要的 人 所在的地方淹没了一个小盒子 所以现在 我不想把那个盒子放在那里 而是想把相机放在那里
  • Shader的功能参数表现

    我试图了解如何在着色器语言中实现传递参数 我读过几篇文章和文档 但仍然有一些疑问 特别是我试图理解与C 函数调用 特别强调性能 之间略有差异HLSL Cg and GLSL但我猜下划线的实现非常相似 到目前为止我所理解的 除非另有说明 函数
  • OpenGL 与 OpenCL,选择哪个以及为什么?

    哪些功能使 OpenCL 能够独特地选择 OpenGL 和 GLSL 进行计算 尽管有与图形相关的术语和不实用的数据类型 OpenGL 是否有任何真正的警告 例如 可以通过使用其他纹理将 a 渲染到纹理来完成并行函数评估 减少操作可以通过迭
  • 为贝塞尔曲线中的每个点绘制切线

    我设法绘制了一条贝塞尔曲线 如下所示 glColor3f 0 1 0 glBegin GL LINE STRIP for int i 3 i lt nPt i 3 glColor3f 0 0 0 for float k 0 k lt NLI
  • 如何在 OpenGL 中绘制镜像某些东西的镜子?

    根据我的理解 要在 OpenGL 中进行镜像 您基本上需要绘制场景 然后将所有内容翻转并再次绘制 只是使其通过镜子可见 从而在镜子中创建完美翻转的图像 但我看到的问题是 执行此操作时 唯一可以看到其他镜子的镜子是在前一个镜子之后渲染的镜子
  • 如何使用OpenGL数组纹理?

    我正在尝试在OpenGL中使用精灵表 通过数组纹理实现它这就是我加载纹理的方式 QImage image image load C QtProjects project images spritesheet png png const un
  • OpenGL 计算着色器调用

    我有一个与新计算着色器相关的问题 我目前正在研究粒子系统 我将所有粒子存储在着色器存储缓冲区中 以便在计算着色器中访问它们 然后我派遣一个一维工作组 define WORK GROUP SIZE 128 shaderManager gt u
  • OpenGL/GLSL - 纹理过滤的实现

    我想在 GLSL 着色器中自己实现纹理过滤 min 和 magfilter 因为我想使用 image load and store 而不是采样器 而且我想以特殊方式处理未定义的像素 并且我正在寻找一篇文章或者这样讨论过滤过程 我记得如何从我
  • 在OpenGL中,我可以在坐标(5, 5)处精确地绘制一个像素吗?

    我所说的 5 5 正是指第五行第五列 我发现使用屏幕坐标来绘制东西非常困难 OpenGL 中的所有坐标都是相对的 通常范围从 1 0 到 1 0 为什么阻止程序员使用屏幕坐标 窗口坐标如此严重 最简单的方法可能是通过以下方式设置投影以匹配渲

随机推荐

  • 权限被拒绝 - Sparklyr 中的 \tmp\hive

    我正在尝试使用将 R 数据帧复制到 Spark 2 0 1copy to功能但它说 HDFS 上的根暂存目录 tmp hive 应该是可写的 当前权限为 rw rw rw 我执行了执行程序更改权限 但我仍然得到相同的权限异常 HADOOP
  • Gradle - 如何排除 /src/test/java 上的 Findbug

    有没有办法排除 src test java 下的类上的 Findbugs 执行 我尝试了以下方法 但似乎不起作用 classes classes filter it path contains classes test org Sure 文
  • 如何将阿拉伯语设置为区域设置

    我正在研究文本到语音的转换 为此 我从网上找到了这个例子 在此他们将英语设置为setLanguage Locale US 所以 现在我尝试设置阿拉伯语而不是英语 但是当我将语言更改为阿拉伯语时 我失败了 任何人都可以帮我将语言更改为阿拉伯语
  • Rails:避免 Factory Girl 中的重复错误...我做错了吗?

    假设我有一个模型user 它有唯一性约束email field 如果我打电话Factory user 一旦一切顺利 但如果我第二次调用它 它将失败并出现 条目已存在 错误 我目前正在使用一个简单的帮助程序在创建工厂之前搜索数据库中的现有条目
  • 简单的 IIS URL 重写

    简单的问题 我需要将特定子域 URL 上的所有 http 80 和 https 443 请求重定向到备用 SSL 端口 https 444 例子 http sub corp com http sub corp com gt https su
  • SQL Server查询优化?

    我有以下查询 SELECT tl d FROM TrackerLocations AS tl inner join Trackers t on tl TrackerId t TrackerId inner join Devices d on
  • Webkit边框半径结合css3 translate3D出血

    我在基于 Webkit 的浏览器上遇到一个问题 如果我向 div 添加边框半径 然后将 moz translate3d 应用于内部的 ul 这是因为在原始示例中我使用的是 flexslider 幻灯片 边框radius 不适用并且会穿过容器
  • 在 _Layout.cshtml 中将 Layout 设置为 null

    您是否有理由希望在 Layout cshtml 中将 Layout 属性设置为 null 比如像这样 在渲染body view之前 section Layout null RenderBody section 对我来说这似乎很荒谬 删除行设
  • 扩展 Angular 2 ngModel 指令以使用可观察量

    角2ngModel指令适用于变量和函数 例如
  • 类型约束“XYZ”已创建

    我想用一个Moose Util TypeConstraints https metacpan org pod Moose Util TypeConstraints在我的应用程序中 所以我在我的main pl main pl use Moos
  • 使用Java锁定屏幕

    基本上我只需要创建一个应用程序 具有某种用户访问权限 其第一个屏幕是一个全屏窗口 如果不输入有效的用户名和密码 则无法最小化或关闭该窗口 类似于 Windows 屏幕保护程序 能做到吗 我应该查看哪些图书馆 这就是我所需要的 如果我的问题不
  • 将数值列表映射到颜色

    我有一个数值列表 如果需要的话我可以标准化这些值 我需要将此列表转换为颜色列表 在 HSL RGB 或任何其他颜色模型中 我可以稍后进行转换 对于任何给定值 颜色每次都必须相同 两个给定数值越不同 对应值的对比度就应该越大 所有使用的颜色必
  • JavaFX:控制器可以是抽象类吗?

    我已经研究这部分代码一天了 只是无法弄清楚为什么它总是生成错误 我有一个控制器和 FXML 他们工作得很好 然后我想到我想通过抽象 updateSelect 函数重用这个特定的控制器 因此 我将控制器更改为抽象 代码编译得很好 直到我尝试运
  • ARC 子类上的超级释放

    在 ARC 中我知道你不会打电话 super dealloc 在任何覆盖 dealloc 所以通常我会删除其中的观察者和计时器而不这样做 但是 如果我要对我制作的发布观察信息的视图进行子类化 dealloc不打电话 super deallo
  • 实体框架继承:按类型排序/分组?

    实体框架 以及我使用它的 RIA 服务 很好地支持继承 数据库映射可以是单表或多表 并且在第一种情况下 数据库表包括包含类型指示符的指示符列 显然 这个指示符在模型中是不可见的 尽管人们希望使用它来进行排序和分组 如果这是我想要做的 我是否
  • 强制 JFrame 在 setResizable(false) 之后不调整大小。命令不起作用

    我有一个简单的 Atari 突破程序 长话短说 我的一个功能是允许用户调整窗口大小几秒钟 然后再次使窗口不可调整大小 一切正常 窗口从不可调整大小 到可调整大小几秒钟 应该发生的情况是 几秒钟后 窗口应该停止接受用于调整窗口大小的输入 即
  • 使用 Google App Engine 在 Android 中推送通知

    我目前正在开发一个应用程序 用户可以在其中创建存储在服务器上的帖子 当另一个用户通过单击按钮对帖子表现出兴趣时 我想使用推送通知来通知帖子的作者 我已经使用 Google App Engine 的云端点设置了数据存储 无论如何 我可以使用这
  • Android 监听来自服务器套接字的消息

    我正在尝试创建一个通过套接字与本地服务器通信的 Android 应用程序 通信使用 JSON 以字符串形式传递简单的命令和数据 客户端应不断侦听来自服务器的传入消息 并在收到新数据时更新用户界面 所以我创建了一个网络服务 它是一个在后台运行
  • platform 和 api 这两个词到底是什么意思?

    我买了一本 学习java SE 6平台 的书 我想知道平台这个词的真正含义是什么 因为它不只是我可以使用的一堆类 Netbeans 中 Libraries 下的 JDK 1 6 节点 什么是API 这和平台不是一回事吗 但是库不是同样的意思
  • 多重采样和片段着色器

    多重采样似乎不适用于片段着色器生成的片段 在下面的示例中 片段着色器用于生成棋盘程序纹理 正方形的外边缘已正确抗锯齿 但程序纹理的内边缘却未正确抗锯齿 片段着色器是否仅针对每个像素进行评估 或者给定像素的每个片段的纹理坐标是否相同 下面是代