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; }
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); } }