全屏纹理采样的最佳方式

2024-01-19

在片段着色器中采样全屏纹理的最佳方法是什么,例如延迟渲染器中的 g 缓冲区,或后处理着色器中的场景纹理?

目前我使用以下两种方式:

  • 将屏幕尺寸作为统一值传递给着色器并计算 (u,v)gl_FragCoord:

    vec2 texCoord = gl_FragCoord.xy / vScreenSize;
    vec3 c = texture( tex, texCoord ).rgb;
    

    似乎并不理想,因为需要进行划分并且为着色器提供屏幕尺寸很麻烦。

  • Convert gl_FragCoord.xy进入一个ivec并使用texelFetch:

    vec3 c = texelFetch( tex, ivec2(gl_FragCoord.xy), 0 ).rgb;
    

    也不理想,因为转换自float to int是必须的。

那么有没有更好的办法呢?我真的只想在像素着色器绘制的确切位置对缓冲区进行采样。


// EDIT:


好的,根据来自顶点着色器的插值纹理坐标的建议,我设法找出以下代码:

顶点着色器:

#version 150

uniform mat4 im_ModelViewProjectionMatrix;

in vec3 iv_Vertex;
noperspective out vec2 vVertCoord;

void main( void )
{
    gl_Position = im_ModelViewProjectionMatrix * vec4(iv_Vertex, 1.0);
    vVertCoord = (gl_Position.xy / gl_Position.w) * (0.5) + vec2(0.5);
}

我基本上通过透视除法从剪辑空间位置计算归一化设备坐标 (NDC),然后将 NDC(范围从 [-1,1])映射到区间 [0,1]。这对于全屏四边形非常有用(即使没有透视划分,因为坐标非常简单)。不过,我需要在延迟渲染器中绘制为光几何的任意几何体存在一些问题。在顶点着色器中我输出vVertCoord作为红色 = x 和绿色 = y 的颜色:

#version 150

noperspective in vec2 vVertCoord;
out vec4 colorOut;

void main( void )
{
    colorOut = vec4(vVertCoord.x, vVertCoord.y, 0, 1);
}

这是当我在点光球内时的结果,一切看起来都很好(黑线是故意渲染的):

然而,如果我更接近光几何,结果就是:

左上角的那个红色补丁在那里做什么?您不希望在禁用调试颜色的情况下看到真实颜色的结果,因为它看起来像 lsd-trip,当您移动相机时,一切都会扭曲。这与精度有关吗?请注意,当我在像素着色器中使用 gl_FragCoord 时,一切都很好。


如果您只需从顶点着色器传入插值顶点坐标,则无需执行任何特殊的数学运算。

例如,如果您正在绘制一个覆盖屏幕的简单单位正方形,您可以然后接收全屏纹理,您可以执行如下操作:

vertex shader pseudocode:
layout(position = 0) in vec3 in_vertex;
out vec3 out_vertex;
void main()
{
    //Do your matrix multiplications to your in_vertex to get its final position...
    out_vertex = in_vertex;
}

然后,您的顶点着色器将正确地将 in_vertex 插值到 x:0...1、y:0...1 范围内(只要您正在绘制单位正方形)并将其传递给片段着色器。然后你的片段着色器将像这样使用它:

fragment shader pseudocode:
in vec3 out_vertex;
uniform sampler2D tex;
void main()
{
    gl_fragcolor = texture(tex,vec2(out_vertex.x,out_vertex.y));
}

不需要其他数学运算,只要注意 out_vertex 只在 0...1 的范围内即可。为了稍微扩展一下这个例子,想象一下我们的正方形:

(0,1)+-----------+(1,1) | | | | | | | | | | (0,0)+-----------+(0,1)

我们想在正中心采样这个点:

(0,1)+-----------+(1,1) | | | | | * | | | | | (0,0)+-----------+(0,1)

我们的顶点着色器将自动从其他 4 个位置插入该位置,并将以下 vec3 传递给片段着色器:

out_vertex = vec3(0.5,0.5,0);

然后可以用来成功采样纹理

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

