尝试渲染到多个纹理以实现延迟渲染。但所有纹理都是平等的

2023-11-29

所以我试图在opengl中实现延迟渲染。为此,我创建了一个 FBO,它渲染 3 个纹理(一个用于位置,一个用于正常,一个用于材质信息),但是由于我尚未完成,因此第三个纹理只是片段的最终颜色。最后一个深度缓冲区用于稍后实现阴影。

然后,该纹理被传递到另一个着色器(并使用默认的帧缓冲区),该着色器计算像素的最终颜色。然而,所有 3 个纹理都包含相同的信息,即几何通道着色器的第一个输出变量。

#version 330
//Fragment shader from the lighting pass
in vec2 vTexCoord;

uniform sampler2D uPosTexture;
uniform sampler2D uNormalTexture;
uniform sampler2D uColorTexture;

out vec4 fFragColor;

void main()
{
    //All of the following lines output the same image
    vec3 color = texture(uNormalTexture, vTexCoord).rgb;
    //vec3 color = texture(uPosTexture, vTexCoord).rgb;
    //vec3 color = texture(uColorTexture, vTexCoord).rgb;

    fFragColor = vec4(color,1);
}

所有 3 个都输出此图像:

All 3 output this image

这是我的几何片段着色器:

#version 330

in vec3 vECPos; // S.R. Vista
in vec3 vECNorm; // S.R. Vista
in vec4 vShadowCoord;

layout (location = 0) out vec3 fPosition;
layout (location = 1) out vec3 fNormal;
layout (location = 2) out vec4 fFragColor;

uniform sampler2DShadow uShadowMap;
uniform int uTipoFiltro;

struct LightInfo {
    vec4 lightPos; // Posición de la luz (S.R. de la vista)
    vec3 intensity;
};
uniform LightInfo uLight;
struct MaterialInfo {
    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
    float shininess;
};
uniform MaterialInfo uMaterial;


vec3 phongModelDiffAndSpec () 
{
    vec3 ldir = normalize(vec3(uLight.lightPos) - vECPos);
    vec3 view = normalize(vec3(-vECPos));
    vec3 r = reflect(-ldir,vECNorm);

    vec3 color = uLight.intensity * ( uMaterial.diffuse * max(dot(ldir,vECNorm), 0.0) +
                                  uMaterial.specular * pow(max(dot(r,view),0),uMaterial.shininess) );

    return clamp(color, 0.0, 1.0);
}


void main()
{

    vec3 ambient = uLight.intensity * uMaterial.ambient;
    vec3 diffAndSpec = phongModelDiffAndSpec();

    fPosition = vECPos;
    fNormal = normalize(vECNorm);
    fFragColor = vec4(ambient + diffAndSpec,1.0);
}

然而,似乎只完成了第一个输出变量,因为如果我更改它:

layout (location = 1) out vec3 fPosition;
layout (location = 2) out vec3 fNormal;
layout (location = 0) out vec4 fFragColor;

由此可见:

This shows

这是其他重要的功能

bool init()
{
    glClearColor(0.93f, 0.93f, 0.93f, 0.0f);

    glEnable(GL_DEPTH_TEST);
    //glDepthFunc(GL_LESS);
    //glClearDepth(1.0f);

    //glShadeModel(GL_SMOOTH);

    //Create shaders
    createShader(geometryPassShader, "geometry.vert", "geometry.frag");
    setUniformGeometry();
    createShader(lightPassShader, "lighting.vert", "lighting.frag");
    setUniformLighting();

    initFBO();
    passTexturesToStdFBO();

    //Init objects
    numVertTeapot = initTeapot(5, glm::mat4(1.0f));
    numVertSphere = initSphere(1.0f, 20, 30);
    numVertPlane = initPlane(10.0f, 10.0f, 2, 2);
    numVertTorus = initTorus(0.5f, 0.25f, 20, 40);
    initQuad();

    return true;
}

