void ProcessedShaderMaterial::setTransforms(const MatrixSet &matrixSet, SceneRenderState *state, const U32 pass) { PROFILE_SCOPE( ProcessedShaderMaterial_setTransforms ); GFXShaderConstBuffer* shaderConsts = _getShaderConstBuffer(pass); ShaderConstHandles* handles = _getShaderConstHandles(pass); // The MatrixSet will lazily generate a matrix under the // various 'get' methods, so inline the test for a valid // shader constant handle to avoid that work when we can. if ( handles->mModelViewProjSC->isValid() ) shaderConsts->set( handles->mModelViewProjSC, matrixSet.getWorldViewProjection() ); if ( handles->mObjTransSC->isValid() ) shaderConsts->set( handles->mObjTransSC, matrixSet.getObjectToWorld() ); if ( handles->mWorldToObjSC->isValid() ) shaderConsts->set( handles->mWorldToObjSC, matrixSet.getWorldToObject() ); if ( handles->mWorldToCameraSC->isValid() ) shaderConsts->set( handles->mWorldToCameraSC, matrixSet.getWorldToCamera() ); if ( handles->mWorldViewOnlySC->isValid() ) shaderConsts->set( handles->mWorldViewOnlySC, matrixSet.getObjectToCamera() ); if ( handles->mViewToObjSC->isValid() ) shaderConsts->set( handles->mViewToObjSC, matrixSet.getCameraToObject() ); if ( handles->mViewProjSC->isValid() ) shaderConsts->set( handles->mViewProjSC, matrixSet.getWorldToScreen() ); if ( handles->mCubeTransSC->isValid() && ( _hasCubemap(pass) || mMaterial->mDynamicCubemap ) ) { // TODO: Could we not remove this constant? Use mObjTransSC and cast to float3x3 instead? shaderConsts->set(handles->mCubeTransSC, matrixSet.getObjectToWorld(), GFXSCT_Float3x3); } if ( handles->m_vEyeSC->isValid() ) shaderConsts->set( handles->m_vEyeSC, state->getVectorEye() ); }
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 ); }
void ProcessedCustomMaterial::setTextureStages( SceneRenderState *state, const SceneData &sgData, U32 pass ) { LightManager* lm = state ? LIGHTMGR : NULL; ShaderRenderPassData* rpd = _getRPD(pass); ShaderConstHandles* handles = _getShaderConstHandles(pass); GFXShaderConstBuffer* shaderConsts = _getShaderConstBuffer(pass); const NamedTexTarget *texTarget; GFXTextureObject *texObject; for( U32 i=0; i<mMaxTex; i++ ) { U32 currTexFlag = rpd->mTexType[i]; if ( !lm || !lm->setTextureStage(sgData, currTexFlag, i, shaderConsts, handles ) ) { GFXShaderConstHandle* handle = handles->mTexHandlesSC[i]; if ( !handle->isValid() ) continue; S32 samplerRegister = handle->getSamplerRegister(); switch( currTexFlag ) { case 0: default: break; case Material::Mask: case Material::Standard: case Material::Bump: case Material::Detail: { GFX->setTexture( samplerRegister, rpd->mTexSlot[i].texObject ); break; } case Material::Lightmap: { GFX->setTexture( samplerRegister, sgData.lightmap ); break; } case Material::Cube: { GFX->setCubeTexture( samplerRegister, rpd->mCubeMap ); break; } case Material::SGCube: { GFX->setCubeTexture( samplerRegister, sgData.cubemap ); break; } case Material::BackBuff: { GFX->setTexture( samplerRegister, sgData.backBuffTex ); //if ( sgData.reflectTex ) // GFX->setTexture( samplerRegister, sgData.reflectTex ); //else //{ // GFXTextureObject *refractTex = REFLECTMGR->getRefractTex( true ); // GFX->setTexture( samplerRegister, refractTex ); //} break; } case Material::ReflectBuff: { GFX->setTexture( samplerRegister, sgData.reflectTex ); break; } case Material::Misc: { GFX->setTexture( samplerRegister, sgData.miscTex ); break; } case Material::TexTarget: { texTarget = rpd->mTexSlot[i].texTarget; if ( !texTarget ) { GFX->setTexture( samplerRegister, 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[samplerRegister]->isValid() && texObject ) { const Point3I &targetSz = texObject->getSize(); const RectI &targetVp = texTarget->getViewport(); Point4F rtParams; ScreenSpace::RenderTargetParameters(targetSz, targetVp, rtParams); shaderConsts->set(handles->mRTParamsSC[samplerRegister], rtParams); } GFX->setTexture( samplerRegister, texObject ); break; } } } } }
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); } }
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; } } } } }