全屏纹理采样的最佳方式 的相关文章

  • 如何用opengl制作2D地形?

    我想制作一个简单的二维地形 只有一些颠簸和高度变化 我想过只使用随机数来描述某个顶点的高度 但我不知道如何从中制作一个网格 我正在寻找一种方法来查找地形的顶点和索引缓冲区 我该怎么做呢 您可以仅将 GL POLYGON 与所有顶点的列表一起
  • CPU 到 GPU 法线映射

    我正在创建一个地形网格 然后这个答案 https stackoverflow com a 5284527 1356106我正在尝试将 CPU 计算法线迁移到基于着色器的版本 以便通过降低网格分辨率并使用在片段着色器中计算的法线贴图来提高性能
  • 三角形未在 OSX 上的 OpenGL 2.1 中绘制

    我正在学习有关使用 OpenGL 在 Java 中创建游戏引擎的教程 我正在尝试在屏幕上渲染一个三角形 一切运行良好 我可以更改背景颜色 但三角形不会显示 我还尝试运行作为教程系列的一部分提供的代码 但它仍然不起作用 教程链接 http b
  • glutPostRedisplay 不在循环内工作

    我试图让一个人在 y 轴上跳跃 所以我使用 2 秒的循环 第一秒它应该向下移动并弯曲膝盖 第二秒它应该向上移动 然后在起始位置完成 现在我刚刚开始让这个人在第一秒内跪下并弯曲膝盖 我还没有编写动画的其余部分 问题是 glutPostRedi
  • 为什么我的 FPS 相机一劳永逸地滚动?

    如果我忽略四元数代数的肮脏细节 我想我理解了旋转和平移变换背后的数学 但仍然不明白我做错了什么 为什么我的相机一劳永逸地滚动 更具体地说 我应该如何从相机的方向 旋转矩阵 计算相机视图矩阵 我正在用 Python 编写一个简约的 3d 引擎
  • 如何将点光源转换为卵形/椭圆形?

    我希望通过具有不同 x 和 y 值的 vec2 半径将当前的圆形光变成椭圆形 有没有办法根据我当前在片段着色器中的代码来做到这一点 uniform struct Light vec4 colour vec3 position vec2 ra
  • 使用未声明的标识符“gl_InstanceID”

    大家好 我一直在IOS平台上尝试在OpenGLES2 0中进行实例化绘制 我的渲染代码 glEnableVertexAttribArray glVertexAttribPointer glDrawElementsInstancedEXT G
  • 使用 OpenGL 着色器进行数学计算 (C++)

    我有一个矩阵 例如 100x100 尺寸 我需要对每个元素进行计算 matrix i j tt 8 5例如 我有一个巨大的矩阵 我想使用 OpenGL 着色器来实现该算法 我想使用着色器 例如 uniform float val unifo
  • SDL 鼠标位置调整大小后裁剪

    我在 SDL 中的鼠标位置上遇到了一些奇怪的行为 如果我将窗口大小调整得更大 则任一鼠标事件的 x y 位置似乎都限制为原始窗口的宽度和高度 如果我缺少一些函数调用来告诉 SDL 鼠标区域的大小已增加 应用程序的相关部分 void Resi
  • 使用 C# 截取任何外部应用程序的屏幕截图

    我们有一个 C WPF 应用程序 我们想要在其中截取我们启动的任意应用程序的屏幕截图 即 我们可以引用我们启动的进程 应用程序可能已最小化或位于其他窗口后面 但我们仍然只需要单个应用程序的图像 而不是重叠像素 我知道使用 BitBlt 或的
  • 当 OpenGL 中同时绑定 1D 和 2D 纹理时,正确的行为是什么?

    假设你有这样的东西 glBindTexture GL TEXTURE 2D my2dTex glBindTexture GL TEXTURE 1D my1dTex glBegin 正确的 OpenGL 行为是什么 要绘制一维纹理 二维纹理还
  • 在 GLUT 中使用鼠标滚轮

    我想在 OpenGL GLUT 程序中使用鼠标滚轮来放大和缩小场景 我怎么做 Freeglut 的 glutMouseWheelFunc 回调与版本相关 并且在 X 中不可靠 使用标准鼠标功能并测试按钮 3 和 4 OpenGlut 对 g
  • GL_CULL_FACE使所有对象消失

    我正在尝试在 openGL3 3 中创建一些简单的多边形 我有两种类型的对象 具有以下属性 对象 1 10 个顶点 按顺序在下面列出 存储在GL ARRAY BUFFER并使用GL TRIANGLE FAN v x y z w v 0 0
  • Glew+GLFW Win32 无依赖项 Visual Studio

    是否可以在不将文件复制到 C 的情况下构建并链接 Glew 和 GLFW 我找不到任何说明如何在不将 DLL 复制到 C 上的 Visual Studio 目录的情况下使用这些库的文档 我只想包含项目目录中所需的所有 dll 和 lib 文
  • 三角形纹理映射OpenGL

    我正在开发一个使用 Marching Cubes 算法并将数据更改为 3D 模型的项目 现在我想在 OpenGL 中为我的 3D 模型使用纹理映射 我首先尝试了一个简单的示例 它将图片映射到三角形上 这是我的代码 int DrawGLSce
  • 根据 GLSL 中向量的特定分量执行最小-最大的最快方法?

    我需要在我的 GLSL 代码中多次调用这种函数 vec2 minx vec2 a vec2 b if a x lt b x return a else return b 我担心过度分支 有没有办法避免 if else 结构 我建议使用 GL
  • 如何仅剪切剪切平面的交集(而不是并集)?

    在 OpenGL JOGL 中 当使用多个剪切平面时 似乎会应用所有剪切平面的并集 我想要的是路口要应用的所有剪裁平面 这可能吗 请参阅下面的简化二维示例 Edit An example of clipping by vertex shad
  • 使用 JOGL 和 Android OpenGL 编写可移植 Java 应用程序

    我计划编写一款可以在 PC 和 Android 上运行的 Java 3D 游戏 不幸的是 这两个平台似乎没有通用的 OpenGL API API 是否有显着差异 有没有办法在两个版本中使用相同的 3D 代码 这是不是一个好主意 Androi
  • 即使手动设置显示环境变量后,WSL Ubuntu 也会显示“错误:无法打开显示”

    我在 WSL Ubuntu 上使用 g 我使用 git 克隆了 GLFW 存储库 使用了ccmake命令配置并生成二进制文件 然后使用make在 build 目录中最终创建 a文件 我安装了所有OpenGL相关的库 usr ld 我不记得我
  • 更改 GLUT 调用以与 MFC/C++ 一起使用

    我有一个使用 GLUT 进行 OpenGL 渲染的程序 现在我需要它位于 MFC 项目内部 以便它可以与另一个程序组件一起使用 我已经按照这个教程进行操作 http www codeguru com cpp g m opengl openf