void initFBO()
{
    //Crear 1 FBO
    glGenFramebuffers(1, &gBuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, gBuffer);

    //Crear textura que guarda posicion
    glGenTextures(1, &gPositionTex);
    //glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, gPositionTex);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, g_Width, g_Height, 0, GL_RGB, GL_FLOAT, NULL);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    //Añadir la textura al FBO
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gPositionTex, 0);

    //Crear textura que guarda normal
    glGenTextures(1, &gNormalTex);
    //glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, gNormalTex);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, g_Width, g_Height, 0, GL_RGB, GL_FLOAT, NULL);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    //Añadir textura al FBO
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, gNormalTex, 0);

    //Crear textura que guarda informacion del material del "pixel"
    glGenTextures(1, &gMaterialTex);
    //glActiveTexture(GL_TEXTURE2);
    glBindTexture(GL_TEXTURE_2D, gMaterialTex);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, g_Width, g_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, gMaterialTex, 0);

    //Crear depth buffer
    glGenTextures(1, &depth_texture);
    glActiveTexture(GL_TEXTURE3);
    glBindTexture(GL_TEXTURE_2D, depth_texture);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, g_Width, g_Height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    //Indicamos que buffers (texturas) seran escritos con el output del fragment shader
    glDrawBuffers(3, attachments); //attachments[3] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 };

    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_texture, 0);


    GLenum result = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    if (result == GL_FRAMEBUFFER_COMPLETE)
        std::cout << "Frame buffer complete" << std::endl;
    else
        std::cout << "Frame buffer is not complete" << std::endl;

    glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

void display()
{

    //glClear of this FBO is done inside drawFBO()
    glUseProgram(geometryPassShader);
    drawFBO();
    glUseProgram(0);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glUseProgram(lightPassShader);
    //passTexturesToStdFBO();
    drawQuad();
    glUseProgram(0);

    glutSwapBuffers();
}

void drawFBO()
{
    glBindFramebuffer(GL_FRAMEBUFFER, gBuffer);
    glViewport(0, 0, g_Width, g_Height);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    drawScene();

    glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

void passTexturesToStdFBO()
{
    glBindBuffer(GL_FRAMEBUFFER, 0);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, gPositionTex);
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, gNormalTex);
    glActiveTexture(GL_TEXTURE2);
    glBindTexture(GL_TEXTURE_2D, gMaterialTex);
    glActiveTexture(GL_TEXTURE3);
    glBindTexture(GL_TEXTURE_2D, depth_texture);
}

void setUniformLighting()
{
    GLuint loc0 = glGetUniformLocation(lightPassShader, "uPosTexture");
    glUniform1i(loc0, 0);

    GLuint loc1 = glGetUniformLocation(lightPassShader, "uNormalTexture");
    glUniform1i(loc1, 1);

    GLuint loc2 = glGetUniformLocation(lightPassShader, "uColorTexture");
    glUniform1i(loc2, 2);
}

void setUniformLighting()
{
    GLuint loc0 = glGetUniformLocation(lightPassShader, "uPosTexture");
    glUniform1i(loc0, 0);

    GLuint loc1 = glGetUniformLocation(lightPassShader, "uNormalTexture");
    glUniform1i(loc1, 1);

    GLuint loc2 = glGetUniformLocation(lightPassShader, "uColorTexture");
    glUniform1i(loc2, 2);
}

glUniform作用于current程序,定义为glUseProgram。我看到一个明显的lack在调用之前调用此函数的次数setUniformLighting。因此,您需要执行以下操作之一:

  1. 有调用的代码setUniformLighting call glUseProgram(lightPassShader)预先。
  2. Have setUniformLighting本身在内部进行该调用。
  3. Use glProgramUniform,它作用于您指定的程序,而不是当前绑定的程序。请注意,此函数需要 GL 4.1/ARB_separate_shader_object。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

