.[ ČeskéHry.cz ].
Problém překreslení scény při zapnutí SSAO nebo stínů

 
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> 3D API / 3D Enginy
Zobrazit předchozí téma :: Zobrazit následující téma  
Autor Zpráva
Mivoj



Založen: 11. 12. 2012
Příspěvky: 32

PříspěvekZaslal: 11. leden 2015, 15:48:54    Předmět: Problém překreslení scény při zapnutí SSAO nebo stínů Odpovědět s citátem

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;
   }
}
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Vilem Otte



Založen: 18. 09. 2007
Příspěvky: 462
Bydliště: Znojmo - Sedlesovice, Kravi Hora

PříspěvekZaslal: 11. leden 2015, 16:23:02    Předmět: Odpovědět s citátem

Bohužel nemám čas číst do detailu kód, ale:

Zkontroluj zda pro každý frame buffer (a to jak FBO, tak tvůj backbuffer) vždy nastavíš Projection a (Model)View matice - v tom bude velice pravděpodobně chyba.
_________________
Should array indices start at 0 or 1? My compromise of 0.5 was rejected without, I thought, proper consideration.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Odeslat e-mail Zobrazit autorovi WWW stránky
Vilem Otte



Založen: 18. 09. 2007
Příspěvky: 462
Bydliště: Znojmo - Sedlesovice, Kravi Hora

PříspěvekZaslal: 11. leden 2015, 16:24:23    Předmět: Odpovědět s citátem

Bohužel nemám čas číst do detailu kód, ale:

Zkontroluj zda pro každý frame buffer (a to jak FBO, tak tvůj backbuffer) vždy nastavíš Projection a (Model)View matice - v tom bude velice pravděpodobně chyba.
_________________
Should array indices start at 0 or 1? My compromise of 0.5 was rejected without, I thought, proper consideration.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Odeslat e-mail Zobrazit autorovi WWW stránky
Mivoj



Založen: 11. 12. 2012
Příspěvky: 32

PříspěvekZaslal: 17. leden 2015, 21:17:31    Předmět: Odpovědět s citátem

Aha asi zřejně posílám do light shaderu špatnou world pozici pro světla. Tudíž jestli by jste mně mohli vysvětlit, jak správně tu pozici získat, protože deffered redndering je zatím pro mně španělská vesnice oproti forwardu, kde mám pozici získanou z modelovej matice a vertexů.
Tak jaký je postup?
1. ze shaderu pro geometii získám tu pozici stejně jak u forwardu a přes frag shader to pošlu do FBO jako data pro texturu
2. načtu data pomocí
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, positionBuffer, 0);
3. přes aktivovanou texturu to pošlu do frag light shaderu a přes funkci
vec3 worldPos = texture(positionMap, gl_FragCoord.xy / gScreenSize).xyz;
získám world pozici fragmentu pro světlo a to je zhruba vše?
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Mivoj



Založen: 11. 12. 2012
Příspěvky: 32

PříspěvekZaslal: 31. leden 2015, 14:55:03    Předmět: Odpovědět s citátem

Tak už jsem to vyřešil a trochu upravil a už mně funguje deferred rendering tak jak má. World pozice pro fragment mně tedy jde, takže světla se stíny jsou na svém místě. Budu ještě řešit ssao, ale ted mám ještě problém, aby mně fungovalo vyhlazovaní fxaa od nvidie. FXAA jsem zkoušel pro forward tam mně podle příkladu od nvidie funguje, ale zatím mně nejde rozjet pro deferred. Stačilo by mně vysvětlit hrubý postup jak to impletovat pro defered. Musí být pro fxaa samostatný framebuffer i s depth renderbufferem?
Mělo by se to fbo bindnout jen na light pass, tedy kde mám shader pro světla i stíny?
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Zobrazit příspěvky z předchozích:   
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> 3D API / 3D Enginy Časy uváděny v GMT + 1 hodina
Strana 1 z 1

 
Přejdi na:  
Nemůžete odesílat nové téma do tohoto fóra
Nemůžete odpovídat na témata v tomto fóru
Nemůžete upravovat své příspěvky v tomto fóru
Nemůžete mazat své příspěvky v tomto fóru
Nemůžete hlasovat v tomto fóru


Powered by phpBB © 2001, 2005 phpBB Group


Vzhled udelal powermac
Styl "vykraden" z phpBB stylu MonkiDream - upraveno by rezna