Exemple #1
0
void ProcessedShaderMaterial::setSceneInfo(SceneRenderState * state, const SceneData& sgData, U32 pass)
{
   PROFILE_SCOPE( ProcessedShaderMaterial_setSceneInfo );

   GFXShaderConstBuffer* shaderConsts = _getShaderConstBuffer(pass);
   ShaderConstHandles* handles = _getShaderConstHandles(pass);

   // Set cubemap stuff here (it's convenient!)
   const Point3F &eyePosWorld = state->getCameraPosition();
   if ( handles->mCubeEyePosSC->isValid() )
   {
      if(_hasCubemap(pass) || mMaterial->mDynamicCubemap)
      {
         Point3F cubeEyePos = eyePosWorld - sgData.objTrans->getPosition();
         shaderConsts->set(handles->mCubeEyePosSC, cubeEyePos);      
      }
   }

   shaderConsts->setSafe(handles->mVisiblitySC, sgData.visibility);

   shaderConsts->setSafe(handles->mEyePosWorldSC, eyePosWorld);   

   if ( handles->mEyePosSC->isValid() )
   {
      MatrixF tempMat( *sgData.objTrans );
      tempMat.inverse();
      Point3F eyepos;
      tempMat.mulP( eyePosWorld, &eyepos );
      shaderConsts->set(handles->mEyePosSC, eyepos);   
   }

   shaderConsts->setSafe(handles->mEyeMatSC, state->getCameraTransform());   

   ShaderRenderPassData *rpd = _getRPD( pass );
   for ( U32 i=0; i < rpd->featureShaderHandles.size(); i++ )
      rpd->featureShaderHandles[i]->setConsts( state, sgData, shaderConsts );

   LIGHTMGR->setLightInfo( this, mMaterial, sgData, state, pass, shaderConsts );
}
bool ProcessedCustomMaterial::setupPass( SceneRenderState *state, const SceneData& sgData, U32 pass )
{
   PROFILE_SCOPE( ProcessedCustomMaterial_SetupPass );

   // Make sure we have a pass.
   if ( pass >= mPasses.size() )
      return false;

   ShaderRenderPassData* rpd = _getRPD( pass );
   U32 currState = _getRenderStateIndex( state, sgData );
   GFX->setStateBlock(rpd->mRenderStates[currState]);      

   // activate shader
   if ( rpd->shader )
      GFX->setShader( rpd->shader );
   else
      GFX->disableShaders();

   // Set our textures   
   setTextureStages( state, sgData, pass );   
   
   GFXShaderConstBuffer* shaderConsts = _getShaderConstBuffer(pass);
   GFX->setShaderConstBuffer(shaderConsts);
   
   // Set our shader constants.
   _setTextureTransforms(pass);
   _setShaderConstants(state, sgData, pass);

   LightManager* lm = state ? LIGHTMGR : NULL;
   if (lm)
      lm->setLightInfo(this, NULL, sgData, state, pass, shaderConsts);

   shaderConsts->setSafe(rpd->shaderHandles.mAccumTimeSC, MATMGR->getTotalTime());   

   return true;
}
Exemple #3
0
void ProcessedShaderMaterial::_setShaderConstants(SceneRenderState * state, const SceneData &sgData, U32 pass)
{
   PROFILE_SCOPE( ProcessedShaderMaterial_SetShaderConstants );

   GFXShaderConstBuffer* shaderConsts = _getShaderConstBuffer(pass);
   ShaderConstHandles* handles = _getShaderConstHandles(pass);
   U32 stageNum = getStageFromPass(pass);

   // First we do all the constants which are not
   // controlled via the material... we have to
   // set these all the time as they could change.

   if ( handles->mFogDataSC->isValid() )
   {
      Point3F fogData;
      fogData.x = sgData.fogDensity;
      fogData.y = sgData.fogDensityOffset;
      fogData.z = sgData.fogHeightFalloff;     
      shaderConsts->set( handles->mFogDataSC, fogData );
   }

   shaderConsts->setSafe(handles->mFogColorSC, sgData.fogColor);

   if( handles->mOneOverFarplane->isValid() )
   {
      const F32 &invfp = 1.0f / state->getFarPlane();
      Point4F oneOverFP(invfp, invfp, invfp, invfp);
      shaderConsts->set( handles->mOneOverFarplane, oneOverFP );
   }

   shaderConsts->setSafe( handles->mAccumTimeSC, MATMGR->getTotalTime() );

   // If the shader constants have not been lost then
   // they contain the content from a previous render pass.
   //
   // In this case we can skip updating the material constants
   // which do not change frame to frame.
   //
   // NOTE: This assumes we're not animating material parameters
   // in a way that doesn't cause a shader reload... this isn't
   // being done now, but it could change in the future.
   // 
   if ( !shaderConsts->wasLost() )
      return;

   shaderConsts->setSafe(handles->mSpecularColorSC, mMaterial->mSpecular[stageNum]);   
   shaderConsts->setSafe(handles->mSpecularPowerSC, mMaterial->mSpecularPower[stageNum]);

   shaderConsts->setSafe(handles->mParallaxInfoSC, mMaterial->mParallaxScale[stageNum]);   
   shaderConsts->setSafe(handles->mMinnaertConstantSC, mMaterial->mMinnaertConstant[stageNum]);

   if ( handles->mSubSurfaceParamsSC->isValid() )
   {
      Point4F subSurfParams;
      dMemcpy( &subSurfParams, &mMaterial->mSubSurfaceColor[stageNum], sizeof(ColorF) );
      subSurfParams.w = mMaterial->mSubSurfaceRolloff[stageNum];
      shaderConsts->set(handles->mSubSurfaceParamsSC, subSurfParams);
   }

   if ( handles->mRTSizeSC->isValid() )
   {
      const Point2I &resolution = GFX->getActiveRenderTarget()->getSize();
      Point2F pixelShaderConstantData;

      pixelShaderConstantData.x = resolution.x;
      pixelShaderConstantData.y = resolution.y;

      shaderConsts->set( handles->mRTSizeSC, pixelShaderConstantData );
   }

   if ( handles->mOneOverRTSizeSC->isValid() )
   {
      const Point2I &resolution = GFX->getActiveRenderTarget()->getSize();
      Point2F oneOverTargetSize( 1.0f / (F32)resolution.x, 1.0f / (F32)resolution.y );

      shaderConsts->set( handles->mOneOverRTSizeSC, oneOverTargetSize );
   }

   // set detail scale
   shaderConsts->setSafe(handles->mDetailScaleSC, mMaterial->mDetailScale[stageNum]);
   shaderConsts->setSafe(handles->mDetailBumpStrength, mMaterial->mDetailNormalMapStrength[stageNum]);

   // MFT_ImposterVert
   if ( handles->mImposterUVs->isValid() )
   {
      U32 uvCount = getMin( mMaterial->mImposterUVs.size(), 64 ); // See imposter.hlsl   
      AlignedArray<Point4F> imposterUVs( uvCount, sizeof( Point4F ), (U8*)mMaterial->mImposterUVs.address(), false );
      shaderConsts->set( handles->mImposterUVs, imposterUVs );
   }
   shaderConsts->setSafe( handles->mImposterLimits, mMaterial->mImposterLimits );

   // Diffuse
   shaderConsts->setSafe(handles->mDiffuseColorSC, mMaterial->mDiffuse[stageNum]);

   shaderConsts->setSafe( handles->mAlphaTestValueSC, mClampF( (F32)mMaterial->mAlphaRef / 255.0f, 0.0f, 1.0f ) );      

   if(handles->mDiffuseAtlasParamsSC)
   {
      Point4F atlasParams(1.0f / mMaterial->mCellLayout[stageNum].x, // 1 / num_horizontal
         1.0f / mMaterial->mCellLayout[stageNum].y, // 1 / num_vertical
         mMaterial->mCellSize[stageNum],            // tile size in pixels
         getBinLog2(mMaterial->mCellSize[stageNum]) );    // pow of 2 of tile size in pixels 2^9 = 512, 2^10=1024 etc
      shaderConsts->setSafe(handles->mDiffuseAtlasParamsSC, atlasParams);
   }

   if(handles->mBumpAtlasParamsSC)
   {
      Point4F atlasParams(1.0f / mMaterial->mCellLayout[stageNum].x, // 1 / num_horizontal
         1.0f / mMaterial->mCellLayout[stageNum].y, // 1 / num_vertical
         mMaterial->mCellSize[stageNum],            // tile size in pixels
         getBinLog2(mMaterial->mCellSize[stageNum]) );    // pow of 2 of tile size in pixels 2^9 = 512, 2^10=1024 etc
      shaderConsts->setSafe(handles->mBumpAtlasParamsSC, atlasParams);
   }

   if(handles->mDiffuseAtlasTileSC)
   {
      // Sanity check the wrap flags
      //AssertWarn(mMaterial->mTextureAddressModeU == mMaterial->mTextureAddressModeV, "Addresing mode mismatch, texture atlasing will be confused");
      Point4F atlasTileParams( mMaterial->mCellIndex[stageNum].x, // Tile co-ordinate, ie: [0, 3]
         mMaterial->mCellIndex[stageNum].y, 
         0.0f, 0.0f ); // TODO: Wrap mode flags?
      shaderConsts->setSafe(handles->mDiffuseAtlasTileSC, atlasTileParams);
   }

   if(handles->mBumpAtlasTileSC)
   {
      // Sanity check the wrap flags
      //AssertWarn(mMaterial->mTextureAddressModeU == mMaterial->mTextureAddressModeV, "Addresing mode mismatch, texture atlasing will be confused");
      Point4F atlasTileParams( mMaterial->mCellIndex[stageNum].x, // Tile co-ordinate, ie: [0, 3]
         mMaterial->mCellIndex[stageNum].y, 
         0.0f, 0.0f ); // TODO: Wrap mode flags?
      shaderConsts->setSafe(handles->mBumpAtlasTileSC, atlasTileParams);
   }
}
Exemple #4
0
void ProcessedShaderMaterial::_setTextureTransforms(const U32 pass)
{
   PROFILE_SCOPE( ProcessedShaderMaterial_SetTextureTransforms );

   ShaderConstHandles* handles = _getShaderConstHandles(pass);
   if (handles->mTexMatSC->isValid())
   {   
      MatrixF texMat( true );

      mMaterial->updateTimeBasedParams();
      F32 waveOffset = _getWaveOffset( pass ); // offset is between 0.0 and 1.0

      // handle scroll anim type
      if(  mMaterial->mAnimFlags[pass] & Material::Scroll )
      {
         if( mMaterial->mAnimFlags[pass] & Material::Wave )
         {
            Point3F scrollOffset;
            scrollOffset.x = mMaterial->mScrollDir[pass].x * waveOffset;
            scrollOffset.y = mMaterial->mScrollDir[pass].y * waveOffset;
            scrollOffset.z = 1.0;

            texMat.setColumn( 3, scrollOffset );
         }
         else
         {
            Point3F offset( mMaterial->mScrollOffset[pass].x, 
               mMaterial->mScrollOffset[pass].y, 
               1.0 );

            texMat.setColumn( 3, offset );
         }

      }

      // handle rotation
      if( mMaterial->mAnimFlags[pass] & Material::Rotate )
      {
         if( mMaterial->mAnimFlags[pass] & Material::Wave )
         {
            F32 rotPos = waveOffset * M_2PI;
            texMat.set( EulerF( 0.0, 0.0, rotPos ) );
            texMat.setColumn( 3, Point3F( 0.5, 0.5, 0.0 ) );

            MatrixF test( true );
            test.setColumn( 3, Point3F( mMaterial->mRotPivotOffset[pass].x, 
               mMaterial->mRotPivotOffset[pass].y,
               0.0 ) );
            texMat.mul( test );
         }
         else
         {
            texMat.set( EulerF( 0.0, 0.0, mMaterial->mRotPos[pass] ) );

            texMat.setColumn( 3, Point3F( 0.5, 0.5, 0.0 ) );

            MatrixF test( true );
            test.setColumn( 3, Point3F( mMaterial->mRotPivotOffset[pass].x, 
               mMaterial->mRotPivotOffset[pass].y,
               0.0 ) );
            texMat.mul( test );
         }
      }

      // Handle scale + wave offset
      if(  mMaterial->mAnimFlags[pass] & Material::Scale &&
         mMaterial->mAnimFlags[pass] & Material::Wave )
      {
         F32 wOffset = fabs( waveOffset );

         texMat.setColumn( 3, Point3F( 0.5, 0.5, 0.0 ) );

         MatrixF temp( true );
         temp.setRow( 0, Point3F( wOffset,  0.0,  0.0 ) );
         temp.setRow( 1, Point3F( 0.0,  wOffset,  0.0 ) );
         temp.setRow( 2, Point3F( 0.0,  0.0,  wOffset ) );
         temp.setColumn( 3, Point3F( -wOffset * 0.5, -wOffset * 0.5, 0.0 ) );
         texMat.mul( temp );
      }

      // handle sequence
      if( mMaterial->mAnimFlags[pass] & Material::Sequence )
      {
         U32 frameNum = (U32)(MATMGR->getTotalTime() * mMaterial->mSeqFramePerSec[pass]);
         F32 offset = frameNum * mMaterial->mSeqSegSize[pass];

         if ( mMaterial->mAnimFlags[pass] & Material::Scale )
            texMat.scale( Point3F( mMaterial->mSeqSegSize[pass], 1.0f, 1.0f ) );

         Point3F texOffset = texMat.getPosition();
         texOffset.x += offset;
         texMat.setPosition( texOffset );
      }

      GFXShaderConstBuffer* shaderConsts = _getShaderConstBuffer(pass);
      shaderConsts->setSafe(handles->mTexMatSC, texMat);
   }
}
Exemple #5
0
void ProcessedShaderMaterial::setTextureStages( SceneRenderState *state, const SceneData &sgData, U32 pass )
{
   PROFILE_SCOPE( ProcessedShaderMaterial_SetTextureStages );

   ShaderConstHandles *handles = _getShaderConstHandles(pass);

   // Set all of the textures we need to render the give pass.
#ifdef TORQUE_DEBUG
   AssertFatal( pass<mPasses.size(), "Pass out of bounds" );
#endif

   RenderPassData *rpd = mPasses[pass];
   GFXShaderConstBuffer* shaderConsts = _getShaderConstBuffer(pass);
   NamedTexTarget *texTarget;
   GFXTextureObject *texObject; 

   for( U32 i=0; i<rpd->mNumTex; i++ )
   {
      U32 currTexFlag = rpd->mTexType[i];
      if (!LIGHTMGR || !LIGHTMGR->setTextureStage(sgData, currTexFlag, i, shaderConsts, handles))
      {
         switch( currTexFlag )
         {
         // If the flag is unset then assume its just
         // a regular texture to set... nothing special.
         case 0:
         default:
            GFX->setTexture(i, rpd->mTexSlot[i].texObject);
            break;

         case Material::NormalizeCube:
            GFX->setCubeTexture(i, Material::GetNormalizeCube());
            break;

         case Material::Lightmap:
            GFX->setTexture( i, sgData.lightmap );
            break;

         case Material::ToneMapTex:
            shaderConsts->setSafe(handles->mToneMapTexSC, (S32)i);
            GFX->setTexture(i, rpd->mTexSlot[i].texObject);
            break;

         case Material::Cube:
            GFX->setCubeTexture( i, rpd->mCubeMap );
            break;

         case Material::SGCube:
            GFX->setCubeTexture( i, sgData.cubemap );
            break;

         case Material::BackBuff:
            GFX->setTexture( i, sgData.backBuffTex );
            break;
            
         case Material::TexTarget:
            {
               texTarget = rpd->mTexSlot[i].texTarget;
               if ( !texTarget )
               {
                  GFX->setTexture( i, NULL );
                  break;
               }
            
               texObject = texTarget->getTexture();

               // If no texture is available then map the default 2x2
               // black texture to it.  This at least will ensure that
               // we get consistant behavior across GPUs and platforms.
               if ( !texObject )
                  texObject = GFXTexHandle::ZERO;

               if ( handles->mRTParamsSC[i]->isValid() && texObject )
               {
                  const Point3I &targetSz = texObject->getSize();
                  const RectI &targetVp = texTarget->getViewport();
                  Point4F rtParams;

                  ScreenSpace::RenderTargetParameters(targetSz, targetVp, rtParams);

                  shaderConsts->set(handles->mRTParamsSC[i], rtParams);
               }

               GFX->setTexture( i, texObject );
               break;
            }
         }
      }
   }
}