尝试渲染到多个纹理以实现延迟渲染。但所有纹理都是平等的 的相关文章

  • OpenGL 使用着色器将 NV12 转换为 RGB24

    我尝试编写一个应用程序来在 OpenGL 中显示 YUV 图像 我使用此代码片段在 C 中成功将 Y UV 转换为 RGB source https blog csdn net subfate article details 4730514
  • 在 OpenGL 中使用不同的着色器程序?

    我必须在 OpenGL 中针对不同的对象使用两个不同的着色器程序 我发现我必须使用glUseProgram 在不同的着色器程序之间切换 但对此没有太多信息 鉴于我有两个用于不同对象的不同着色器程序 如何为每个着色器程序生成和绑定 VAO 和
  • 使用 glGetFloatv 检索 pyglet 中的模型视图矩阵

    我正在使用 pyglet 在 python 中进行 3D 可视化 并且需要检索模型视图和投影矩阵来进行一些选择 我使用以下方式定义我的窗口 from pyglet gl import from pyglet window import wi
  • 渲染具有透明度的纹理时,OpenGL 不需要的像素

    我已经为这个问题苦苦挣扎了一段时间了 当我使用 OpenGL 渲染 2D 纹理 在无透明度和部分透明度之间的过渡上具有透明度值 时 我得到了一些烦人的灰色像素 我认为这是像素值插值的产物 关于如何改进这一点有什么想法吗 I m attach
  • GL_COLOR_ATTACHMENT 有什么作用?

    我现在正在学习帧缓冲区 但我只是不明白颜色附件的作用 我了解帧缓冲区 第二个参数的意义是什么 glFramebufferTexture2D GL FRAMEBUFFER GL COLOR ATTACHMENT0 GL TEXTURE 2D
  • OpenGL什么时候完成函数中指针的处理?

    OpenGL有多项功能 http www opengl org wiki GLAPI glTexSubImage2D直接获取指针 他们中有一些从这些指针读取数据 http www opengl org wiki GLAPI glBuffer
  • GLSL聚光投影体积

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

    GL ES 2 0 中的功能纹理2DLod在片段着色器中不可用 我需要移植 GLSL 着色器 在 GL ES 2 0 中我只能使用二维纹理 sampler2D 采样器 vec2 坐标 浮点数bias 告诉我如何计算 a 的值bias相当于已
  • 如何在OpenGL中像这样绘制连接的带状线

    我想用以下方式绘制一系列连接线 GL LINE STRIP 我尝试过自己编写代码 但没有得到想要的结果 所以我来到这里 帮助我找出我错在哪里 这里我只给出我的draw 函数 glBegin GL LINE STRIP glVertex2f
  • 无法在 QGLWidget 中设置所需的 OpenGL 版本

    我正在尝试在 Qt 4 8 2 中使用 QGLWidget 我注意到 QGLWidget 创建的默认上下文不显示 OpenGL 3 1 以上的任何输出 Qt wiki 有一个教程 http qt project org wiki How t
  • OpenSceneGraph 将相机设置在初始位置

    我是第一次使用 OpenSceneGraph 我有点迷失 因为文档确实不太清楚 所以 我有这段代码加载一个带有房子的 obj 文件 并且我在我想要的 人 所在的地方淹没了一个小盒子 所以现在 我不想把那个盒子放在那里 而是想把相机放在那里
  • 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
  • Retina 显示屏中具有 QOpenGLWIdget 的 Qt MainWindow 显示错误大小

    我有一个 Qt 应用程序MainWindow 我嵌入一个QOpenGLWidget在里面 一切正常 直到我开始使用 Apple Retina 显示屏并在高 DPI 模式下运行我的应用程序 我的QOpenGLWidget只是它应该具有的大小的
  • 无法在 Linux 的 NetBeans 中编译 C++ 和 OpenGL (GLFW) 的简单源代码

    我开始学习 OpenGL glfw 我从教程中复制源代码并尝试编译它 但出现了错误 我想我已经正确安装了所有头文件 glm glfw 等 这是我的来源 我没有在头文件中使用这些字符 include iostream include stdi
  • 使用 OpenGL 渲染 QImage

    与我相关的其他问题 https stackoverflow com questions 20126354 render qimage from sooffscreenrenderer in qglwidget 我认为更核心的问题是 如何渲染
  • nVidia 和 ATI 之间的 OpenGL 渲染差异

    最近 我将 ATI 驱动程序 我使用的是 HD7970 更新为最新版本 但我的 OpenGL 项目的一些对象停止工作 更重要的是 他们适用于 nVidia 最新驱动程序 在 960m 上测试 ATI 和 nVidia 渲染管道之间有什么我应
  • 新显卡上的 nvoglv32.dll 中的绘制调用崩溃

    几天前 由于一些硬件更改 我设置了计算机并安装了新的 Windows 8 副本 其中 我将显卡从 Radeon HD 7870 更改为 Nvidia GTX 660 再次设置 Visual Studio 11 后 我从 Github 下载了
  • OpenGL 计算着色器调用

    我有一个与新计算着色器相关的问题 我目前正在研究粒子系统 我将所有粒子存储在着色器存储缓冲区中 以便在计算着色器中访问它们 然后我派遣一个一维工作组 define WORK GROUP SIZE 128 shaderManager gt u
  • 允许使用 SurfaceTexture 在 GLSurfaceView 渲染器中进行多通道渲染

    我正在显示视频GLSurfaceView使用需要连续应用多个着色器的自定义渲染器 目前 它可以成功地使用一个着色器 但我不确定如何扩展渲染管道以连续应用多个着色器 我知道有一些关于应用多个着色器的示例 使用FrameBuffers and

