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 ) );
}
Exemple #4
0
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;
   }
}
Exemple #6
0
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;
}
Exemple #7
0
void WaterObject::setShaderParams( SceneRenderState *state, BaseMatInstance *mat, const WaterMatParams &paramHandles )
{
   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;
}