Also ich versuche, verzögerte Wiedergabe in opengl zu implementieren. Dazu erstelle ich einen FBO, der 3 Texturen rendert (eine für Position, eine für Normal, eine für Materialinfo), aber da ich nicht fertig bin, ist die 3. Textur stattdessen nur die letzte Farbe des Fragments. Und ein letzter Tiefenpuffer, um später Schatten zu implementieren.Der Versuch, mehrere Texturen zu rendern, um das verzögerte Rendering zu implementieren. Aber alle Texturen sind gleich
Diese Texturen werden dann an einen anderen Shader (und mit dem Standard-Frame-Buffer) übergeben, der die endgültige Farbe des Pixels berechnet. Alle 3 Texturen enthalten jedoch die gleichen Informationen, die die erste Ausgabevariable des Geometry-Pass-Shaders ist.
#version 330
//Fragment shader from the lighting pass
in vec2 vTexCoord;
uniform sampler2D uPosTexture;
uniform sampler2D uNormalTexture;
uniform sampler2D uColorTexture;
out vec4 fFragColor;
void main()
{
//All of the following lines output the same image
vec3 color = texture(uNormalTexture, vTexCoord).rgb;
//vec3 color = texture(uPosTexture, vTexCoord).rgb;
//vec3 color = texture(uColorTexture, vTexCoord).rgb;
fFragColor = vec4(color,1);
}
Alle 3 Ausgang dieses Bild:
Und hier ist meine Geometrie Fragment-Shader:
#version 330
in vec3 vECPos; // S.R. Vista
in vec3 vECNorm; // S.R. Vista
in vec4 vShadowCoord;
layout (location = 0) out vec3 fPosition;
layout (location = 1) out vec3 fNormal;
layout (location = 2) out vec4 fFragColor;
uniform sampler2DShadow uShadowMap;
uniform int uTipoFiltro;
struct LightInfo {
vec4 lightPos; // Posición de la luz (S.R. de la vista)
vec3 intensity;
};
uniform LightInfo uLight;
struct MaterialInfo {
vec3 ambient;
vec3 diffuse;
vec3 specular;
float shininess;
};
uniform MaterialInfo uMaterial;
vec3 phongModelDiffAndSpec()
{
vec3 ldir = normalize(vec3(uLight.lightPos) - vECPos);
vec3 view = normalize(vec3(-vECPos));
vec3 r = reflect(-ldir,vECNorm);
vec3 color = uLight.intensity * (uMaterial.diffuse * max(dot(ldir,vECNorm), 0.0) +
uMaterial.specular * pow(max(dot(r,view),0),uMaterial.shininess));
return clamp(color, 0.0, 1.0);
}
void main()
{
vec3 ambient = uLight.intensity * uMaterial.ambient;
vec3 diffAndSpec = phongModelDiffAndSpec();
fPosition = vECPos;
fNormal = normalize(vECNorm);
fFragColor = vec4(ambient + diffAndSpec,1.0);
}
Allerdings scheint es, dass nur die erste Ausgangsgröße da getan wird, wenn Ich ändere das:
layout (location = 1) out vec3 fPosition;
layout (location = 2) out vec3 fNormal;
layout (location = 0) out vec4 fFragColor;
Dies zeigt:
Hier sind weitere wichtige Funktionen
bool init()
{
glClearColor(0.93f, 0.93f, 0.93f, 0.0f);
glEnable(GL_DEPTH_TEST);
//glDepthFunc(GL_LESS);
//glClearDepth(1.0f);
//glShadeModel(GL_SMOOTH);
//Create shaders
createShader(geometryPassShader, "geometry.vert", "geometry.frag");
setUniformGeometry();
createShader(lightPassShader, "lighting.vert", "lighting.frag");
setUniformLighting();
initFBO();
passTexturesToStdFBO();
//Init objects
numVertTeapot = initTeapot(5, glm::mat4(1.0f));
numVertSphere = initSphere(1.0f, 20, 30);
numVertPlane = initPlane(10.0f, 10.0f, 2, 2);
numVertTorus = initTorus(0.5f, 0.25f, 20, 40);
initQuad();
return true;
}
void initFBO()
{
//Crear 1 FBO
glGenFramebuffers(1, &gBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, gBuffer);
//Crear textura que guarda posicion
glGenTextures(1, &gPositionTex);
//glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, gPositionTex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, g_Width, g_Height, 0, GL_RGB, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
//Añadir la textura al FBO
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gPositionTex, 0);
//Crear textura que guarda normal
glGenTextures(1, &gNormalTex);
//glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, gNormalTex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, g_Width, g_Height, 0, GL_RGB, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
//Añadir textura al FBO
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, gNormalTex, 0);
//Crear textura que guarda informacion del material del "pixel"
glGenTextures(1, &gMaterialTex);
//glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, gMaterialTex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, g_Width, g_Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, gMaterialTex, 0);
//Crear depth buffer
glGenTextures(1, &depth_texture);
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, depth_texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, g_Width, g_Height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
//Indicamos que buffers (texturas) seran escritos con el output del fragment shader
glDrawBuffers(3, attachments); //attachments[3] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 };
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_texture, 0);
GLenum result = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (result == GL_FRAMEBUFFER_COMPLETE)
std::cout << "Frame buffer complete" << std::endl;
else
std::cout << "Frame buffer is not complete" << std::endl;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void display()
{
//glClear of this FBO is done inside drawFBO()
glUseProgram(geometryPassShader);
drawFBO();
glUseProgram(0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(lightPassShader);
//passTexturesToStdFBO();
drawQuad();
glUseProgram(0);
glutSwapBuffers();
}
void drawFBO()
{
glBindFramebuffer(GL_FRAMEBUFFER, gBuffer);
glViewport(0, 0, g_Width, g_Height);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
drawScene();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void passTexturesToStdFBO()
{
glBindBuffer(GL_FRAMEBUFFER, 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, gPositionTex);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, gNormalTex);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, gMaterialTex);
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, depth_texture);
}
void setUniformLighting()
{
GLuint loc0 = glGetUniformLocation(lightPassShader, "uPosTexture");
glUniform1i(loc0, 0);
GLuint loc1 = glGetUniformLocation(lightPassShader, "uNormalTexture");
glUniform1i(loc1, 1);
GLuint loc2 = glGetUniformLocation(lightPassShader, "uColorTexture");
glUniform1i(loc2, 2);
}