随机推荐

  • jQuery Mobile Cordova (Phonegap) 在每个页面底部留下空白

    对于我的每个 jQm 页面 每个页面的底部似乎都有一些空白 并且它无缘无故地添加了滚动行为 我已附上屏幕截图 这种不必要的滚动行为给我带来了很多麻烦 我检查了firebug中的页面 似乎jQm正在添加 min height 213px 到页
  • 不带正则表达式的 String.replaceAll

    我想替换字符串中子字符串的所有实例 但是String replaceAll 只接受一个模式 我从上一场比赛中获得的字符串 是否可以将转义添加到我拥有的模式中 或者是否有一个版本replaceAll 在另一个接受文字字符串而不是模式的类中 只
  • Matlab uint8 稀疏

    在 Matlab 中创建稀疏矩阵时 您似乎可以创建一个填充逻辑数或双值数的稀疏矩阵 在阅读周围内容时 我了解到 Matlab 不支持其他类型的稀疏矩阵 即uint8或其他整数 在我的应用程序中我知道max values 16 而记忆是至关重
  • 如何让文字接触到div的底部

    我有一个包含较大文本元素的 HTML 页面 我希望文本与包含的 div 的底部对齐 以便它接触到 div 的底部 我尝试跟随 但文本和底部之间仍然有一些空格 有什么方法可以删除这个空格并使文本接触底部吗 Here是我尝试过的活生生的例子
  • 显示模式时出现“aria-hidden elements do not contains focusable elements”问题

    我在用着反应模态在我的应用程序中 当它打开时运行斧头辅助工具给出以下错误 aria 隐藏元素不包含可聚焦元素 这是因为 React 模态添加了一个aria hidden true 到应用程序的根元素 我的所有应用程序组件都在 div 下呈现
  • 如何使用 FFMPEG 分割视频,以便每个块都以关键帧开始?

    我们需要将大型实时 WMV 视频源分割成大小相同的小块 我们制作了一个脚本 可以很好地执行此操作 但有一点除外 视频块不以关键帧开始 因此在播放大多数视频块时 它们不会显示任何图像 直到原始视频中的关键帧最终出现为止 到达 有没有办法告诉
  • SQL Server 中的 guid 实际上是如何存储和排序/比较的?

    假设我有这个指南 2A87E3E2 2B6A 4149 9F5A 1B76092843D9 它实际上是否将其存储为数据库中的字母数字 我不这么认为 因为它必须适合 16 个字节 如果没有 那么它是如何存储的呢 我的猜测是十六进制数字 但我不
  • 如何修复ggplot中的纵横比?

    我正在尝试调整绘图的大小以适合我的文档 但我很难将绘制的图表变成正方形 Example pdf file out pdf width 5 height 5 p lt ggplot mydata aes x col1 y col2 print
  • Android TextView 停止换行

    我花了很多时间寻找解决方案 但没有找到任何与我所经历的类似的东西 当我在 G2 上运行我的应用程序时 我的文本视图都不会换行文本 无论视图有多大 如果我在模拟器上运行它 它们会适当地换行 当我的其他应用程序部署到我的 G2 时 似乎没有出现
  • AngularJS 表中的键盘导航

    我正在尝试将 Windows Delphi VCL 中制作的特殊表格 网格表单移植到 Angular 应用程序 可以在此处测试 Angular 应用程序的简化版本 jsFiddle 演示 用户可以添加任意数量的行 如 jsFiddle 中所
  • 使用递归辅助函数检查素数

    我正在尝试使用递归检查一个数字是否为素数 我被要求使用递归辅助函数 但我不确定应该如何实现它 我想我知道这个算法 但我从未尝试过在 Racket 中使用递归辅助函数 这是我目前的想法 看看 n 是否能被整除i 2 Set i i 1 If
  • 2D/3D CUDA 块如何划分为扭曲?

    如果我使用一个网格来启动我的内核 该网格的块具有尺寸 dim3 block dims 16 16 网格块现在如何分割成扭曲 这样一个块的前两行是否形成一个扭曲 或者前两列 或者这是任意排序的 假设 GPU 计算能力为 2 0 线程在块内按顺
  • 在 PHP 中使用 CURL 的 POST 给出无效请求错误

    我正在使用下面的使用curl的谷歌帐户发布方法 但它给了我invalid request错误 POST o oauth2 token HTTP 1 1 Host accounts google com Content Type applic
  • ES6 将一些函数导入为对象

    动作 js export const setX gt export const setY gt export const setT gt 一些组件 js import setX setY setT from actions export c
  • 触摸事件延迟

    我们在 AppStore 有一个应用程序半身像 A 幽灵我们有一个问题 当您点击屏幕时 我们使用 CALayer 来查找动画期间所有视图的位置 如果您点击其中一个 我们就会开始一个骰子序列 但是 存在明显的延迟 似乎触摸已被缓冲 并且我们收
  • Firestore限制

    Firestore 提供 50000 个文档读取操作作为其免费捆绑包的一部分 但是 在我的应用程序中 客户端正在获取包含价格数据的集合 价格数据是随着时间的推移而创建的 因此 从特定时间戳开始 客户端最多可以读取 1000 个文档 每个文档
  • 如何从 MVC 中的 Javascript 代码将值传递到控制器

    实际上我有一个这样的场景 我通过 Javascript 获取 GridView 中检查记录的值 现在我需要将这些值发送到控制器以删除这些记录
  • 从 UIDatePicker 中删除“今天”条目

    在 iOS SDK 中使用 UIDatePicker 时 当前日期始终有一个 今天 条目 这在大多数情况下很有用 但在我需要它的地方 它却相当令人困惑 有没有办法 a 禁用 今天 条目 改为使用常规日期 并且有所有条目看起来都一样 甚至更好
  • 以编程方式检查进程是否正在后台运行

    2个问题 1 是否有任何Linux Posix API可以知道进程是否已被调用为后台进程 linux gt myprogram 代码可以吗myprogram检测到它已被调用在后台运行 通过 2 是否有任何Linux Posix API可以使
  • 尝试渲染到多个纹理以实现延迟渲染。但所有纹理都是平等的

    所以我试图在opengl中实现延迟渲染 为此 我创建了一个 FBO 它渲染 3 个纹理 一个用于位置 一个用于正常 一个用于材质信息 但是由于我尚未完成 因此第三个纹理只是片段的最终颜色 最后一个深度缓冲区用于稍后实现阴影 然后 该纹理被传