void ProjectedShadow::update( const SceneRenderState *state ) { mUpdateTexture = true; // Set the decal lod settings. mDecalData->fadeStartPixelSize = smFadeStartPixelSize; mDecalData->fadeEndPixelSize = smFadeEndPixelSize; // Update our decal before // we render to texture. // If it fails, something bad happened // (no light to grab/failed clip) and we should return. if ( !_updateDecal( state ) ) { // Release our shadow texture // so that others can grab it out // of the pool. mShadowTexture = NULL; mUpdateTexture = false; return; } _calcScore( state ); if ( !mCasterPositionSC || !mCasterPositionSC->isValid() ) mCasterPositionSC = mDecalData->matInst->getMaterialParameterHandle( "$shadowCasterPosition" ); if ( !mShadowLengthSC || !mShadowLengthSC->isValid() ) mShadowLengthSC = mDecalData->matInst->getMaterialParameterHandle( "$shadowLength" ); MaterialParameters *matParams = mDecalData->matInst->getMaterialParameters(); matParams->setSafe( mCasterPositionSC, mParentObject->getRenderPosition() ); matParams->setSafe( mShadowLengthSC, mShadowLength / 4.0f ); }
void AtlasClipMapBatcher::renderDetail( SceneGraphData& sgData ) { PROFILE_SCOPE(AtlasClipMapBatcher_renderDetail); if( !mDetailMat ) return; if( mFixedFunction ) { MatrixF detailTexMatrix( true ); detailTexMatrix.scale( Point3F( mDetailMapTextureMultiply, mDetailMapTextureMultiply, 0.0f ) ); GFX->setTextureMatrix( 0, detailTexMatrix ); } else { Point3F detailConst( mDetailMapFadeStartDistance, 1.f / (mDetailMapFadeEndDistance - mDetailMapFadeStartDistance), mDetailMapTextureMultiply); F32 brightnessScale = 1.0; MaterialParameters* params = mDetailMat->getMaterialParameters(); params->set( mDetDataSC, detailConst ); params->set( mBrightnessScaleSC, brightnessScale ); } GFX->setTexture( 0, mObject->mDetailTex ); // And render all the detailed chunks - all for now. for(S32 i=0; i<mDetailList.size(); i++) { // Grab the render note. const RenderNote *rn = mDetailList[i]; // And draw it. while( mDetailMat->setupPass( mState, sgData ) ) rn->chunk->render(); } }
void AdvancedLightBinManager::LightMaterialInfo::setViewParameters( const F32 _zNear, const F32 _zFar, const Point3F &_eyePos, const PlaneF &_farPlane, const PlaneF &_vsFarPlane) { MaterialParameters *matParams = matInstance->getMaterialParameters(); matParams->setSafe( farPlane, *((const Point4F *)&_farPlane) ); matParams->setSafe( vsFarPlane, *((const Point4F *)&_vsFarPlane) ); if ( negFarPlaneDotEye->isValid() ) { // -dot( farPlane, eyePos ) const F32 negFarPlaneDotEyeVal = -( mDot( *((const Point3F *)&_farPlane), _eyePos ) + _farPlane.d ); matParams->set( negFarPlaneDotEye, negFarPlaneDotEyeVal ); } matParams->setSafe( zNearFarInvNearFar, Point4F( _zNear, _zFar, 1.0f / _zNear, 1.0f / _zFar ) ); }
void WaterPlane::setShaderParams( SceneRenderState *state, BaseMatInstance* mat, const WaterMatParams& paramHandles) { // Set variables that will be assigned to shader consts within WaterCommon // before calling Parent::setShaderParams mUndulateMaxDist = mGridElementSize * mGridSizeMinusOne * 0.5f; Parent::setShaderParams( state, mat, paramHandles ); // Now set the rest of the shader consts that are either unique to this // class or that WaterObject leaves to us to handle... MaterialParameters* matParams = mat->getMaterialParameters(); // set vertex shader constants //----------------------------------- matParams->setSafe(paramHandles.mGridElementSizeSC, (F32)mGridElementSize); //matParams->setSafe( paramHandles.mReflectTexSizeSC, mReflectTexSize ); if ( paramHandles.mModelMatSC->isValid() ) matParams->set(paramHandles.mModelMatSC, getRenderTransform(), GFXSCT_Float4x4); // set pixel shader constants //----------------------------------- ColorF c( mWaterFogData.color ); matParams->setSafe( paramHandles.mBaseColorSC, c ); // By default we need to show a true reflection is fullReflect is enabled and // we are above water. F32 reflect = mPlaneReflector.isEnabled() && !isUnderwater( state->getCameraPosition() ); // If we were occluded the last frame a query was fetched ( not necessarily last frame ) // and we weren't updated last frame... we don't have a valid texture to show // so use the cubemap / fake reflection color this frame. if ( mPlaneReflector.lastUpdateMs != REFLECTMGR->getLastUpdateMs() && mPlaneReflector.isOccluded() ) reflect = false; //Point4F reflectParams( getRenderPosition().z, mReflectMinDist, mReflectMaxDist, reflect ); Point4F reflectParams( getRenderPosition().z, 0.0f, 1000.0f, !reflect ); // TODO: This is a hack... why is this broken... check after // we merge advanced lighting with trunk! // reflectParams.z = 0.0f; matParams->setSafe( paramHandles.mReflectParamsSC, reflectParams ); VectorF reflectNorm( 0, 0, 1 ); matParams->setSafe(paramHandles.mReflectNormalSC, reflectNorm ); }
void AdvancedLightBinManager::LightMaterialInfo::setLightParameters( const LightInfo *lightInfo, const SceneRenderState* renderState, const MatrixF &worldViewOnly ) { MaterialParameters *matParams = matInstance->getMaterialParameters(); // Set color in the right format, set alpha to the luminance value for the color. ColorF col = lightInfo->getColor(); // TODO: The specularity control of the light // is being scaled by the overall lumiance. // // Not sure if this may be the source of our // bad specularity results maybe? // const Point3F colorToLumiance( 0.3576f, 0.7152f, 0.1192f ); F32 lumiance = mDot(*((const Point3F *)&lightInfo->getColor()), colorToLumiance ); col.alpha *= lumiance; matParams->setSafe( lightColor, col ); matParams->setSafe( lightBrightness, lightInfo->getBrightness() ); switch( lightInfo->getType() ) { case LightInfo::Vector: { VectorF lightDir = lightInfo->getDirection(); worldViewOnly.mulV(lightDir); lightDir.normalize(); matParams->setSafe( lightDirection, lightDir ); // Set small number for alpha since it represents existing specular in // the vector light. This prevents a divide by zero. ColorF ambientColor = renderState->getAmbientLightColor(); ambientColor.alpha = 0.00001f; matParams->setSafe( lightAmbient, ambientColor ); // If no alt color is specified, set it to the average of // the ambient and main color to avoid artifacts. // // TODO: Trilight disabled until we properly implement it // in the light info! // //ColorF lightAlt = lightInfo->getAltColor(); ColorF lightAlt( ColorF::BLACK ); // = lightInfo->getAltColor(); if ( lightAlt.red == 0.0f && lightAlt.green == 0.0f && lightAlt.blue == 0.0f ) lightAlt = (lightInfo->getColor() + renderState->getAmbientLightColor()) / 2.0f; ColorF trilightColor = lightAlt; matParams->setSafe(lightTrilight, trilightColor); } break; case LightInfo::Spot: { const F32 outerCone = lightInfo->getOuterConeAngle(); const F32 innerCone = getMin( lightInfo->getInnerConeAngle(), outerCone ); const F32 outerCos = mCos( mDegToRad( outerCone / 2.0f ) ); const F32 innerCos = mCos( mDegToRad( innerCone / 2.0f ) ); Point4F spotParams( outerCos, innerCos - outerCos, mCos( mDegToRad( outerCone ) ), 0.0f ); matParams->setSafe( lightSpotParams, spotParams ); VectorF lightDir = lightInfo->getDirection(); worldViewOnly.mulV(lightDir); lightDir.normalize(); matParams->setSafe( lightDirection, lightDir ); } // Fall through case LightInfo::Point: { const F32 radius = lightInfo->getRange().x; matParams->setSafe( lightRange, radius ); Point3F lightPos; worldViewOnly.mulP(lightInfo->getPosition(), &lightPos); matParams->setSafe( lightPosition, lightPos ); // Get the attenuation falloff ratio and normalize it. Point3F attenRatio = lightInfo->getExtended<ShadowMapParams>()->attenuationRatio; F32 total = attenRatio.x + attenRatio.y + attenRatio.z; if ( total > 0.0f ) attenRatio /= total; Point2F attenParams( ( 1.0f / radius ) * attenRatio.y, ( 1.0f / ( radius * radius ) ) * attenRatio.z ); matParams->setSafe( lightAttenuation, attenParams ); break; } default: AssertFatal( false, "Bad light type!" ); break; } }
BaseMatInstance* ClipMap::getMaterialAndTextures( U32 level1, U32 level2, U32 level3/*=-1*/, U32 level4/*=-1*/, bool doTerrainRenderHack ) { // Figure out how many layers we have. U32 levelCount = 2; if(level3 != -1) levelCount++; if(level4 != -1) levelCount++; GRAPHIC->clearSamplerOverrides(); mMapInfoConst.setSize(levelCount); // Set up constants, bind textures. for(S32 i=0; i<levelCount; i++) { U32 curLevel = -1; switch(i) { case 0: curLevel = level1; break; case 1: curLevel = level2; break; case 2: curLevel = level3; break; case 3: curLevel = level4; break; } AssertFatal(curLevel != -1, "ClipMap::bindShaderAndTextures - tried to draw an unspecified layer!"); AssertFatal(curLevel < mLevels.size(), "ClipMap::bindShaderAndTextures - out of range level specified!"); // Grab references to relevant data. Point4F &pt = mMapInfoConst[i]; ClipMap::ClipStackEntry &cse = mLevels[curLevel]; // Bind debug or real textures, depending on flag. if(smDebugTextures) GRAPHIC->setTexture(i, cse.mDebugTex); else GRAPHIC->setTexture(i, cse.mTex); // Note the offset and center for this level as well. pt.x = cse.mClipCenter.x * cse.mScale; pt.y = cse.mClipCenter.y * cse.mScale; pt.z = cse.mScale; pt.w = 0.f; if (doTerrainRenderHack && TerrainRender::mCurrentBlock && !TerrainRender::mCurrentBlock->isTiling()) { // At scale 1.0 we can clamp the UV edges avoiding edge bleed between terrain blocks if (cse.mScale == 1.0f) { GRAPHIC->setSamplerAddressModeOverride(i, true, GAddressClamp); } // Ideally, we want to clamp at scale 2.0 as well. // however, we can't clamp as the shader is scaling the UV coords // edge bleed is caused by mipmaps wrapping, so let's bias the mipmap selection // out a little bit, this is only necessary for level 2 of the clip map if (cse.mScale == 2.0f) { GRAPHIC->setSamplerMipLODBiasOverride(i, true, -1.0f); } else { GRAPHIC->setSamplerMipLODBiasOverride(i, true, 0.0f); } } } S32 idx = levelCount - 1; BaseMatInstance* ret = mClipmapMat[idx]; MaterialParameters* params = ret->getMaterialParameters(); // We do not use the morph target in the shader, but // we also cannot assume it will be cleared for us. params->set(mMorphTSC[idx], 0.0f); // Set all the constants in one go. params->set(mMapInfoTC[idx], mMapInfoConst); params->set(mDiffuseMap0TC[idx], (S32)0); params->set(mDiffuseMap1TC[idx], (S32)1); params->set(mDiffuseMap2TC[idx], (S32)2); params->set(mDiffuseMap3TC[idx], (S32)3); GRAPHIC->updateStates(true); // Ok - all bound! return ret; }
void WaterObject::setShaderParams( SceneRenderState *state, BaseMatInstance *mat, const WaterMatParams ¶mHandles ) { MaterialParameters* matParams = mat->getMaterialParameters(); matParams->setSafe( paramHandles.mElapsedTimeSC, (F32)Sim::getCurrentTime() / 1000.0f ); // set vertex shader constants //----------------------------------- Point2F reflectTexSize( mPlaneReflector.reflectTex.getWidth(), mPlaneReflector.reflectTex.getHeight() ); matParams->setSafe( paramHandles.mReflectTexSizeSC, reflectTexSize ); static AlignedArray<Point2F> mConstArray( MAX_WAVES, sizeof( Point4F ) ); // Ripples... for ( U32 i = 0; i < MAX_WAVES; i++ ) mConstArray[i].set( -mRippleDir[i].x, -mRippleDir[i].y ); matParams->setSafe( paramHandles.mRippleDirSC, mConstArray ); Point3F rippleSpeed( mRippleSpeed[0], mRippleSpeed[1], mRippleSpeed[2] ); matParams->setSafe( paramHandles.mRippleSpeedSC, rippleSpeed ); Point4F rippleMagnitude( mRippleMagnitude[0], mRippleMagnitude[1], mRippleMagnitude[2], mOverallRippleMagnitude ); matParams->setSafe( paramHandles.mRippleMagnitudeSC, rippleMagnitude ); for ( U32 i = 0; i < MAX_WAVES; i++ ) { Point2F texScale = mRippleTexScale[i]; if ( texScale.x > 0.0 ) texScale.x = 1.0 / texScale.x; if ( texScale.y > 0.0 ) texScale.y = 1.0 / texScale.y; mConstArray[i].set( texScale.x, texScale.y ); } matParams->setSafe(paramHandles.mRippleTexScaleSC, mConstArray); static AlignedArray<Point4F> mConstArray4F( 3, sizeof( Point4F ) ); F32 angle, cosine, sine; for ( U32 i = 0; i < MAX_WAVES; i++ ) { angle = mAtan2( mRippleDir[i].x, -mRippleDir[i].y ); cosine = mCos( angle ); sine = mSin( angle ); mConstArray4F[i].set( cosine, sine, -sine, cosine ); matParams->setSafe( paramHandles.mRippleMatSC, mConstArray4F ); } // Waves... for ( U32 i = 0; i < MAX_WAVES; i++ ) mConstArray[i].set( -mWaveDir[i].x, -mWaveDir[i].y ); matParams->setSafe( paramHandles.mWaveDirSC, mConstArray ); for ( U32 i = 0; i < MAX_WAVES; i++ ) mConstArray[i].set( mWaveSpeed[i], mWaveMagnitude[i] * mOverallWaveMagnitude ); matParams->setSafe( paramHandles.mWaveDataSC, mConstArray ); // Foam... Point4F foamDir( mFoamDir[0].x, mFoamDir[0].y, mFoamDir[1].x, mFoamDir[1].y ); matParams->setSafe( paramHandles.mFoamDirSC, foamDir ); Point2F foamSpeed( mFoamSpeed[0], mFoamSpeed[1] ); matParams->setSafe( paramHandles.mFoamSpeedSC, foamSpeed ); //Point3F rippleMagnitude( mRippleMagnitude[0] * mOverallRippleMagnitude, // mRippleMagnitude[1] * mOverallRippleMagnitude, // mRippleMagnitude[2] * mOverallRippleMagnitude ); //matParams->setSafe( paramHandles.mRippleMagnitudeSC, rippleMagnitude ); Point4F foamTexScale( mFoamTexScale[0].x, mFoamTexScale[0].y, mFoamTexScale[1].x, mFoamTexScale[1].y ); for ( U32 i = 0; i < 4; i++ ) { if ( foamTexScale[i] > 0.0f ) foamTexScale[i] = 1.0 / foamTexScale[i]; } matParams->setSafe(paramHandles.mFoamTexScaleSC, foamTexScale); // Other vert params... matParams->setSafe( paramHandles.mUndulateMaxDistSC, mUndulateMaxDist ); // set pixel shader constants //----------------------------------- Point2F fogParams( mWaterFogData.density, mWaterFogData.densityOffset ); matParams->setSafe(paramHandles.mFogParamsSC, fogParams ); matParams->setSafe(paramHandles.mFarPlaneDistSC, (F32)state->getFarPlane() ); Point2F wetnessParams( mWaterFogData.wetDepth, mWaterFogData.wetDarkening ); matParams->setSafe(paramHandles.mWetnessParamsSC, wetnessParams ); Point3F distortionParams( mDistortStartDist, mDistortEndDist, mDistortFullDepth ); matParams->setSafe(paramHandles.mDistortionParamsSC, distortionParams ); LightInfo *sun = LIGHTMGR->getSpecialLight(LightManager::slSunLightType); const ColorF &sunlight = state->getAmbientLightColor(); Point3F ambientColor = mEmissive ? Point3F::One : sunlight; matParams->setSafe(paramHandles.mAmbientColorSC, ambientColor ); matParams->setSafe(paramHandles.mLightDirSC, sun->getDirection() ); Point4F foamParams( mOverallFoamOpacity, mFoamMaxDepth, mFoamAmbientLerp, mFoamRippleInfluence ); matParams->setSafe(paramHandles.mFoamParamsSC, foamParams ); Point4F miscParams( mFresnelBias, mFresnelPower, mClarity, mMiscParamW ); matParams->setSafe( paramHandles.mMiscParamsSC, miscParams ); Point4F specularParams( mSpecularColor.red, mSpecularColor.green, mSpecularColor.blue, mSpecularPower ); if ( !mEmissive ) { const ColorF &sunColor = sun->getColor(); F32 brightness = sun->getBrightness(); specularParams.x *= sunColor.red * brightness; specularParams.y *= sunColor.green * brightness; specularParams.z *= sunColor.blue * brightness; } matParams->setSafe( paramHandles.mSpecularParamsSC, specularParams ); matParams->setSafe( paramHandles.mDepthGradMaxSC, mDepthGradientMax ); matParams->setSafe( paramHandles.mReflectivitySC, mReflectivity ); }
// BTRTODO: Support arrays!? MaterialParameters* ProcessedCustomMaterial::allocMaterialParameters() { MaterialParameters* ret = Parent::allocMaterialParameters(); // See if any of the dynamic fields match up with shader constants we have. SimFieldDictionary* fields = mMaterial->getFieldDictionary(); if (!fields || fields->getNumFields() == 0) return ret; const Vector<GFXShaderConstDesc>& consts = ret->getShaderConstDesc(); for (U32 i = 0; i < consts.size(); i++) { // strip the dollar sign from the front. String stripped(consts[i].name); stripped.erase(0, 1); SimFieldDictionary::Entry* field = fields->findDynamicField(stripped); if (field) { MaterialParameterHandle* handle = getMaterialParameterHandle(consts[i].name); switch (consts[i].constType) { case GFXSCT_Float : setMaterialParameter<F32>(ret, handle, field->value); break; case GFXSCT_Float2: setMaterialParameter<Point2F>(ret, handle, field->value); break; case GFXSCT_Float3: setMaterialParameter<Point3F>(ret, handle, field->value); break; case GFXSCT_Float4: setMaterialParameter<Point4F>(ret, handle, field->value); break; case GFXSCT_Float2x2: case GFXSCT_Float3x3: setMatrixParameter(ret, handle, field->value, consts[i].constType); break; case GFXSCT_Float4x4: setMaterialParameter<MatrixF>(ret, handle, field->value); break; case GFXSCT_Int: setMaterialParameter<S32>(ret, handle, field->value); break; case GFXSCT_Int2: setMaterialParameter<Point2I>(ret, handle, field->value); break; case GFXSCT_Int3: setMaterialParameter<Point3I>(ret, handle, field->value); break; case GFXSCT_Int4: setMaterialParameter<Point4I>(ret, handle, field->value); break; // Do we want to ignore these? case GFXSCT_Sampler: case GFXSCT_SamplerCube: default: break; } } } return ret; }