Застрял на рендеринг огней после привязки FBO с использованием отложенного рендеринга с использованием OpenGL

Прежде всего, я прошу прощения за этот длинный пост после попытки сделать эту работу целый день.

У меня много вопросов по этому поводу, особенно потому, что я использую наследование в C ++ для создания источников света.

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

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

Это была первая проблема, вторая, так как у каждого типа света есть свой шейдер, и я строю их, используя полиморфизм. Мой второй вопрос: я могу перебрать каждый источник света в C ++ и вызвать каждый источник освещения для рендеринга, или есть другой способ решить эту проблему в шейдерах.
Прототипы светильников
РЕДАКТИРОВАТЬ: я исправил небольшую проблему, в которой трансформировался квант рендеринга с проекцией VP, но все же я ничего не могу нарисовать, и я понятия не имею, работает ли теперь FB правильно. Отладчик nvidia opengl просто падает.

 Light(glm::vec3& color, float intensity, float ambient, ShaderProgram& lightShader);
DirectionalLight(glm::vec3& color = glm::vec3(1.0f, 1.0f, 1.0f), glm::vec3& position = glm::vec3(0.0f, 0.0f, 0.0f), float intensity = 1.0f, float ambient = 0.0f, ShaderProgram& lightShader = ShaderProgram("Directional Light"));
PointLight(glm::vec3& color = glm::vec3(1.0f, 1.0f, 1.0f), glm::vec3& position = glm::vec3(0.0f, 0.0f, 0.0f), float intensity = 1.0f, float ambient = 0.0f, LightAttenuation& lightAttenuation = LightAttenuation(), ShaderProgram& lightShader = ShaderProgram("Point Light"));
SpotLight(glm::vec3& color = glm::vec3(1.0f, 1.0f, 1.0f), glm::vec3& position = glm::vec3(0.0f, 0.0f, 0.0f),

Мой путь рендеринга выглядит следующим образом.

            glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);

defferedShader_.startProgram();
defferedShader_.setUniformMat4("VP", camera.getVP());glBindFramebuffer(GL_FRAMEBUFFER, deferredFbo);

//the scene is small and does not need culling.
for (auto* mesh : world.getMeshes()) {

//mesh->draw(light->getLightShader());
//mesh->draw(activeLight_->getLightShader());
mesh->draw(defferedShader_);

drawCallCounter += mesh->getMeshObjectSize();
}

glBindFramebuffer(GL_FRAMEBUFFER, 0);
defferedShader_.stopProgram();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, positionFbo);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, normalFbo);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, albedoFbo);

//This is where i got stuck, I would like to make directional light work then test other lights then test the whole program with more than one light
//for (auto* light : world.getLights()) {
//  //glEnable(GL_CULL_FACE);
//  //glCullFace(GL_FRONT);
glDisable(GL_DEPTH_TEST);
activeLight_->getLightShader().startProgram();

activeLight_->getLightShader().setUniformMat4("VP", camera.getVP());
activeLight_->getLightShader().setUniformVec3("eyePosition", camera.getCameraPosition());

//activeLight_->getLightShader();
RenderQuad();

activeLight_->getLightShader().stopProgram();

//}

Код шейдера, который я начал собирать, — это (сейчас я удалил тени)
Вершинный шейдер

    #version 410 core

#include "../Global/GlobalShader.inc"#include "../Global/GlobalMesh.inc"
out vec3 Position;
out vec2 TexCoord;
//out vec4 ShadowCoord;

//uniform mat4 ShadowMatrix;

void main() {

Position = position;
TexCoord = texCoord;

//ShadowCoord = ShadowMatrix * vec4(position, 1.0);
gl_Position = VP * vec4(position, 1.0);
}

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

        #version 410 core

#include "../Global/GlobalShader.inc"#include "../Global/GlobalMesh.inc"#include "../Global/GlobalLight.inc"//#include "../Global/ShadowSampling.inc"
in vec3 Position;
in vec2 TexCoord;
//in vec4 ShadowCoord;

uniform sampler2D gPosition;
uniform sampler2D gNormal;
uniform sampler2D gAlbedoSpec;

float specularStrength = 32.0f; // to be impelemented

out vec4 gl_FragColor;
void main() {

//vec4 lightning = vec4(0.0f);
////vec4 shadowMapping = vec4(0.0f);
//
vec3 FragPos = texture(gPosition, TexCoord).rgb;
vec3 Normal = texture(gNormal, TexCoord).rgb;
vec3 Diffuse = texture(gAlbedoSpec, TexCoord).rgb;
float Specular = texture(gAlbedoSpec, TexCoord).a;

//vec3 Diffuse = texture(gAlbedoSpec, TexCoord).rgb;
//lightning = calculateDirectionalLight(directionalLight.light, directionalLight.position, Normal, Position, specularStrength, eyePosition, material, TexCoord);
//gl_fragColor = vec3(Position, 1.0);
//shadowMapping = calculateShadow(shadowMap, ShadowCoord, directionalLight.light.ambient);
//gl_FragColor = vec4(Diffuse, 1.0);
gl_FragColor = vec4(1.0); //vec4(Diffuse, 1.0);// lightning;//g * shadowMapping;

//gl_FragColor = lightning;// * shadowMapping;
}

