Var *AdvancedLightBufferConditioner::_conditionOutput( Var *unconditionedOutput, MultiLine *meta )
{
   Var *conditionedOutput = new Var;

   if(GFX->getAdapterType() == OpenGL)
      conditionedOutput->setType("vec4");
   else
      conditionedOutput->setType("float4");

   DecOp *outputDecl = new DecOp(conditionedOutput);
   if(mColorFormat == RGB)
   {
      conditionedOutput->setName("rgbLightInfoOut");

      // If this is a 16 bit integer format, scale up/down the values. All other
      // formats just write out the full 0..1
      if(getBufferFormat() == GFXFormatR16G16B16A16)
         meta->addStatement( new GenOp( "   @ = max(4.0, (float4(lightColor, specular) * NL_att + float4(bufferSample.rgb, 0.0)) / 4.0);\r\n", outputDecl ) );
      else
         meta->addStatement( new GenOp( "   @ = float4(lightColor, 0) * NL_att + float4(bufferSample.rgb, specular);\r\n", outputDecl ) );
   }
   else
   {
      // Input u'v' assumed to be scaled
      conditionedOutput->setName("luvLightInfoOut");
      meta->addStatement( new GenOp( "   @ = float4( lerp(bufferSample.xy, lightColor.xy, saturate(NL_att / bufferSample.z) * 0.5),\r\n", outputDecl ) );
      meta->addStatement( new GenOp( "               bufferSample.z + NL_att, bufferSample.w + saturate(specular * NL_att) );\r\n" ) );
   }

   return conditionedOutput;
}
Пример #2
0
    void
    BufferAdapter::performAction(GLSourceBuffer theSourceBuffer) {
        GLenum myFormat = getBufferFormat(theSourceBuffer);
        if (theSourceBuffer == FRAME_BUFFER) {
            glReadBuffer(GL_BACK);
        }

        alloc(_myWidth * _myHeight * _myComponents);
        if (_myComponents != 4) {
            glPixelStorei(GL_PACK_ALIGNMENT, 1);
        }
        glReadPixels(0, 0, _myWidth, _myHeight, myFormat, GL_UNSIGNED_BYTE, _myData.begin());
    }
