2016-10-24 2 views
2

enter image description hereOpenGL - Один дает проход cubemap не выход

Я написал реализацию отображения сырой тень, которая делает эту сцену 6 раз с 6 различными матрицами зрения для создания cubemap.

Как оптимизация, я пытаюсь перейти на однопроходный подход, используя геометрический шейдер, но изо всех сил пытаюсь получить какой-либо вывод из моих шейдеров.

Проблема возникает при связывании текстуры куба. С multi-pass я просто связываю 1 из 6 FBOs за один раз, однако с одним проходом мне нужно связать все 6 кубических граней сразу, и у меня нет дескриптора для этого. В этих случаях документация предлагает создать один FBO с FrameBufferTexture, который содержит все 6 лиц. Правильно ли я это сделал?

В качестве альтернативы, проблема может быть маршрутизирована в геометрическом шейдере, но, видя, что я не получаю никакого вывода, его очень сложно отладить.

ПОЛИСТНОЙ (без вывода)

создание 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(); 
    } 
} 

Rendering

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); 
} 

Я прошу прощения за массивный свалку кода, FBOs довольно длинны, я уверен, вы знаете. Для тех, кто не знаком с оболочкой OpenTK C#, я полагаю, что это было бы полезно, если бы я также предоставил рабочий код многопроходного кода.

многопроходной (работает нормально)

создание 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(); 
} 

Rendering

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); 
    } 
} 

Фрагмент 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); 
} 

Любое понимание было бы весьма признателен, спасибо!

+0

Итак ... как насчет вашего буфера глубины? Вы проверяли, завершено ли ваше FBO? Или если вы получили ошибки OpenGL? –

+0

Я пока храню глубину в текстуре. Я добавлю шейдер фрагмента выше, это будет иметь смысл, как только вы это увидите. –

+0

FBO завершен в обоих случаях. Я не уверен, как проверить ошибки OpenGL, но я получу на нем. –

ответ

2

Сложно, причиной была комбинация опечаток в геометрическом шейдере.

shadowTransforms[shadowTransforms] нужно быть shadowTransforms[face] и

uniform mat4 shadowTransforms[6] нужно быть uniform mat4 shadowTransforms[].

enter image description here

Это знаменует собой огромный прорыв для меня. Многократная подсветка точек затенения при 60 кадрах в секунду.Спасибо всем, кто помог мне на этом пути.

+0

И для записи Альфонса, хорошего вызова в буфере глубины, это было в основном случайностью, что он работал без него. Тени просачивались в другие комнаты, я просто не проверял их. –

Смежные вопросы