2014-01-05 2 views
1

Я работаю над компонентом рендеринга текстуры графического движка. Мне потребовалось пару часов, чтобы реализовать его на DX, и он работает так, как ожидалось, я потратил несколько дней на реализацию OpenGL, но он отказывается работать.Странные результаты при рендеринге глубины текстуры в OpenGL

При визуализации буфера глубины текстуры я получаю несколько ожидаемые результаты, но изображение полностью из странных артефактов (цветные цели прекрасно работают). Я играл с различными настройками глубины и трафаретов, разными способами привязки, но я не получаю.

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

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

Вот результат я получаю в DX (что я и ожидал): [1]: http://i.imgur.com/Zfchzq3.png "Хороший результат"

И вот результат я получаю от GL: [2]: http://i.imgur.com/vH9u1bq.png «Одд Результат "

Я не знаю, откуда берутся черные части. Через небольшую отладку шейдеров я могу сказать, что незагруженные области остаются 1.0 (глубина четкого значения), а не черные области близки к 1.0, но никогда не достигают этого (как и следовало ожидать). Черные области ... случайные.

код я использую для создания текстуры:

glGenTextures(1, &textureID); 
dim = GL_TEXTURE_2D; 
wth = width; 
hgt = height; 
iFormat = _glTranslateFormat(fmt, format, type); 
glBindTexture(dim, textureID); 
glTexStorage2D(dim, 1, iFormat, width, height); 

_glTranslateFormat переводит собственные форматы в форматы GL, это возвращает GL_DEPTH_COMPONENT16 атм. Я пробовал другие форматы, они приносят еще более странные результаты. 32 и 32F позволяют выборку значений за пределами диапазона 0 и 1 (например, выше 1000000000), основанные на трафарете также вызывают множество проблем (даже когда я изменяю код, чтобы принять трафарет).

код я использую, чтобы связать его в буфер кадра является:

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, d->_exposeTexture()->_exposeAPI(), 0); 

_exposeAPI возвращает идентификатор текселя. Это происходит каждый раз, когда код требует, чтобы буфер глубины связывался с другим буфером кадров (фреймбуфер будет связан перед рукой).

Я пробовал различные методы привязки цели визуализации к буферу кадров, а что нет, но проблема никогда не исчезает. Любая помощь будет принята с благодарностью. Пока мне придется отказаться от компонентов OpenGL от движка и работать с DX, пока не найду исправление для этой проблемы.

EDIT: В соответствии с просьбой я добавил шейдер, ответственный за выборку из текстуры, материал в конце файла - это просто отлаживаемый код, с которым я играл. Текстура глубины входит как диффузная текстура.

#version 430 

    struct Light 
     { 
     vec4 diffuse; 
     vec4 specular; 
     vec4 attenuation; 
     vec3 spot; 
     uint nID; 
     uint type; 
     }; 

    layout (std140, binding = 9) uniform singleLight 
     { 
     Light light; 
     }; 

    struct BasicFSInput 
     { 
     vec4 position; 
     vec3 normal; 
     vec2 uv; 
     vec4 fragPos; 
     vec3 toLight; 
     }; 

    layout(binding = 1) uniform sampler2D diff1; 
    layout(binding = 2) uniform sampler2D amb1; 
    layout(binding = 3) uniform sampler2D spec1; 

    layout (location = 0) in BasicFSInput fin; 
    layout (location = 0) out vec4 color; 

    layout(std140, binding = 10) uniform material 
     { 
     float specular; 
     float shininess; 
     }; 

    void BasicFragmentShader() 
     { 
     vec4 dTexel = texture(diff1, fin.uv).rgba; 
     vec4 aTexel = texture(amb1, fin.uv).rgba; 
     vec4 sTexel = texture(spec1,fin.uv).rgba; 

     vec3 lightDir = normalize(fin.toLight); 
     vec3 n = normalize(fin.normal); 
     float NdotL = max(dot(n, lightDir),0.0); 
     vec4 col = NdotL * light.diffuse; 
     vec4 ambContrib = aTexel; 
     vec4 diffContrib = dTexel * col; 

     vec3 refl = 2.0 * NdotL * n + lightDir; 
     float NdotR = max(dot(normalize(refl), normalize(-fin.fragPos.xyz)),0.0); 
     float specContrib = sTexel * specular * pow(NdotR, shininess); 

     color = ambContrib + diffContrib + specContrib;/* 
     if(dTexel.r < -1.0) 
      color.r = 1.0f; 
     if(dTexel.r > 1.0) 
      color.b = 1.0f; 
     if(dTexel.r == 1.0f) 
      color.g = 1.0f;*/ 
     //color.r = dTexel.r; 

     /*if(dTexel.r < 0.5f) 
      color.b = 1.0f; 
     if(dTexel.r > 0.5f) 
      color.r = 1.0f;*/ 
     /*if(dTexel.r < -10000000.0f) 
      color.g = 1.0f;*/ 
     //color.a = 1.0f; 
     } 
+0

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

+0

@ AndonM.Coleman Не думаю, что я беру выборку из того же буфера глубины, когда пишу, но я посмотрю на это, спасибо. Я добавлю шейдер в конец вопроса, его не слишком сложно. – CloudScorpion

+0

Вы задали режим образца текстур глубины? i.e GL_LEQUAL –

ответ

1

Не оставляйте OpenGL, что быстро :)

Вы уверены, что вы хотите сделать буфер глубины в текстуру, а не цвет буфер текстуры?

Возможно, ниже может помочь (извинения, если вы уже это знали).(Это взято из OpenGL Superbible 6-е издание.)

Настройка фреймбуфера

glGenFramebuffers(1, &fbo); 
glBindFramebuffer(GL_FRAMEBUFFER, fbo); 
    //texture for the colour buffer 
glGenTextures(1, &colourTexture); 
glBindTexture(GL_TEXTURE_2D, colourTexture); 
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, width, height); 

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
    //texture for the depth buffer 
glGenTextures(1, &depthTexture); 
glBindTexture(GL_TEXTURE_2D, depthTexture); 
glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT32F, width, hwight); 

glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, colourTexture, 0); 
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthTexture, 0); 

const GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0 }; 
glDrawBuffers(1, drawBuffers); 

Затем перед вызовом glDrawArrays/элементы связываются с фреймбуфером

glBindFramebuffer(GL_FRAMEBUFFER, fbo); 

Позже, когда вы хотите, чтобы сделать текстуру экран связывает текстуру

 glBindTexture(GL_TEXTURE_2D, colourTexture); 

Внутри фрагмента, когда рендеринга текстуры требуется сэмплер.

#version 430 core 
uniform sampler2D tex; 
in VS_OUT 
{ 
    vec2 texcoord; 
} fs_in; 
out vec4 color; 
void main(void) 
{ 
color = texture(tex, fs_in.texcoord); 
} 
+0

Спасибо за ваш ответ. У меня уже есть обработка цвета, я пытаюсь работать с глубиной. [Изображение этого рабочего.] (Http://i.imgur.com/fVTctoB.png) Не волнуйтесь, я уже написал этот движок для работы с DX и GL, я не оставляю GL, просто оставив эту задачу на данный момент. – CloudScorpion

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