Var *AdvancedLightBufferConditioner::_unconditionInput( Var *conditionedInput, MultiLine *meta )
{
   if(mColorFormat == RGB)
   {
      if(getBufferFormat() == GFXFormatR16G16B16A16)
         meta->addStatement( new GenOp( "   lightColor = @.rgb * 4.0;\r\n", conditionedInput ) );
      else
         meta->addStatement( new GenOp( "   lightColor = @.rgb;\r\n", conditionedInput ) );
      meta->addStatement( new GenOp( "   NL_att = dot(@.rgb, float3(0.3576, 0.7152, 0.1192));\r\n", conditionedInput ) );
   }
   else
   {
      meta->addStatement( new GenOp( "   // TODO: This clamps HDR values.\r\n" ) );
      meta->addStatement( new GenOp( "   NL_att = @.b;\r\n", conditionedInput ) );
      meta->addStatement( new GenOp( "   lightColor = DecodeLuv(float3(saturate(NL_att), @.rg * 0.62));\r\n", conditionedInput ) );
   }
   meta->addStatement( new GenOp( "   specular = @.a;\r\n", conditionedInput ) );

   return NULL;
}
Пример #4
0
HDRStageDataTransitPtr HDRStage::setupStageData(Int32 iPixelWidth,
                                                Int32 iPixelHeight)
{
    HDRStageDataTransitPtr returnValue = HDRStageData::createLocal();

    if(returnValue == NULL)
        return returnValue;

    OSG::Thread::setCurrentLocalFlags();

    // Scene Target

    FrameBufferObjectUnrecPtr pSceneFBO    = FrameBufferObject::createLocal();

    RenderBufferUnrecPtr      pDepthBuffer = RenderBuffer     ::createLocal();

    pDepthBuffer->setInternalFormat(GL_DEPTH_COMPONENT24   );

        
    TextureObjChunkUnrecPtr pSceneTex     = TextureObjChunk::createLocal();
    TextureEnvChunkUnrecPtr pSceneTexEnv  = TextureEnvChunk::createLocal();
    ImageUnrecPtr           pImg          = Image          ::createLocal();
    
    pImg->set(Image::OSG_RGB_PF, 
              iPixelWidth, 
              iPixelHeight,
              1,
              1,
              1,
              0.0,
              0,
              Image::OSG_FLOAT32_IMAGEDATA,
              false);
    
    pSceneTex   ->setImage         (pImg             ); 
    pSceneTex   ->setMinFilter     (GL_LINEAR        );
    pSceneTex   ->setMagFilter     (GL_LINEAR        );
    pSceneTex   ->setWrapS         (GL_CLAMP_TO_EDGE );
    pSceneTex   ->setWrapT         (GL_CLAMP_TO_EDGE );
    pSceneTex   ->setInternalFormat(getBufferFormat());

    pSceneTexEnv->setEnvMode       (GL_REPLACE       );
    
    TextureBufferUnrecPtr pSceneTexBuffer   = TextureBuffer::createLocal();
    
    pSceneTexBuffer->setTexture(pSceneTex);
    

    
    pSceneFBO->setSize(iPixelWidth, iPixelHeight);
    
    pSceneFBO->setColorAttachment(pSceneTexBuffer, 0);
    pSceneFBO->setDepthAttachment(pDepthBuffer      );
    
    pSceneFBO->editMFDrawBuffers()->push_back(GL_COLOR_ATTACHMENT0_EXT);
    
    setRenderTarget(pSceneFBO);
    



    // Shrink Target (w/2, h/2)

    FrameBufferObjectUnrecPtr pShrinkFBO     = FrameBufferObject::createLocal();

    TextureObjChunkUnrecPtr   pShrinkTex     = TextureObjChunk::createLocal();
    TextureEnvChunkUnrecPtr   pShrinkTexEnv  = TextureEnvChunk::createLocal();
                              pImg           = Image          ::createLocal();
    
    pImg->set(Image::OSG_RGB_PF, 
              iPixelWidth  / 2, 
              iPixelHeight / 2,
              1,
              1,
              1,
              0.0,
              0,
              Image::OSG_FLOAT32_IMAGEDATA,
              false);
    
    pShrinkTex   ->setImage         (pImg             ); 
    pShrinkTex   ->setMinFilter     (GL_LINEAR        );
    pShrinkTex   ->setMagFilter     (GL_LINEAR        );
    pShrinkTex   ->setWrapS         (GL_CLAMP_TO_EDGE );
    pShrinkTex   ->setWrapT         (GL_CLAMP_TO_EDGE );
    pShrinkTex   ->setInternalFormat(getBufferFormat());

    pShrinkTexEnv->setEnvMode       (GL_REPLACE       );
    
    TextureBufferUnrecPtr pShrinkTexBuffer   = TextureBuffer::createLocal();
    
    pShrinkTexBuffer->setTexture(pShrinkTex);
    

    
    pShrinkFBO->setSize(iPixelWidth / 2, iPixelHeight / 2);
    
    pShrinkFBO->setColorAttachment(pShrinkTexBuffer, 0);
    
    pShrinkFBO->editMFDrawBuffers()->push_back(GL_COLOR_ATTACHMENT0_EXT);
    
    returnValue->setShrinkRenderTarget(pShrinkFBO);





    // blur (w/4, h/4)


    FrameBufferObjectUnrecPtr pBlurFBO     = FrameBufferObject::createLocal();

    TextureObjChunkUnrecPtr   pBlurTex1    = TextureObjChunk  ::createLocal();
    TextureEnvChunkUnrecPtr   pBlurTex1Env = TextureEnvChunk  ::createLocal();
    
    
    pImg = Image::createLocal();
    
    pImg->set(Image::OSG_RGB_PF, 
              iPixelWidth  / 4,
              iPixelHeight / 4,
              1,
              1,
              1,
              0.0,
              0,
              Image::OSG_FLOAT32_IMAGEDATA,
              false);
    
    pBlurTex1   ->setImage         (pImg             ); 
    pBlurTex1   ->setMinFilter     (GL_LINEAR        );
    pBlurTex1   ->setMagFilter     (GL_LINEAR        );
    pBlurTex1   ->setWrapS         (GL_CLAMP_TO_EDGE );
    pBlurTex1   ->setWrapT         (GL_CLAMP_TO_EDGE );
    pBlurTex1   ->setInternalFormat(getBufferFormat());

    pBlurTex1Env->setEnvMode       (GL_REPLACE       );
    
    TextureBufferUnrecPtr pBlurTexBuffer1 = TextureBuffer::createLocal();
    
    pBlurTexBuffer1->setTexture(pBlurTex1);
    
    
    
    TextureObjChunkUnrecPtr pBlurTex2    = TextureObjChunk::createLocal();
    TextureEnvChunkUnrecPtr pBlurTex2Env = TextureEnvChunk::createLocal();
    
    
    pImg = Image::createLocal();

    pImg->set(Image::OSG_RGB_PF, 
              iPixelWidth  / 4,
              iPixelHeight / 4,
              1,
              1,
              1,
              0.0,
              0,
              Image::OSG_FLOAT32_IMAGEDATA,
              false);
    
    pBlurTex2   ->setImage         (pImg             ); 
    pBlurTex2   ->setMinFilter     (GL_LINEAR        );
    pBlurTex2   ->setMagFilter     (GL_LINEAR        );
    pBlurTex2   ->setWrapS         (GL_CLAMP_TO_EDGE );
    pBlurTex2   ->setWrapT         (GL_CLAMP_TO_EDGE );
    pBlurTex2   ->setInternalFormat(getBufferFormat());

    pBlurTex2Env->setEnvMode       (GL_REPLACE       );
    
    TextureBufferUnrecPtr pBlurTexBuffer2 = TextureBuffer::createLocal();

    pBlurTexBuffer2->setTexture(pBlurTex2);


    pBlurFBO->setSize(iPixelWidth  / 4,
                      iPixelHeight / 4);
    
    pBlurFBO->setColorAttachment(pBlurTexBuffer1,  0);
    pBlurFBO->setColorAttachment(pBlurTexBuffer2,  1);
    
    returnValue->setBlurRenderTarget(pBlurFBO);


    // general mat chunk


    MaterialChunkUnrecPtr pMatChunk = MaterialChunk::createLocal();
        
    pMatChunk->setLit(false);




    // tone map material

    ChunkMaterialUnrecPtr    pTonemapMat  = ChunkMaterial  ::createLocal();
    
    pTonemapMat->addChunk(pMatChunk         );
    pTonemapMat->addChunk(pSceneTex,       0);
    pTonemapMat->addChunk(pSceneTexEnv,    0);
    pTonemapMat->addChunk(pBlurTex1,       1);
    pTonemapMat->addChunk(pBlurTex1Env,    1);

    SimpleSHLChunkUnrecPtr pTonemapShader = generateHDRFragmentProgram();
    
    pTonemapShader->addUniformVariable("sceneTex",     0);
    pTonemapShader->addUniformVariable("blurTex",      1);
    pTonemapShader->addUniformVariable("blurAmount",   getBlurAmount  ());
    pTonemapShader->addUniformVariable("exposure",     getExposure    ());
    pTonemapShader->addUniformVariable("effectAmount", getEffectAmount());
    pTonemapShader->addUniformVariable("gamma",        getGamma       ());
    
    pTonemapMat->addChunk(pTonemapShader, 0);
    
    returnValue->setToneMappingMaterial(pTonemapMat);




    // Shrink material

    ChunkMaterialUnrecPtr pShrinkMat = ChunkMaterial::createLocal();
    
    pShrinkMat->addChunk(pMatChunk   );
    
    pShrinkMat->addChunk(pSceneTex,     0);
    pShrinkMat->addChunk(pSceneTexEnv,  0);

    SimpleSHLChunkUnrecPtr pShrinkShader = generate2DShrinkHalfFilterFP();
        
    pShrinkShader->addUniformVariable("inputTex", 0);
    
    pShrinkMat->addChunk(pShrinkShader, 0);
    
    returnValue->setShrinkMaterial(pShrinkMat);




    // Blur material

    ChunkMaterialUnrecPtr pBlurMat = ChunkMaterial::createLocal();
    
    pBlurMat->addChunk(pMatChunk   );
    
    pBlurMat->addChunk(pShrinkTex,    0);
    pBlurMat->addChunk(pShrinkTexEnv, 0);
    pBlurMat->addChunk(pBlurTex1,     1);
    pBlurMat->addChunk(pBlurTex1Env,  1);
    pBlurMat->addChunk(pBlurTex2,     2);
    pBlurMat->addChunk(pBlurTex2Env,  2);

    pBlurMat->addChunk(pShrinkShader, 0);
    
    returnValue->setBlurMaterial(pBlurMat);


    // generate blur fragment programs
    SimpleSHLChunkUnrecPtr pHBlurShader = 
        generate1DConvolutionFilterFP(getBlurWidth(), 
                                      false, 
                                      true, 
                                      iPixelWidth  / 2, 
                                      iPixelHeight / 2);
    
   
    pHBlurShader->addUniformVariable("inputTex", 0);

    returnValue->setHBlurShader(pHBlurShader);

    
    
    // VBlur Override


    SimpleSHLChunkUnrecPtr pVBlurShader = 
        generate1DConvolutionFilterFP(getBlurWidth(),  
                                      true, 
                                      true, 
                                      iPixelWidth  / 2, 
                                      iPixelHeight / 2);
    
    pVBlurShader->addUniformVariable("inputTex", 1);
    
    returnValue->setVBlurShader(pVBlurShader);

    OSG::Thread::resetCurrentLocalFlags();

    Thread::getCurrentChangeList()->commitChanges();

    return returnValue;
}
Пример #5
0
Var* GBufferConditionerGLSL::_unconditionInput( Var *conditionedInput, MultiLine *meta )
{
   Var *retVar = new Var;
   retVar->setType("float4");
   retVar->setName("_gbUnconditionedInput");
   LangElement *outputDecl = new DecOp( retVar );

   switch(mNormalStorageType)
   {
      case CartesianXYZ:
         meta->addStatement( new GenOp( "   // g-buffer unconditioner: float4(normal.xyz, depth)\r\n" ) );
         meta->addStatement( new GenOp( "   @ = float4(@, @.a);\r\n", outputDecl, 
            _posnegDecode(new GenOp("@.xyz", conditionedInput)), conditionedInput ) );
         break;

      case CartesianXY:
         meta->addStatement( new GenOp( "   // g-buffer unconditioner: float4(normal.xy, depth Hi + z-sign, depth Lo)\r\n" ) );
         meta->addStatement( new GenOp( "   @ = float4(@, @.a);\r\n", outputDecl, 
            _posnegDecode(new GenOp("@.xyz", conditionedInput)), conditionedInput ) );
         meta->addStatement( new GenOp( "   @.z *= sqrt(1.0 - dot(@.xy, @.xy));\r\n", retVar, retVar, retVar ) );
         break;

      case Spherical:
         meta->addStatement( new GenOp( "   // g-buffer unconditioner: float4(normal.theta, normal.phi, depth Hi, depth Lo)\r\n" ) );
         meta->addStatement( new GenOp( "   float2 spGPUAngles = @;\r\n", _posnegDecode(new GenOp("@.xy", conditionedInput)) ) );
         meta->addStatement( new GenOp( "   float2 sincosTheta;\r\n" ) );
         meta->addStatement( new GenOp( "   sincos(spGPUAngles.x * 3.14159265358979323846f, sincosTheta.x, sincosTheta.y);\r\n" ) );
         meta->addStatement( new GenOp( "   float2 sincosPhi = float2(sqrt(1.0 - spGPUAngles.y * spGPUAngles.y), spGPUAngles.y);\r\n" ) );
         meta->addStatement( new GenOp( "   @ = float4(sincosTheta.y * sincosPhi.x, sincosTheta.x * sincosPhi.x, sincosPhi.y, @.a);\r\n", outputDecl, conditionedInput ) );
         break;

      case LambertAzimuthal:
         // Note we're casting to half to use partial precision
         // sqrt which is much faster on older Geforces while
         // still being acceptable for normals.
         //      
         meta->addStatement( new GenOp( "   // g-buffer unconditioner: float4(normal.X, normal.Y, depth Hi, depth Lo)\r\n" ) );
         meta->addStatement( new GenOp( "   float2 _inpXY = @;\r\n", _posnegDecode(new GenOp("@.xy", conditionedInput)) ) );
         meta->addStatement( new GenOp( "   float _xySQ = dot(_inpXY, _inpXY);\r\n" ) );
         meta->addStatement( new GenOp( "   @ = float4( sqrt(half(1.0 - (_xySQ / 4.0))) * _inpXY, -1.0 + (_xySQ / 2.0), @.a).xzyw;\r\n", outputDecl, conditionedInput ) );
         break;
   }

   // Recover depth from encoding
   if(mNormalStorageType != CartesianXYZ)
   {
      const U64 maxValPerChannel = 1 << mBitsPerChannel;
      meta->addStatement( new GenOp( "   \r\n   // Decode depth\r\n" ) );
      meta->addStatement( new GenOp( avar( "   @.w = dot( @.zw, float2(1.0, 1.0/%llu.0));\r\n", maxValPerChannel - 1 ), 
         retVar, conditionedInput ) );
   }


   AssertFatal( retVar != NULL, avar( "Cannot uncondition input from buffer format: %s", GFXStringTextureFormat[getBufferFormat()] ) );
   return retVar; 
}
Пример #6
0
Var* GBufferConditionerGLSL::_conditionOutput( Var *unconditionedOutput, MultiLine *meta )
{
   Var *retVar = new Var;
   retVar->setType("float4");
   retVar->setName("_gbConditionedOutput");
   LangElement *outputDecl = new DecOp( retVar );

   switch(mNormalStorageType)
   {
      case CartesianXYZ:
         meta->addStatement( new GenOp( "   // g-buffer conditioner: float4(normal.xyz, depth)\r\n" ) );
         meta->addStatement( new GenOp( "   @ = float4(@, @.a);\r\n", outputDecl, 
            _posnegEncode(new GenOp("@.xyz", unconditionedOutput)), unconditionedOutput ) );
         break;

      case CartesianXY:
         meta->addStatement( new GenOp( "   // g-buffer conditioner: float4(normal.xy, depth Hi + z-sign, depth Lo)\r\n" ) );
         meta->addStatement( new GenOp( "   @ = float4(@, @.a);", outputDecl, 
            _posnegEncode(new GenOp("float3(@.xy, sign(@.z))", unconditionedOutput, unconditionedOutput)), unconditionedOutput ) );
         break;

      case Spherical:
         meta->addStatement( new GenOp( "   // g-buffer conditioner: float4(normal.theta, normal.phi, depth Hi, depth Lo)\r\n" ) );
         meta->addStatement( new GenOp( "   @ = float4(@, 0.0, @.a);\r\n", outputDecl, 
            _posnegEncode(new GenOp("float2(atan2(@.y, @.x) / 3.14159265358979323846f, @.z)", unconditionedOutput, unconditionedOutput, unconditionedOutput ) ), 
            unconditionedOutput ) );

         // HACK: This fixes the noise present when using a floating point
         // gbuffer on Geforce cards and the "flat areas unlit" issues.
         //
         // We need work around atan2() above to fix this issue correctly
         // without the extra overhead of this test.
         //
         meta->addStatement( new GenOp( "   if ( abs( dot( @.xyz, float3( 0.0, 0.0, 1.0 ) ) ) > 0.999f ) @ = float4( 0, 1 * sign( @.z ), 0, @.a );\r\n", 
            unconditionedOutput, retVar, unconditionedOutput, unconditionedOutput ) );
         break;

      case LambertAzimuthal:
         //http://en.wikipedia.org/wiki/Lambert_azimuthal_equal-area_projection
         //
         // Note we're casting to half to use partial precision
         // sqrt which is much faster on older Geforces while
         // still being acceptable for normals.
         //
         meta->addStatement( new GenOp( "   // g-buffer conditioner: float4(normal.X, normal.Y, depth Hi, depth Lo)\r\n" ) );
         meta->addStatement( new GenOp( "   @ = float4(@, 0.0, @.a);\r\n", outputDecl, 
            _posnegEncode(new GenOp("sqrt(half(2.0/(1.0 - @.y))) * half2(@.xz)", unconditionedOutput, unconditionedOutput)), 
            unconditionedOutput ) );
         break;
   }

   // Encode depth into two channels
   if(mNormalStorageType != CartesianXYZ)
   {
      const U64 maxValPerChannel = 1 << mBitsPerChannel;
      meta->addStatement( new GenOp( "   \r\n   // Encode depth into hi/lo\r\n" ) );
      meta->addStatement( new GenOp( avar( "   float2 _tempDepth = frac(@.a * float2(1.0, %llu.0));\r\n", maxValPerChannel - 1 ), 
         unconditionedOutput ) );
      meta->addStatement( new GenOp( avar( "   @.zw = _tempDepth.xy - _tempDepth.yy * float2(1.0/%llu.0, 0.0);\r\n\r\n", maxValPerChannel - 1 ), 
         retVar ) );
   }

   AssertFatal( retVar != NULL, avar( "Cannot condition output to buffer format: %s", GFXStringTextureFormat[getBufferFormat()] ) );
   return retVar; 
}
Пример #7
0
Var* GBufferConditionerGLSL::_unconditionInput( Var *conditionedInput, MultiLine *meta )
{
   Var *retVar = new Var;
   retVar->setType("vec4");
   retVar->setName("_gbUnconditionedInput");
   LangElement *outputDecl = new DecOp( retVar );

   switch(mNormalStorageType)
   {
      case CartesianXYZ:
         meta->addStatement( new GenOp( "   // g-buffer unconditioner: vec4(normal.xyz, depth)\r\n" ) );
         meta->addStatement( new GenOp( "   @ = vec4(@, @.a);\r\n", outputDecl, 
            _posnegDecode(new GenOp("@.xyz", conditionedInput)), conditionedInput ) );
         break;

      case CartesianXY:
         meta->addStatement( new GenOp( "   // g-buffer unconditioner: vec4(normal.xy, depth Hi + z-sign, depth Lo)\r\n" ) );
         meta->addStatement( new GenOp( "   @ = vec4(@, @.a);\r\n", outputDecl, 
            _posnegDecode(new GenOp("@.xyz", conditionedInput)), conditionedInput ) );
         meta->addStatement( new GenOp( "   @.z *= sqrt(1.0 - dot(@.xy, @.xy));\r\n", retVar, retVar, retVar ) );
         break;

      case Spherical:
         meta->addStatement( new GenOp( "   // g-buffer unconditioner: vec4(normal.theta, normal.phi, depth Hi, depth Lo)\r\n" ) );
         meta->addStatement( new GenOp( "   vec2 spGPUAngles = @;\r\n", _posnegDecode(new GenOp("@.xy", conditionedInput)) ) );
         meta->addStatement( new GenOp( "   vec2 sincosTheta;\r\n" ) );
         meta->addStatement( new GenOp( "   sincosTheta.x = sin(spGPUAngles.x * 3.14159265358979323846);\r\n" ) );
         meta->addStatement( new GenOp( "   sincosTheta.y = cos(spGPUAngles.x * 3.14159265358979323846);\r\n" ) );
         meta->addStatement( new GenOp( "   vec2 sincosPhi = vec2(sqrt(1.0 - spGPUAngles.y * spGPUAngles.y), spGPUAngles.y);\r\n" ) );
         meta->addStatement( new GenOp( "   @ = vec4(sincosTheta.y * sincosPhi.x, sincosTheta.x * sincosPhi.x, sincosPhi.y, @.a);\r\n", outputDecl, conditionedInput ) );
         break;
   }

   // Recover depth from encoding
   if(mNormalStorageType != CartesianXYZ)
   {
      const U64 maxValPerChannel = 1 << mBitsPerChannel;
      meta->addStatement( new GenOp( "   \r\n   // Decode depth\r\n" ) );
      meta->addStatement( new GenOp( avar( "   @.w = dot( @.zw, vec2(1.0, 1.0/%llu.0));\r\n", maxValPerChannel - 1 ), 
         retVar, conditionedInput ) );
   }


   AssertFatal( retVar != NULL, avar( "Cannot uncondition input from buffer format: %s", GFXStringTextureFormat[getBufferFormat()] ) );
   return retVar; 
}
Пример #8
0
Var* GBufferConditionerGLSL::_conditionOutput( Var *unconditionedOutput, MultiLine *meta )
{
   Var *retVar = new Var;
   retVar->setType("vec4");
   retVar->setName("_gbConditionedOutput");
   LangElement *outputDecl = new DecOp( retVar );

   switch(mNormalStorageType)
   {
      case CartesianXYZ:
         meta->addStatement( new GenOp( "   // g-buffer conditioner: vec4(normal.xyz, depth)\r\n" ) );
         meta->addStatement( new GenOp( "   @ = vec4(@, @.a);\r\n", outputDecl, 
            _posnegEncode(new GenOp("@.xyz", unconditionedOutput)), unconditionedOutput ) );
         break;

      case CartesianXY:
         meta->addStatement( new GenOp( "   // g-buffer conditioner: vec4(normal.xy, depth Hi + z-sign, depth Lo)\r\n" ) );
         meta->addStatement( new GenOp( "   @ = vec4(@, @.a);", outputDecl, 
            _posnegEncode(new GenOp("vec3(@.xy, sign(@.z))", unconditionedOutput, unconditionedOutput)), unconditionedOutput ) );
         break;

      case Spherical:
         meta->addStatement( new GenOp( "   // g-buffer conditioner: vec4(normal.theta, normal.phi, depth Hi, depth Lo)\r\n" ) );
         meta->addStatement( new GenOp( "   @ = vec4(@, 0.0, @.a);\r\n", outputDecl, 
            _posnegEncode(new GenOp("vec2(atan2(@.y, @.x) / 3.14159265358979323846f, @.z)", unconditionedOutput, unconditionedOutput, unconditionedOutput ) ), 
            unconditionedOutput ) );
         break;
   }

   // Encode depth into two channels
   if(mNormalStorageType != CartesianXYZ)
   {
      const U64 maxValPerChannel = 1 << mBitsPerChannel;
      const U64 extraVal = (maxValPerChannel * maxValPerChannel - 1) - (maxValPerChannel - 1) * 2;
      meta->addStatement( new GenOp( "   \r\n   // Encode depth into hi/lo\r\n" ) );
      meta->addStatement( new GenOp( avar( "   vec3 _tempDepth = fract(@.a * vec3(1.0, %llu.0, %llu.0));\r\n", maxValPerChannel - 1, extraVal ), 
         unconditionedOutput ) );
      meta->addStatement( new GenOp( avar( "   @.zw = _tempDepth.xy - _tempDepth.yz * vec2(1.0/%llu.0, 1.0/%llu.0);\r\n\r\n", maxValPerChannel - 1, maxValPerChannel - 1  ), 
         retVar ) );
   }

   AssertFatal( retVar != NULL, avar( "Cannot condition output to buffer format: %s", GFXStringTextureFormat[getBufferFormat()] ) );
   return retVar; 
}
Пример #9
0
LangElement *ConditionerFeature::assignOutput( Var *unconditionedOutput, ShaderFeature::OutputTarget outputTarget /* = ShaderFeature::DefaultTarget*/ )
{
    LangElement *assign;
    MultiLine *meta = new MultiLine;

    meta->addStatement( new GenOp( avar( "\r\n\r\n   // output buffer format: %s\r\n", GFXStringTextureFormat[getBufferFormat()] ) ) );

    // condition the output
    Var *conditionedOutput = _conditionOutput( unconditionedOutput, meta );

    // search for color var
    Var *color = (Var*) LangElement::find( getOutputTargetVarName(outputTarget) );

    if ( !color )
    {
        // create color var
        color = new Var;

        if(GFX->getAdapterType() == OpenGL)
        {
            color->setName( getOutputTargetVarName(outputTarget) );
            color->setType( "vec4" );
            DecOp* colDecl = new DecOp(color);

            assign = new GenOp( "@ = vec4(@)", colDecl, conditionedOutput );
        }
        else
        {
            color->setType( "fragout" );
            color->setName( getOutputTargetVarName(outputTarget) );
            color->setStructName( "OUT" );

            assign = new GenOp( "@ = @", color, conditionedOutput );
        }
    }
    else
    {
        if (GFX->getAdapterType() == OpenGL)
            assign = new GenOp( "@ = vec4(@)", color, conditionedOutput);
        else
            assign = new GenOp( "@ = @", color, conditionedOutput );
    }

    meta->addStatement( new GenOp( "   @;\r\n", assign ) );

    return meta;
}