Game Development Community

Refracting refractions?

by Josh Moore · in Torque Game Engine Advanced · 04/23/2006 (11:45 pm) · 1 replies

Would it be possible to have refractive materials refract other refractive materials that are behind them? I know performance would be horrible if the refraction buffer is built too many times, but stuff like this just looks silly.

img212.imageshack.us/img212/3502/screenshot001000040fr.png

I was thinking that if you built a back-to-front BSP tree for the refraction objects that overlap each other, you'd beable to copy them to the refraction buffer after each(group) is rendered. I realise this might kill performance with too many overlapped objects, so one could limit the amout of calls to copyBBToSfxBuff to say 3 or 4 total. I'm wondering if someone that knows more about TSE rendering could tell me if this is a bad idea or not.

Here's some pseudo-code to give a better idea of what I'm thinking.

void SceneState::renderCurrentImages()
{
...........

   // Render refraction images
   //-----------------------------
   if( mRefractionImages.size() &&
       !gClientSceneGraph->isReflectPass() )
   {
      // set ortho projection matrix
      MatrixF proj = GFX->getProjectionMatrix();
      MatrixF newMat(true);
      GFX->setProjectionMatrix( newMat );
      GFX->pushWorldMatrix();
      GFX->setWorldMatrix( newMat );

      // copy sfx back buffer out to tex
      GFX->copyBBToSfxBuff();

      // restore projection matrix
      GFX->setProjectionMatrix( proj );
      GFX->popWorldMatrix();

      buildRefractiveBSP(); // Only adds overlapped refractive images to the tree(and removes them from mRefractionImages?)

      // render overlapped refraction surfaces
      for (i = 0; i < mMultipleRefractionImages.size(); i++)
      {
         for(U32 s; s < mMultipleRefractionImages[i].images.size(); s++) {
            renderImage( this,  mMultipleRefractionImages[i].images[s]);
         }

         set projection and world matrix
         copyBBToSfxBuff();
         restore projection matrix
      }

      // render refraction surfaces
      for (i = 0; i < mRefractionImages.size(); i++)
      {
         renderImage( this, mRefractionImages[i] );
      }
   }

...........
}

#1
04/25/2006 (7:04 am)
It seems possible, but performance is a concern. A quick way to determinate how slow things will become is calling copyBBToSfxBuff() after each refraction image is drawn (worst case) and seeing how much the framerate loss you get. Depending on that, you can determinate your approach. If there isn't much of a loss, it could be possible to use sort the refraction images just like transluscent images are sorted, and update the sfx buffer after each one. Otherwise a more complex sorting, like the one you propose, would be required to minimuze the refraction buffer updates.