コード例 #1
0
U32 ProcessedMaterial::_getRenderStateIndex( const SceneRenderState *sceneState, 
                                             const SceneData &sgData,
                                             U32 pass )
{
   // Based on what the state of the world is, get our render state block
   U32 currState = 0;

   // NOTE: We should only use per-material or per-pass hints to
   // change the render state.  This is importaint because we 
   // only change the state blocks between material passes.
   //
   // For example sgData.visibility would be bad to use
   // in here without changing how RenderMeshMgr works.

   U32 stageNum = getStageFromPass(pass);

   if(mMaterial->mWireframe[stageNum])
      currState |= RenderPassData::STATE_WIREFRAME;

   if ( sgData.binType == SceneData::GlowBin )
      currState |= RenderPassData::STATE_GLOW;

   if ( sceneState && sceneState->isReflectPass() )
      currState |= RenderPassData::STATE_REFLECT;

   if ( sgData.binType != SceneData::PrePassBin &&
        mMaterial->isTranslucent() )
      currState |= RenderPassData::STATE_TRANSLUCENT;

   if ( sgData.wireframe )
      currState |= RenderPassData::STATE_WIREFRAME;

   return currState;
}
コード例 #2
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);
   }
}