编辑:我仍在寻找有关使用OpenCL或计算着色器的一些帮助.我更喜欢继续使用OGL 3.3并且不必处理对OGL 4.3和OpenCL 1.2的坏驱动程序支持,但我无论如何都不能想到这种类型的着色而不使用其中一个(用于匹配灯和砖).是否可以在不使用GPGPU的情况下实现基于区块的剔除?
我在OpenGL 3.3中编写了一个延迟渲染.现在我没有对光通道进行任何剔除(我只为每个灯光渲染一个全屏四边形).这(显然)有很多透支.(有时它是~100%).因此,我一直在研究在光通过期间提高性能的方法.似乎(几乎)每个人的意见中最好的方法是使用屏幕空间图块来剔除场景.这是Frostbite 2中使用的方法.我在SIGGRAPH 2010期间阅读了Andrew Lauritzen的演示文稿(http://download-software.intel.com/sites/default/files/m/d/4/1/d/8 /lauritzen_deferred_shading_siggraph_2010.pdf),我不确定我是否完全理解这个概念.(为此,为什么它比其他任何东西都好,如果它对我更好)
在演示中,Laurtizen通过轻量,四边形和瓷砖进行延迟着色,以剔除场景.根据他的数据,基于区块的延迟渲染器是最快的(到目前为止).我不明白为什么会这样.我猜这与事实有关,即每个瓷砖都将所有灯光一起分批.在演示文稿中,它说要读取G-Buffer一次然后计算光照,但这对我来说没有意义.在我看来,我会这样实现:
for each tile {
for each light effecting the tile {
render quad (the tile) and compute lighting
blend with previous tiles (GL_ONE, GL_ONE)
}
}
Run Code Online (Sandbox Code Playgroud)
这仍然需要对G-Buffer进行大量采样.我认为这样做会产生与为每个灯光渲染四边形屏幕相同(如果不是更差)的性能.从它的措辞来看,似乎这就是发生的事情:
for each tile {
render quad (the tile) and compute all lights
}
Run Code Online (Sandbox Code Playgroud)
但我没有看到如何在不超过某些GPU上片段着色器的指令限制的情况下执行此操作.谁能帮我这个?看起来几乎每个基于tile的延迟渲染器都使用计算着色器或OpenCL(批量灯),为什么会这样,如果我没有使用它们会发生什么?
我正在尝试从延迟渲染器中的深度值重建3D世界坐标,但我有一点时间.我在网上找到的大多数例子都假设了标准的透视转换,但我不想做出这样的假设.
在我的几何传递顶点着色器中,我使用以下方法计算gl_Position:
gl_Position = wvpMatrix * vec4(vertexLocation, 1.0f);
Run Code Online (Sandbox Code Playgroud)
在我的照明传递片段着色器中,我尝试使用以下方法获取世界坐标:
vec3 decodeLocation()
{
vec4 clipSpaceLocation;
clipSpaceLocation.xy = texcoord * 2.0f - 1.0f;
clipSpaceLocation.z = texture(depthSampler, texcoord).r;
clipSpaceLocation.w = 1.0f;
vec4 homogenousLocation = viewProjectionInverseMatrix * clipSpaceLocation;
return homogenousLocation.xyz / homogenousLocation.w;
}
Run Code Online (Sandbox Code Playgroud)
我以为我做对了,事实上,相机附近的物体似乎正确点亮了.但是我最近意识到,当我向远处移动时,物体被照亮,好像它们离相机更远,而不是它们实际上.我玩过我的灯光通道并验证我的世界坐标是唯一被误算的东西.
我不禁想到我的clipSpaceLocation.z和clipSpaceLocation.w是问题的根源,但我已经尝试了我能想到的每个变化来计算它们,上面的代码得到了最正确的结果.
任何想法或建议?
在将当前的延迟渲染器更改为使用对数深度缓冲区后,我无法解决,对于我的生活,如何从深度缓冲区值重建世界空间深度.
当我编写OpenGL默认z/w深度时,我可以通过从窗口空间转换到NDC空间来轻松计算此值,然后执行逆透视变换.
我在第二遍片段着色器中完成了所有这些操作:
uniform sampler2D depth_tex;
uniform mat4 inv_view_proj_mat;
in vec2 uv_f;
vec3 reconstruct_pos(){
float z = texture(depth_tex, uv_f).r;
vec4 pos = vec4(uv_f, z, 1.0) * 2.0 - 1.0;
pos = inv_view_proj_mat * pos;
return pos.xyz / pos.w;
}
Run Code Online (Sandbox Code Playgroud)
并得到一个看起来非常正确的结果:
但现在通往简单z价值的道路并不那么容易(似乎也不应该这么难).
我的第一次传递的顶点着色器具有日志深度:
#version 330 core
#extension GL_ARB_shading_language_420pack : require
layout(location = 0) in vec3 pos;
layout(location = 1) in vec2 uv;
uniform mat4 mvp_mat;
uniform float FC;
out vec2 uv_f;
out float logz_f;
out float FC_2_f; …Run Code Online (Sandbox Code Playgroud) 我是WebGL的菜鸟。我读过几篇有关ND缓冲区和G缓冲区的文章,好像它是WebGL开发的战略选择。
ND缓冲区和G缓冲区与渲染管线有何关系?ND缓冲区仅用于正向渲染,G缓冲区仅用于延迟渲染吗?
一个JavaScript代码示例如何实现这两者将对我理解区别很有用。
尝试在延迟着色之上实现抗锯齿,我尝试使用多重采样渲染缓冲区,然后使用缓冲区位块传输传递解析样本。
按照延迟着色的传统做法,我使用发出 3 个颜色输出的专用着色器来渲染场景:
然后将它们用于照明计算通道,从而产生最终的场景纹理
使用简单的着色器将场景纹理渲染到全屏四边形的屏幕上
正如您可能猜到的,渲染到屏幕时,屏幕上的 MSAA 不会应用于场景纹理的内容:为了实现抗锯齿,我因此选择在步骤 1) 中使用多重采样渲染缓冲区,并引入了额外的步骤1.1) 分辨率。当然,多重采样仅对彩色图是必要的/有用的,对其他两张图来说不是必需的/有用的。
我的问题是,显然,具有多个渲染缓冲区/颜色附件的帧缓冲区只能为相同类型的附件定义;这意味着如果一个附件经过多次采样,那么所有其他附件也必须经过多次采样。
这成为分辨率期间位置和法线缓冲区的一个问题,因为几何体和照明会因抗锯齿而受到影响。
// Create the frame buffer for deferred shading: 3 color attachments and a depth buffer
glGenFramebuffers(1, &gBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, gBuffer);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
{
// - Position color buffer
glGenRenderbuffers(1, &gPosition);
glBindRenderbuffer(GL_RENDERBUFFER, gPosition);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 8, GL_RGBA16F, w, h);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, gPosition);
// - Normal color buffer
glGenRenderbuffers(1, &gNormal);
glBindRenderbuffer(GL_RENDERBUFFER, gNormal);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 8, GL_RGBA16F, w, h);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, gNormal);
// …Run Code Online (Sandbox Code Playgroud) opengl multisampling framebuffer deferred-rendering deferred-shading
我想用GLSL,Java和openGl开始一个延迟着色项目
1.延迟渲染管道如何工作,是否为每个图像渲染场景?例如,当我想创建一个镜面反射,模糊和阴影纹理时,是否需要为每个纹理渲染场景.
我见过一些代码片段,那里没有多个渲染循环.
2.什么是几何缓冲区,它有什么作用?它是否类似于场景数据的存储,我可以绘制到纹理而不再渲染?
我正在尝试将模板缓冲区放入纹理中以便在延迟渲染器中使用.
我正在使用其他颜色和深度附件,glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[color1], 0);结果是正确的.