in case you want to see global light

struct Light
{
vec3 color;
float intensity;
float ambient;
};

struct DirectionalLight
{
Light light;
vec3 position;
};

struct Attenuation
{
float constant;
float linear;
float quadratic;
};

struct PointLight
{
Light light;
Attenuation atten;
vec3 position;
float range;
};

struct SpotLight
{
PointLight pointLight;
//vec3 lookAt;
vec3 direction;
float cutOff;
};

vec3 GAMMA = vec3(1.0/2.2);

vec4 calculateDirectionalLight(Light light, vec3 direction, vec3 normal, vec3 worldPosition, float specularIntensity, vec3 eyePosition, Material material, vec2 texCoord)
{
vec3 diffuseFactor = ( light.color * material.diffuse * vec3(texture(material.texture.diffuse, texCoord.st)) )
* (light.intensity * clamp(dot(normal, direction), 0.0, 1.0) ) ;

vec3 viewDir = normalize(eyePosition - worldPosition);
vec3 reflectDir = normalize(reflect(-direction, normal));

float specularFactor = pow(clamp(dot(viewDir, reflectDir), 0.0, 1.0), specularIntensity);
vec3 specularColor = ( light.color * material.specular * vec3(texture(material.texture.specular, texCoord.st)) ) * (specularFactor * material.shininess);

return vec4(pow((diffuseFactor + specularColor + light.ambient + material.ambient), GAMMA), 1.0);
}

vec4 calculatePointLight(PointLight pointLight, vec3 normal, vec3 worldPosition, float specularIntensity, vec3 eyePosition, Material material, vec2 texCoord)
{
// DO NOT NORMALIZE lightDirection, WE NEED IT TO CALCULATE THE DISTANCE TO COMPARE RANGE OF LIGHT
vec3 lightDirection = pointLight.position - worldPosition;
float distanceToPoint = length(lightDirection);

// I dont like conditionals in shader, but since this is fragment based lighting i believe
// this will speed-up things insetead of calculating the light
if(distanceToPoint > pointLight.range)
return vec4(0.0,0.0,0.0,0.0);

vec4 light = calculateDirectionalLight(pointLight.light, lightDirection, normal, worldPosition,  specularIntensity, eyePosition, material, texCoord);

// light attenuateion explained https://developer.valvesoftware.com/wiki/Constant-Linear-Quadratic_Falloff
// http://www.ogre3d.org/tikiwiki/tiki-index.php?page=Light+Attenuation+Shortcut
float attenuation = max(pointLight.atten.constant
+ pointLight.atten.linear * distanceToPoint
+ pointLight.atten.quadratic * distanceToPoint * distanceToPoint,
1.0);

return light / attenuation;
}

vec4 calculateSpotLight(SpotLight spotLight, vec3 normal, vec3 worldPosition, float specularIntensity, vec3 eyePosition, Material material, vec2 texCoord)
{
vec3 lightDirection = normalize(spotLight.pointLight.position - worldPosition);
float spotFactor = dot(lightDirection, spotLight.direction);

vec4 light = vec4(0.0f);
if(spotFactor > spotLight.cutOff)
{
light = calculatePointLight(spotLight.pointLight, normal, worldPosition, specularIntensity, eyePosition, material, texCoord) * (1.0 - (1.0 - spotFactor)/(1.0 - spotLight.cutOff));
}

return light;
}

Глобальная сетка

   struct Texture {
sampler2D diffuse;
sampler2D specular;
sampler2D normal;
sampler2D ambient;
sampler2D height;
//vec2 texCoord;
};

struct Material {
vec3 ambient;           // Ka
vec3 diffuse;           // Kd
vec3 specular;          // Ks
vec3 transmittance;     // Tr
vec3 emission;          // Ke
float shininess;        // Ns
float ior;              // Ni
float dissolve;         // Dissolve
int illum;              // Illum
Texture texture;
};

uniform Material material;

layout (location = 0) in vec3 position;
layout (location = 1) in vec2 texCoord;
layout (location = 2) in vec3 normal;

Глобальный шейдер

    uniform mat4 VP;
uniform mat4 P;

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

и просто в качестве примера, чтобы увидеть сцену, это буфер положения
введите описание изображения здесь

0

Решение

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

glEnable(GL_DEPTH_TEST);glBindFramebuffer(GL_FRAMEBUFFER, deferredFbo);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
defferedShader_.startProgram();
defferedShader_.setUniformMat4("VP", camera.getVP());
.
.
. rest of the code
0

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

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

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