随机推荐

  • 在 Canvas Fabric JS 元素上添加删除按钮

    您好 我想使用 FabricJS 在元素中添加删除按钮 我有一个例子 我尝试添加这部分代码 但是当我调整图像大小时 删除按钮不会保留在原位 http jsfiddle net wxao1on8 13 http jsfiddle net wx
  • 如何通过 Google Cloud 调试在 Docker 容器内运行的 Nodejs 应用程序

    我发现谷歌提供了一些指导方针如何在自定义运行环境上运行 Nodejs https cloud google com solutions nodejs 一切看起来都很好 我正在设法在本地计算机上启动我的 Nodejs 应用程序gcloud p
  • ActiveMQ 警告:帧大小为 1 GB,大于允许的最大大小 100 MB

    我正在尝试从旧版 jms 代理切换到 ActiveMQ 我无法弄清楚的一件事是日志中的警告每小时一次 WARN Transport Connection to tcp 127 0 0 1 38542 failed java io IOExc
  • 如何在使用 pytest-repeat 时动态捕获测试内部的迭代次数

    我使用 pytest repeat 多次执行我的 selenium 脚本 我需要在执行过程中捕获迭代次数并利用它 我探索了 pytest mark pytest collect 和 pytest Collector class Teston
  • 在Python中向上移动一个目录

    有没有一种简单的方法可以使用一行代码在 python 中上移一个目录 类似的东西cd 在命令行中 gt gt gt import os gt gt gt print os path abspath os curdir C Python27
  • 运行 play 框架时不支持 Major.minor 版本 51.0

    我知道存在版本冲突 只是希望有人告诉我如何解决它 在之前的 stackoverflow 帖子中 没有人告诉我们解决方案 版本 Ubuntu 12 04 1 LTS java 1 6 0 24 OpenJDK javac 1 7 0 07 O
  • R 中用于大型复杂调查数据集的方法?

    我不是调查方法学家或人口统计学家 但我是 Thomas Lumley 的 R 调查包的狂热粉丝 我一直在处理一个相对较大的复杂调查数据集 即医疗保健成本和利用项目 HCUP 国家急诊室样本 NEDS https www hcup us ah
  • Gboard 贴纸搜索未返回结果

    通过应用程序索引 我将贴纸包添加到 GBoard 但 GBoard 搜索无法按关键字找到我的贴纸 new Indexable Builder Sticker setName Bye setImage http www snoopystick
  • 如何在 Swift 中获取前置摄像头?

    我正在尝试让前置摄像头具有实时取景功能 我可以使用以下方式获取后置摄像头 var backCamera AVCaptureDevice defaultDeviceWithMediaType AVMediaTypeVideo 但我似乎找不到如
  • Stripe 在特定日期取消订阅

    我在用着条纹API https stripe com docs api在 PHP 中 我不知道如何在特定日期停止客户订阅 我知道有一个立即取消订阅的选项 subscription Stripe Subscription retrieve s
  • 使用 Lucene Search 一次搜索多个索引

    我正在使用 Zend Search Lucene 来实现站点搜索 我为不同的数据类型创建了单独的索引 例如 一个用于用户 一个用于帖子等 结果类似地按数据类型划分 但有一个 全部 选项应显示不同结果类型的组合 是否可以同时搜索不同的索引 或
  • 如何在 C# 中引用另一个项目?

    我在我的解决方案中添加了一个项目 Project2 它已经有另一个项目 比如说项目 1 我如何将项目 2 中的类和方法调用到项目 1 中 我做了什么 我有项目 1 及其解决方案 我将项目 2 添加到项目 1 的解决方案中 项目 1 和项目
  • Java 8 DateTimeFormatters 常量在哪里定义?

    我正在看DateTimeFormatter https docs oracle com javase 8 docs api java time format DateTimeFormatter html类 我想知道常量在哪里 M EEE a
  • 包含或异或有什么区别?

    我一直在研究一些业务流程执行语言 BPEL 和相关的建模系统 BPMN 其中设计人员需要了解流程流的包容性和排他性网关 非常感谢您的帮助 假设适用相同的规则 对术语的一般解释就足够了 这是我试图理解的一些技术文本对马克的回应 对于连接两个活
  • 是否在数据库级别或服务器/实例级别启用了“CLR 集成”?

    我试图了解启用 CLR 是否在数据库级别或服务器级别 实例级别启用它 在线书籍根本不清楚 如果我使用此命令启用 CLR 会发生什么 它会在所有服务器上启用吗 sp configure clr enabled 1 GO RECONFIGURE
  • “结合更牢固”这句话是什么意思?

    我知道这可能是一个新手问题 但我试图理解这句话 来自一篇关于使用 EBNF 的元语言的论文 Logical and binds stronger than logical or 在此之前它说 Conditions are condition
  • 无法从 master 连接到 kubernetes pod:i/o 超时

    我配置了 1 个主节点和一个节点的 kubernetes 集群 运行主节点和节点的机器不在同一网络中 对于网络 我安装了 calico 并且所有 pod 都在运行 为了测试我使用的集群获取外壳示例 https kubernetes io d
  • 用 Java 写入文件

    我对 Java 很陌生 由于某种原因我无法写入文件 我的代码如下所示 FileWriter fstream try fstream new FileWriter fileLocation BufferedWriter out new Buf
  • 如何定期更新 Label 控件的值?

    我试图让标签显示一些文本 然后在一段时间后刷新自身并能够稍后重新显示其他内容 但目前我不知道如何使标签暂停 如果可能的话 到目前为止我的代码 foreach var x in mod labelWARNING Visible true la
  • 全屏纹理采样的最佳方式

    在片段着色器中采样全屏纹理的最佳方法是什么 例如延迟渲染器中的 g 缓冲区 或后处理着色器中的场景纹理 目前我使用以下两种方式 将屏幕尺寸作为统一值传递给着色器并计算 u v gl FragCoord vec2 texCoord gl Fr