但是,当我尝试将模板缓冲区附加到纹理时,
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT ,GL_TEXTURE_2D, textures[stencil], 0);我得到一个乱码的结果,好像FBO没有清除它的缓冲区.

我不知道问题是什么.我怀疑这是设置模板纹理的问题......
//Stencil Texture Initialization
glBindTexture(GL_TEXTURE_2D, textures[stencil]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D( GL_TEXTURE_2D, 0, GL_STENCIL_INDEX8, 512, 512, 0, GL_STENCIL_INDEX, GL_BYTE, 0);
Run Code Online (Sandbox Code Playgroud)
我的设置中没有任何错误代码,所以我不知道问题是什么.
编辑:也许我没有正确地这样做.如果有人知道如何将模板缓冲区写入纹理,我真的不在乎我是否写了不同的鳕鱼.我只需要一种有效的方法.
所以,我一直在读这个,我还没有得出结论.一些例子使用纹理作为渲染目标,有些人使用渲染缓冲区,有些人同时使用它们!
例如,仅使用纹理:
// Create the gbuffer textures
glGenTextures(ARRAY_SIZE_IN_ELEMENTS(m_textures), m_textures);
glGenTextures(1, &m_depthTexture);
for (unsigned int i = 0 ; i < ARRAY_SIZE_IN_ELEMENTS(m_textures) ; i++) {
glBindTexture(GL_TEXTURE_2D, m_textures[i]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, WindowWidth, WindowHeight, 0, GL_RGB, GL_FLOAT, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, m_textures[i], 0);
}
Run Code Online (Sandbox Code Playgroud)
都:
glGenRenderbuffersEXT ( 1, &m_diffuseRT );
glBindRenderbufferEXT ( GL_RENDERBUFFER_EXT, m_diffuseRT );
glRenderbufferStorageEXT ( GL_RENDERBUFFER_EXT, GL_RGBA, m_width, m_height );
glFramebufferRenderbufferEXT ( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_diffuseRT );
glGenTextures ( 1, &m_diffuseTexture );
glBindTexture ( GL_TEXTURE_2D, m_diffuseTexture );
glTexImage2D ( …Run Code Online (Sandbox Code Playgroud) 我正在尝试实现阴影贴图技术,但在使其发挥作用时遇到一些问题。
我在灯光位置有一个相机,这是我得到的阴影贴图。所有顶点均已乘以每个modelViewProjectionMatrix。

我还有一个带有顶点世界位置的纹理。它是一个GL_RGBA32F纹理,因为所有点都已被每个点相乘ModelMatrix以获得世界空间中的点。

和着色器:
layout(binding=5) uniform sampler2D shadowMap;
layout(binding=6) uniform sampler2D positionMap;
in vec2 texcoord;
uniform mat uViewProjectionMatrix;
out vec4 color;
void main() {
vec4 pos = texture(positionMap, texcoord);
vec4 ShadowCoord = uViewProjectionMatrix * pos;
ShadowCoord.xy = ShadowCoord.xy * vec2(0.5,0.5) + vec2(0.5,0.5);
float a = texture(shadowMap, ShadowCoord.xy).z;
color = vec4(a, a, a, 1.0);
}
Run Code Online (Sandbox Code Playgroud)
输出(相机几乎处于光线的相同位置):

我只是想看看每个顶点的投影是否与相机的位置垂直,但看起来并非如此。所有这一切的目的是比较:
if ( texture(shadowMap, ShadowCoord.xy).z < ( ShadowCoord.z-bias ) )
Run Code Online (Sandbox Code Playgroud)
但它也不起作用。
我将不胜感激任何帮助。谢谢。
opengl ×8
glsl ×3
culling ×1
depth-buffer ×1
framebuffer ×1
java ×1
javascript ×1
lighting ×1
macos ×1
textures ×1
webgl ×1
webgl2 ×1