gpt4 book ai didi

c# - OpenGL - 单 channel 立方体贴图不产生任何输出

转载 作者:行者123 更新时间:2023-11-30 23:19:32 32 4
gpt4 key购买 nike

enter image description here

我编写了一个粗略的阴影映射实现,它使用 6 个不同的 View 矩阵渲染场景 6 次以创建立方体贴图。

作为优化,我正在尝试使用几何着色器升级到单 channel 方法,但很难从我的着色器获得任何输出。

我的问题始于绑定(bind)立方体贴图纹理。对于多 channel ,我一次只绑定(bind) 6 个 FBO 中的 1 个,但是对于单 channel ,我需要一次绑定(bind)所有 6 个立方体贴图面,但我没有这个句柄。在这些情况下,文档建议使用包含所有 6 个面孔的 FrameBufferTexture 创建一个 FBO。我这样做正确吗?

或者,问题可能出在几何着色器中,但由于我没有得到任何输出,因此很难在那里进行调试。

SINGLE PASS(无输出)

创建Fbo

// Create the FBO
GL.GenFramebuffers(1, out FBO_handle);

// Create and bind the cubemap Texture
GL.GenTextures(1, out cubeMapTexture);
GL.BindTexture(TextureTarget.TextureCubeMap, cubeMapTexture);

// Generate each of the single cubemap faces as 2D texture
GL.TexImage2D(TextureTarget.TextureCubeMapPositiveX, 0, PixelInternalFormat.R16f, size, size, 0, PixelFormat.Red, PixelType.Float, IntPtr.Zero);
GL.TexImage2D(TextureTarget.TextureCubeMapNegativeX, 0, PixelInternalFormat.R16f, size, size, 0, PixelFormat.Red, PixelType.Float, IntPtr.Zero);
GL.TexImage2D(TextureTarget.TextureCubeMapPositiveY, 0, PixelInternalFormat.R16f, size, size, 0, PixelFormat.Red, PixelType.Float, IntPtr.Zero);
GL.TexImage2D(TextureTarget.TextureCubeMapNegativeY, 0, PixelInternalFormat.R16f, size, size, 0, PixelFormat.Red, PixelType.Float, IntPtr.Zero);
GL.TexImage2D(TextureTarget.TextureCubeMapPositiveZ, 0, PixelInternalFormat.R16f, size, size, 0, PixelFormat.Red, PixelType.Float, IntPtr.Zero);
GL.TexImage2D(TextureTarget.TextureCubeMapNegativeZ, 0, PixelInternalFormat.R16f, size, size, 0, PixelFormat.Red, PixelType.Float, IntPtr.Zero);

// Set the suitable texture parameters
GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge);
GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge);
GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapR, (int)TextureWrapMode.ClampToEdge);
GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureBaseLevel, 0);
GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureMaxLevel, 0);

// Attach cubemap texture as the FBO's color buffer
GL.BindFramebuffer(FramebufferTarget.Framebuffer, FBO_handle);
GL.FramebufferTexture(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, cubeMapTexture, 0);

几何着色器

#version 330

layout(triangles) in;
layout (triangle_strip, max_vertices=18) out;

uniform mat4 projectionMatrix;
uniform mat4 shadowTransforms[6];
out vec4 frag_position;

void main()
{
for(int face = 0; face < 6; face++)
{
gl_Layer = face;
for(int i=0; i<3; i++)
{
frag_position = shadowTransforms[face] * gl_in[i].gl_Position;
gl_Position = projectionMatrix * shadowTransforms[shadowTransforms] * gl_in[i].gl_Position;

EmitVertex();
}
EndPrimitive();
}
}

渲染

for (int j = 0; j < lights.Count; j++)
{
// GL setup
GL.BindFramebuffer(FramebufferTarget.Framebuffer, shadowBuffers[j].FBO_handle);
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
Matrix4 viewMatrix = Matrix4.Identity;

// Create the light's view matrices
List<Matrix4> shadowTransforms = new List<Matrix4>();
shadowTransforms.Add(Matrix4.LookAt(lights[j].position, lights[j].position + new Vector3(1, 0, 0), new Vector3(0, -1, 0)));
shadowTransforms.Add(Matrix4.LookAt(lights[j].position, lights[j].position + new Vector3(-1, 0, 0), new Vector3(0, -1, 0)));
shadowTransforms.Add(Matrix4.LookAt(lights[j].position, lights[j].position + new Vector3(0, 1, 0), new Vector3(0, 0, -1)));
shadowTransforms.Add(Matrix4.LookAt(lights[j].position, lights[j].position + new Vector3(0, -1, 0), new Vector3(0, 0, -1)));
shadowTransforms.Add(Matrix4.LookAt(lights[j].position, lights[j].position + new Vector3(0, 0, 1), new Vector3(0, -1, 0)));
shadowTransforms.Add(Matrix4.LookAt(lights[j].position, lights[j].position + new Vector3(0, 0, -1), new Vector3(0, -1, 0)));

// Send them to the shader
for (int i = 0; i < 6; ++i)
{
Matrix4 shadowTransform = shadowTransforms[i];
GL.UniformMatrix4(shader.getUniformID("shadowTransforms[" + i + "]"), false, ref shadowTransform);
}

// Draw Scene
for (int r = 0; r < renderables.Count; r++)
renderables[r].draw(shader);
}

