Почему я не могу получить доступ к G-Buffer из моего осветительного шейдера?

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

Я не могу объяснить это поведение, и странно то, что в любой момент нет ошибок OpenGL.

Вершинный шейдер для рисования полноэкранного четырехугольника.

#version 330

in vec4 vertex;

out vec2 coord;

void main()
{
coord = vertex.xy;
gl_Position = vertex * 2.0 - 1.0;
}

Фрагмент шейдера для освещения.

#version 330

in vec2 coord;
out vec3 image;

uniform int type = 0;
uniform sampler2D positions;
uniform sampler2D normals;
uniform vec3 light;
uniform vec3 color;
uniform float radius;
uniform float intensity = 1.0;

void main()
{
if(type == 0) // directional light
{
vec3 normal = texture2D(normals, coord).xyz;
float fraction = max(dot(normalize(light), normal) / 2.0 + 0.5, 0);
image = intensity * color * fraction;
}
else if(type == 1) // point light
{
vec3 pixel = texture2D(positions, coord).xyz;
vec3 normal = texture2D(normals, coord).xyz;
float dist = max(distance(pixel, light), 1);
float magnitude = 1 / pow(dist / radius + 1, 2);
float cutoff = 0.4;
float attenuation = clamp((magnitude - cutoff) / (1 - cutoff), 0, 1);
float fraction = clamp(dot(normalize(light - pixel), normal), -1, 1);
image = intensity * color * attenuation * max(fraction, 0.2);
}
}

Мишени и пробоотборники для освещения проходят. Идентификаторы текстуры сопоставляются с вложением соответственно местоположению шейдера.

unordered_map<GLenum, GLuint> targets;
targets.insert(make_pair(GL_COLOR_ATTACHMENT2, ...)); // light
targets.insert(make_pair(GL_DEPTH_STENCIL_ATTACHMENT, ...)); // depth and stencil

unordered_map<string, GLuint> samplers;
samplers.insert(make_pair("positions", ...)); // positions from G-Buffer
samplers.insert(make_pair("normals", ...)); // normals from G-Buffer

Функция Draw для освещения прохода.

void DrawLights(unordered_map<string, GLuint> Samplers, GLuint Program)
{
auto lis = Entity->Get<Light>();

glClear(GL_COLOR_BUFFER_BIT);

glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);

glUseProgram(Program);
int n = 0; for(auto i : Samplers)
{
glActiveTexture(GL_TEXTURE0 + n);
glBindTexture(GL_TEXTURE_2D, i.second);
glUniform1i(glGetUniformLocation(Program, i.first.c_str()), n);
n++;
}

mat4 view = Entity->Get<Camera>(*Global->Get<unsigned int>("camera"))->View;

for(auto i : lis)
{
int type = i.second->Type == Light::DIRECTIONAL ? 0 : 1;
vec3 pos = vec3(view * vec4(Entity->Get<Form>(i.first)->Position(), !type ? 0 : 1));
glUniform1i(glGetUniformLocation(Program, "type"),      type);
glUniform3f(glGetUniformLocation(Program, "light"),     pos.x, pos.y, pos.z);
glUniform3f(glGetUniformLocation(Program, "color"),     i.second->Color.x, i.second->Color.y, i.second->Color.z);
glUniform1f(glGetUniformLocation(Program, "radius"),    i.second->Radius);
glUniform1f(glGetUniformLocation(Program, "intensity"), i.second->Intensity);

glBegin(GL_QUADS);
glVertex2i(0, 0);
glVertex2i(1, 0);
glVertex2i(1, 1);
glVertex2i(0, 1);
glEnd();
}

glDisable(GL_BLEND);
glActiveTexture(GL_TEXTURE0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
}

5

Решение

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

Поэтому кадровый буфер G-Buffer все еще был связан, и проход освещения изменил свои цели.

Спасибо вам, ребята, у вас не было никаких изменений, чтобы найти эту ошибку, так как я не опубликовал свою полную систему конвейера.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]