Mivoj
Založen: 11. 12. 2012 Příspěvky: 32
|
Zaslal: 11. leden 2015, 15:48:54 Předmět: Problém překreslení scény při zapnutí SSAO nebo stínů |
|
|
Tak zkouším deffered shading s SSAO podle tohoto tutorialu http://www.3dcpptutorials.sk/ a mám tam jakože polofunkční i SSAO jenže mám problém s tím, že se mně neaktializuje FBO vrstva čtverce do kterého zapisuju to SSAO. Prostě deffered lighting jide, ale jak zapnu SSAO tak už scena je statická a s kamerou nemůžu otáčet. To samé, když zapnu stíny, taky nemůžu hýbat kamerou, ale hýbu světly se stíny namísto kamery.
kód: |
void drawScene()
{
glMatrixMode(GL_PROJECTION);
glLoadMatrixf((const GLfloat*)&mProjection);
mView = camera.look(); // pohybuj a rotuj kamerou
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf((const GLfloat*)&mView);
gFrustum.calculateFrustum();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBO);
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
spMain.useProgram();
scene.drawVBO();
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
// calculate shadow cube maps matrices ------------------------------------------------------------------------------------
if (appSet.calculateShadows && !ShowSSAO)
{
for (GLushort i = 0; i < lightsModel.pLightObj.size(); ++i)
// for (int i = 0; i < 4; i++)
{
lightViewMatrices[i * 6 + 0] = glm::lookAt(lightPositions[i], lightPositions[i] + glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
lightViewMatrices[i * 6 + 1] = glm::lookAt(lightPositions[i], lightPositions[i] + glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
lightViewMatrices[i * 6 + 2] = glm::lookAt(lightPositions[i], lightPositions[i] + glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f));
lightViewMatrices[i * 6 + 3] = glm::lookAt(lightPositions[i], lightPositions[i] + glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f));
lightViewMatrices[i * 6 + 4] = glm::lookAt(lightPositions[i], lightPositions[i] + glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, 1.0f, 0.0f));
lightViewMatrices[i * 6 + 5] = glm::lookAt(lightPositions[i], lightPositions[i] + glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, 1.0f, 0.0f));
for (int ii = 0; ii < 6; ii++)
{
shadowMatrices[i * 6 + ii] = biasMatrix * mLightProjection * lightViewMatrices[i * 6 + ii] * glm::inverse(mView);
}
}
}
// render scene to shadow cube maps ---------------------------------------------------------------------------------------
if (appSet.calculateShadows && !ShowSSAO)
{
glViewport(0, 0, SHADOW_CUBE_MAP_SIZE, SHADOW_CUBE_MAP_SIZE);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBO);
glDrawBuffers(0, NULL); glReadBuffer(GL_NONE);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, 0, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, 0, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0);
glMatrixMode(GL_PROJECTION);
glLoadMatrixf((const GLfloat*)&lightProjectionMatrix);
glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glCullFace(GL_FRONT);
for (GLushort l = 0; l < lightsModel.pLightObj.size(); ++l)
{
lightObject *lObj = &lightsModel.pLightObj[l];
if (gFrustum.sphereInFrustum(lObj->position, lObj->radius))
{
// For each side of cubemap
for (GLushort i = 0; i < 6; ++i)
{
glFramebufferTextureLayerEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, ShadowCubeMaps, 0, i);
glClear(GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf((const GLfloat*)&lightViewMatrices[i]);
scene.drawFBO(lObj);
}
}
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
glCullFace(GL_BACK);
glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glViewport(0, 0, windowWidth, windowHeight);
}
glm::mat4 projectionBiasMatrixInverse = glm::inverse(mProjection) * biasMatrixInverse;
// calculate screen space ambient occlusion -------------------------------------------------------------------------------
if (appSet.calculateSSAO || ShowSSAO)
{
glViewport(0, 0, windowWidth / 2, windowHeight / 2);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBO);
glDrawBuffers(1, Buffers); glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, SSAOBuffers[0], 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, 0, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0);
glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, NormalBuffer);
glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, DepthBuffer);
glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, RotationTexture);
spSSAO.useProgram();
vec2 scale = vec2((float)windowWidth / 2.0f / 64.0f, (float)windowHeight / 2.0f / 64.0f);
spSSAO.SetUniform("Scale", scale);
spSSAO.SetUniform("ProjectionBiasMatrixInverse", projectionBiasMatrixInverse);
glBegin(GL_QUADS);
glVertex2f(0.0f, 0.0f);
glVertex2f(1.0f, 0.0f);
glVertex2f(1.0f, 1.0f);
glVertex2f(0.0f, 1.0f);
glEnd();
glUseProgram(0);
glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glViewport(0, 0, windowWidth, windowHeight);
}
// set lights positions ---------------------------------------------------------------------------------------------------
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf((const GLfloat*)&mView);
numPointLights = 0, numSpotLights = 0; GLushort dorovnani = 0;
for (GLushort i = 0; i < lightsModel.pLightObj.size(); i++)
{
lightObject *obj = &lightsModel.pLightObj[i];
if (gFrustum.sphereInFrustum(obj->position, obj->radius) && obj->lightOn)
{
GLushort result = i - dorovnani;
if (result < 8) // max bodových světel ve scéně
{
glLightfv(GL_LIGHT0 + result, GL_POSITION, (const GLfloat*)&vec4(obj->position, 1.0f));
glLightfv(GL_LIGHT0 + result, GL_AMBIENT, (const GLfloat*)&vec4(obj->colorDiffuse * 0.25f, 1.0f));
glLightfv(GL_LIGHT0 + result, GL_DIFFUSE, (const GLfloat*)&vec4(obj->colorDiffuse * 0.75f, 1.0f));
glLightf(GL_LIGHT0 + result, GL_LINEAR_ATTENUATION, 0.3f / (obj->radius / 2));
glLightf(GL_LIGHT0 + result, GL_QUADRATIC_ATTENUATION, 0.3f / obj->radius);
} numPointLights++;
}
else dorovnani++;
}
// ------------------------------------------------------------------------------------------------------------------------
if (ShowSSAO)
{
// display SSAO -------------------------------------------------------------------------------------------------------
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glColor3f(1.0f, 1.0f, 1.0f);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, SSAOBuffers[0]);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex2f(1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex2f(1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f, 1.0f);
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
}
else
{
// calculate lighting -------------------------------------------------------------------------------------------------
glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, ColorBuffers[0]);
glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, NormalBuffer);
glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, DepthBuffer);
if (appSet.calculateSSAO)glActiveTexture(GL_TEXTURE3), glBindTexture(GL_TEXTURE_2D, SSAOBuffers[0]);
glActiveTexture(GL_TEXTURE4); glBindTexture(GL_TEXTURE_2D_ARRAY_EXT, ShadowCubeMaps);
spDefLighting.useProgram();
spDefLighting.SetUniform("ProjectionBiasMatrixInverse", projectionBiasMatrixInverse);
// if (CalculateShadows) glUniformMatrix4fv(DeferredLighting.UniformLocations[1], 1, GL_FALSE, (const GLfloat*)&glm::inverse(mView));
if (appSet.calculateShadows) spDefLighting.SetUniform("ViewMatrixInverse", glm::inverse(mView));
// if (CalculateShadows) glUniformMatrix4fv(DeferredLighting.UniformLocations[2], 24, GL_FALSE, (float*)shadowMatrices);
if (appSet.calculateShadows) spDefLighting.SetUniform("ShadowMatrices", shadowMatrices, lightsModel.pLightObj.size() * 6);
spDefLighting.SetUniform("CalculateSSAO", appSet.calculateSSAO);
spDefLighting.SetUniform("CalculateShadows", appSet.calculateShadows);
glBegin(GL_QUADS);
glVertex2f(0.0f, 0.0f);
glVertex2f(1.0f, 0.0f);
glVertex2f(1.0f, 1.0f);
glVertex2f(0.0f, 1.0f);
glEnd();
glUseProgram(0);
glActiveTexture(GL_TEXTURE4); glBindTexture(GL_TEXTURE_2D_ARRAY_EXT, 0);
if (appSet.calculateSSAO)glActiveTexture(GL_TEXTURE3), glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, 0);
}
OrthoMode();
}
shader SSAO vert
#version 120
uniform vec2 Scale;
void main()
{
gl_TexCoord[0] = gl_Vertex;
gl_TexCoord[1] = vec4(gl_Vertex.xy * Scale, gl_Vertex.zw);
gl_Position = gl_Vertex * 2.0 - 1.0;
}
frag
#version 120
uniform sampler2D NormalBuffer, DepthBuffer, RotationTexture;
uniform mat4x4 ProjectionBiasMatrixInverse;
uniform vec2 Samples[16];
void main()
{
float Depth = texture2D(DepthBuffer, gl_TexCoord[0].st).r;
if(Depth < 1.0)
{
vec3 Normal = normalize(texture2D(NormalBuffer, gl_TexCoord[0].st).rgb * 2.0 - 1.0);
vec4 Position = ProjectionBiasMatrixInverse * vec4(gl_TexCoord[0].st, Depth, 1.0);
Position.xyz /= Position.w;
if(dot(Normal, Position.xyz) > 0.0)
{
Normal = -Normal;
}
vec4 ScaleRotationVector = normalize(texture2D(RotationTexture, gl_TexCoord[1].st) * 2.0 - 1.0) / length(Position.xyz);
mat2x2 ScaleRotationMatrix = mat2x2(ScaleRotationVector.xy, ScaleRotationVector.zw);
float SSAO = 0.0;
for(int i = 0; i < 16; i++)
{
vec2 TexCoord = clamp(ScaleRotationMatrix * Samples[i] + gl_TexCoord[0].st, 0.0, 0.999999);
float depth = texture2D(DepthBuffer, TexCoord).r;
vec4 position = ProjectionBiasMatrixInverse * vec4(TexCoord, depth, 1.0);
position.xyz /= position.w;
vec3 P2P = position.xyz - Position.xyz;
float Distance2 = dot(P2P, P2P);
float Weight = 1.0 - Distance2 * 0.25;
if(Weight > 0.0)
{
P2P /= sqrt(Distance2);
float NdotP2P = dot(Normal, P2P);
if(NdotP2P > 0.342)
{
SSAO += NdotP2P * Weight;
}
}
}
gl_FragColor = vec4(vec3(1.0 - SSAO * 0.0625), 1.0);
}
else
{
gl_FragColor = vec4(vec3(0.0), 1.0);
}
}
deffered ligthing shader
#version 120
void main()
{
gl_TexCoord[0] = gl_Vertex;
gl_Position = gl_Vertex * 2.0 - 1.0;
}
frag
#version 120
#extension GL_EXT_texture_array : enable
uniform sampler2D ColorBuffer, NormalBuffer, DepthBuffer, SSAOBuffer;
uniform sampler2DArrayShadow ShadowCubeMaps;
uniform mat4x4 ProjectionBiasMatrixInverse, ViewMatrixInverse, ShadowMatrices[24];
uniform bool CalculateSSAO, CalculateShadows;
const int MAX_POINT_LIGHTS = 8;
void main()
{
gl_FragColor = texture2D(ColorBuffer, gl_TexCoord[0].st);
float Depth = texture2D(DepthBuffer, gl_TexCoord[0].st).r;
if (Depth < 1.0)
{
vec3 Normal = normalize(texture2D(NormalBuffer, gl_TexCoord[0].st).rgb * 2.0 - 1.0);
vec4 Position = ProjectionBiasMatrixInverse * vec4(gl_TexCoord[0].st, Depth, 1.0);
Position /= Position.w;
float SSAO = CalculateSSAO ? texture2D(SSAOBuffer, gl_TexCoord[0].st).r : 1.0;
vec3 Light = vec3(0.0);
// vec3 Light = vec3(1,1,1);
if (lighting)
{
for (int i = 0; i < MAX_POINT_LIGHTS; i++)
// for(int i = 0; i < 4; i++)
{
vec3 LightDirection = gl_LightSource[i].position.xyz - Position.xyz;
float LightDistance2 = dot(LightDirection, LightDirection);
float LightDistance = sqrt(LightDistance2);
LightDirection /= LightDistance;
float NdotLD = max(dot(Normal, LightDirection), 0.0);
float Attenuation = gl_LightSource[i].constantAttenuation;
Attenuation += gl_LightSource[i].linearAttenuation * LightDistance;
Attenuation += gl_LightSource[i].quadraticAttenuation * LightDistance2;
float Shadow = 1.0;
if (CalculateShadows)
{
LightDirection = (ViewMatrixInverse * vec4(LightDirection, 0.0)).xyz;
float Axis[6];
Axis[0] = -LightDirection.x;
Axis[1] = LightDirection.x;
Axis[2] = -LightDirection.y;
Axis[3] = LightDirection.y;
Axis[4] = -LightDirection.z;
Axis[5] = LightDirection.z;
int MaxAxisID = 0;
for (int ii = 1; ii < 6; ii++)
{
if (Axis[ii] > Axis[MaxAxisID])
{
MaxAxisID = ii;
}
}
int Index = i * 6 + MaxAxisID;
vec4 ShadowTexCoord = ShadowMatrices[Index] * vec4(Position.xyz, 1.0);
ShadowTexCoord.xyz /= ShadowTexCoord.w;
ShadowTexCoord.w = ShadowTexCoord.z;
ShadowTexCoord.z = float(Index);
Shadow = shadow2DArray(ShadowCubeMaps, ShadowTexCoord).r;
}
Light += (gl_LightSource[i].ambient.rgb * SSAO + gl_LightSource[i].diffuse.rgb * NdotLD * Shadow) / Attenuation;
}
}
gl_FragColor.rgb *= Light;
}
}
|
|
|