对于大量的代码转储,我深表歉意,FBO 有点冗长,我相信你知道。对于那些不熟悉 OpenTK c# 包装器的人,我认为如果我也提供有效的多 channel 代码可能会有所帮助。

多次通过(工作正常)

创建Fbo

// Create cubemap texture
GL.GenTextures(1, out cubeTex);
GL.BindTexture(TextureTarget.TextureCubeMap, cubeTex);
GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureBaseLevel, 0);
GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureMaxLevel, 0);
GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
GL.TexImage2D(TextureTarget.TextureCubeMapPositiveX, 0, PixelInternalFormat.R16f, size, size, 0, PixelFormat.Red, PixelType.Float, IntPtr.Zero);
GL.TexImage2D(TextureTarget.TextureCubeMapNegativeX, 0, PixelInternalFormat.R16f, size, size, 0, PixelFormat.Red, PixelType.Float, IntPtr.Zero);
GL.TexImage2D(TextureTarget.TextureCubeMapPositiveY, 0, PixelInternalFormat.R16f, size, size, 0, PixelFormat.Red, PixelType.Float, IntPtr.Zero);
GL.TexImage2D(TextureTarget.TextureCubeMapNegativeY, 0, PixelInternalFormat.R16f, size, size, 0, PixelFormat.Red, PixelType.Float, IntPtr.Zero);
GL.TexImage2D(TextureTarget.TextureCubeMapPositiveZ, 0, PixelInternalFormat.R16f, size, size, 0, PixelFormat.Red, PixelType.Float, IntPtr.Zero);
GL.TexImage2D(TextureTarget.TextureCubeMapNegativeZ, 0, PixelInternalFormat.R16f, size, size, 0, PixelFormat.Red, PixelType.Float, IntPtr.Zero);

// Create cubemap FBOs
GL.GenFramebuffers(6, cubeFBOs);
for (int i = 0; i < 6; i++)
{
GL.BindFramebuffer(FramebufferTarget.Framebuffer, cubeFBOs[i]);
GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.TextureCubeMapPositiveX + i, cubeTex, 0);
}

几何着色器

#version 330

layout(triangles) in;
layout(triangle_strip, max_vertices=3) out;

uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
out vec4 frag_position;

void main()
{
for(int i=0; i<3; i++)
{
frag_position = viewMatrix * gl_in[i].gl_Position;
gl_Position = projectionMatrix * viewMatrix * gl_in[i].gl_Position;
EmitVertex();
}
EndPrimitive();
}

渲染

for (int j = 0; j < lights.Count; j++)
{
for (int i = 0; i < 6; ++i)
{
GL.BindFramebuffer(FramebufferTarget.Framebuffer, shadowBuffers[j].cubeFBOs[i]);
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
Matrix4 viewMatrix = Matrix4.Identity;

if (i == 0) viewMatrix = Matrix4.LookAt(lights[j].position, lights[j].position + new Vector3(1, 0, 0), new Vector3(0, -1, 0));
if (i == 1) viewMatrix = Matrix4.LookAt(lights[j].position, lights[j].position + new Vector3(-1, 0, 0), new Vector3(0, -1, 0));
if (i == 2) viewMatrix = Matrix4.LookAt(lights[j].position, lights[j].position + new Vector3(0, 1, 0), new Vector3(0, 0, -1));
if (i == 3) viewMatrix = Matrix4.LookAt(lights[j].position, lights[j].position + new Vector3(0, -1, 0), new Vector3(0, 0, -1));
if (i == 4) viewMatrix = Matrix4.LookAt(lights[j].position, lights[j].position + new Vector3(0, 0, 1), new Vector3(0, -1, 0));
if (i == 5) viewMatrix = Matrix4.LookAt(lights[j].position, lights[j].position + new Vector3(0, 0, -1), new Vector3(0, -1, 0));
GL.UniformMatrix4(shader.getUniformID("viewMatrix"), false, ref viewMatrix);

// Draw Scene
for (int r = 0; r < renderables.Count; r++)
renderables[r].draw(shader);
}
}

片段着色器

#version 330

precision lowp float;

in vec4 frag_position;

layout (location = 0) out vec4 outColor;

void main() {
float depth = length( vec3(frag_position) ) / 20;

float moment1 = depth;
float moment2 = depth * depth;

float dx = dFdx(depth);
float dy = dFdy(depth);
moment2 += 0.25*(dx*dx+dy*dy);

outColor = vec4( moment1, moment2, 0.0, 0.0);
}

任何见解将不胜感激,谢谢!

最佳答案

令人尴尬的是,原因是几何着色器中的拼写错误。

shadowTransforms[shadowTransforms] 需要是 shadowTransforms[face]

uniform mat4 shadowTransforms[6] 需要是 uniform mat4 shadowTransforms[]

enter image description here

这对我来说是一个巨大的突破。以 60 fps 的速度转换多个阴影点光源。感谢一路上帮助过我的每一个人。

关于c# - OpenGL - 单 channel 立方体贴图不产生任何输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40222125/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com