그래서 나는 OpenGL에서 지연 렌더링을 구현하려고합니다. 이렇게하려면 3 개의 텍스처 (위치에 대한 하나, 일반에 대한 하나, 재료 정보에 대한 하나)로 렌더하는 FBO를 만듭니다.하지만 3 번째 텍스처가 완성되지 않았으므로 대신 단편의 최종 색상이됩니다. 그리고 마지막 깊이 버퍼는 나중에 그림자를 구현합니다.여러 텍스처를 렌더링하여 지연 렌더링을 구현하려고합니다. 하지만 모든 텍스처는 동일합니다
이 텍스처는 픽셀의 최종 색상을 계산하는 다른 셰이더 (기본 프레임 버퍼가있는)로 전달됩니다. 그러나 모든 3 개의 텍스처에는 기하학 패스 셰이더의 첫 번째 출력 변수 인 동일한 정보가 포함되어 있습니다.
#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);
}
모든 3 출력이 이미지 :
#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);
}
그러나이 첫 번째 출력 변수가 있기 때문에 경우에 할 것 같다 : 여기
그리고 내 기하학 조각 쉐이더입니다 나는 이것을 바꾼다 :
layout (location = 1) out vec3 fPosition;
layout (location = 2) out vec3 fNormal;
layout (location = 0) out vec4 fFragColor;
백45경1천5백15조5백36억9천1백36만3천2백10
이 보여 glUseProgram
의해 정의
은 다른 중요한 기능
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);
}
현재 프로그램에