Pārlūkot izejas kodu

Add support for both ies and cookie

Both ies and cookies can now exist on a light

We are still not using all the capabilities of an IES profile, such as candela and luminance values we are just using them as a mask for the moment

Issues compiling on mac and linux, will need to update the ies-loader to use torque methods instead of std::
marauder2k7 1 gadu atpakaļ
vecāks
revīzija
4417462499

+ 20 - 0
Engine/source/core/util/tDictionary.h

@@ -65,6 +65,21 @@ struct CompoundKey3
    bool operator==(const CompoundKey3 & compound) const { return key1==compound.key1 && key2==compound.key2 && key3==compound.key3; }
    bool operator==(const CompoundKey3 & compound) const { return key1==compound.key1 && key2==compound.key2 && key3==compound.key3; }
 };
 };
 
 
+template<class A, class B, class C, class D>
+struct CompoundKey4
+{
+   A key1;
+   B key2;
+   C key3;
+   D key4;
+
+   CompoundKey4() {};
+   CompoundKey4(const A& a, const B& b, const C& c, const D& d) { key1 = a; key2 = b; key3 = c; key4 = d;};
+
+   bool operator==(const CompoundKey4& compound) const { return key1 == compound.key1 && key2 == compound.key2 && key3 == compound.key3 && key4 == compound.key4; }
+};
+
+
 
 
 namespace DictHash
 namespace DictHash
 {
 {
@@ -110,6 +125,11 @@ namespace DictHash
       return hash(compound.key1) + hash(compound.key2) + hash(compound.key3);
       return hash(compound.key1) + hash(compound.key2) + hash(compound.key3);
    }
    }
 
 
+   template<class A, class B, class C, class D>
+   inline U32 hash(const CompoundKey4<A, B, C, D>& compound)
+   {
+      return hash(compound.key1) + hash(compound.key2) + hash(compound.key3) + hash(compound.key4);
+   }
    U32 nextPrime(U32);
    U32 nextPrime(U32);
 };
 };
 
 

+ 9 - 5
Engine/source/lighting/advanced/advancedLightBinManager.cpp

@@ -253,7 +253,7 @@ void AdvancedLightBinManager::addLight( LightInfo *light )
    LightBinEntry lEntry;
    LightBinEntry lEntry;
    lEntry.lightInfo = light;
    lEntry.lightInfo = light;
    lEntry.shadowMap = lsm;
    lEntry.shadowMap = lsm;
-   lEntry.lightMaterial = _getLightMaterial( lightType, shadowType, lsp->hasCookieTex() );
+   lEntry.lightMaterial = _getLightMaterial( lightType, shadowType, lsp->hasCookieTex(), lsp->hasIesProfile() );
 
 
    if( lightType == LightInfo::Spot )
    if( lightType == LightInfo::Spot )
       lEntry.vertBuffer = mLightManager->getConeMesh( lEntry.numPrims, lEntry.primBuffer );
       lEntry.vertBuffer = mLightManager->getConeMesh( lEntry.numPrims, lEntry.primBuffer );
@@ -399,9 +399,9 @@ void AdvancedLightBinManager::render( SceneRenderState *state )
          sunLight->getCastShadows() &&
          sunLight->getCastShadows() &&
          !disableShadows &&
          !disableShadows &&
          sunLight->getExtended<ShadowMapParams>() )
          sunLight->getExtended<ShadowMapParams>() )
-      vectorMatInfo = _getLightMaterial( LightInfo::Vector, ShadowType_PSSM, false );
+      vectorMatInfo = _getLightMaterial( LightInfo::Vector, ShadowType_PSSM );
    else
    else
-      vectorMatInfo = _getLightMaterial( LightInfo::Vector, ShadowType_None, false );
+      vectorMatInfo = _getLightMaterial( LightInfo::Vector, ShadowType_None );
 
 
    // Initialize and set the per-frame parameters after getting
    // Initialize and set the per-frame parameters after getting
    // the vector light material as we use lazy creation.
    // the vector light material as we use lazy creation.
@@ -513,12 +513,13 @@ void AdvancedLightBinManager::render( SceneRenderState *state )
 
 
 AdvancedLightBinManager::LightMaterialInfo* AdvancedLightBinManager::_getLightMaterial(   LightInfo::Type lightType, 
 AdvancedLightBinManager::LightMaterialInfo* AdvancedLightBinManager::_getLightMaterial(   LightInfo::Type lightType, 
                                                                                           ShadowType shadowType, 
                                                                                           ShadowType shadowType, 
-                                                                                          bool useCookieTex )
+                                                                                          bool useCookieTex,
+                                                                                          bool isPhotometric)
 {
 {
    PROFILE_SCOPE( AdvancedLightBinManager_GetLightMaterial );
    PROFILE_SCOPE( AdvancedLightBinManager_GetLightMaterial );
 
 
    // Build the key.
    // Build the key.
-   const LightMatKey key( lightType, shadowType, useCookieTex );
+   const LightMatKey key( lightType, shadowType, useCookieTex, isPhotometric );
 
 
    // See if we've already built this one.
    // See if we've already built this one.
    LightMatTable::Iterator iter = mLightMaterials.find( key );
    LightMatTable::Iterator iter = mLightMaterials.find( key );
@@ -558,6 +559,9 @@ AdvancedLightBinManager::LightMaterialInfo* AdvancedLightBinManager::_getLightMa
       if ( useCookieTex )
       if ( useCookieTex )
          shadowMacros.push_back( GFXShaderMacro( "USE_COOKIE_TEX" ) );
          shadowMacros.push_back( GFXShaderMacro( "USE_COOKIE_TEX" ) );
 
 
+      if(isPhotometric)
+         shadowMacros.push_back(GFXShaderMacro("UES_PHOTOMETRIC_MASK"));
+
       // Its safe to add the PSSM debug macro to all the materials.
       // Its safe to add the PSSM debug macro to all the materials.
       if ( smPSSMDebugRender )
       if ( smPSSMDebugRender )
          shadowMacros.push_back( GFXShaderMacro( "PSSM_DEBUG_RENDER" ) );
          shadowMacros.push_back( GFXShaderMacro( "PSSM_DEBUG_RENDER" ) );

+ 2 - 2
Engine/source/lighting/advanced/advancedLightBinManager.h

@@ -233,14 +233,14 @@ protected:
 
 
    static const GFXVertexFormat* smLightMatVertex[LightInfo::Count];
    static const GFXVertexFormat* smLightMatVertex[LightInfo::Count];
 
 
-   typedef CompoundKey3<LightInfo::Type,ShadowType,bool> LightMatKey;
+   typedef CompoundKey4<LightInfo::Type,ShadowType,bool, bool> LightMatKey;
 
 
    typedef HashTable<LightMatKey,LightMaterialInfo*> LightMatTable;
    typedef HashTable<LightMatKey,LightMaterialInfo*> LightMatTable;
 
 
    /// The fixed table of light material info.
    /// The fixed table of light material info.
    LightMatTable mLightMaterials;
    LightMatTable mLightMaterials;
 
 
-   LightMaterialInfo* _getLightMaterial( LightInfo::Type lightType, ShadowType shadowType, bool useCookieTex );
+   LightMaterialInfo* _getLightMaterial( LightInfo::Type lightType, ShadowType shadowType, bool useCookieTex = false, bool isPhotometric = false );
 
 
    ///
    ///
    void _onShadowFilterChanged();
    void _onShadowFilterChanged();

+ 15 - 0
Engine/source/lighting/advanced/advancedLightManager.cpp

@@ -277,6 +277,7 @@ void AdvancedLightManager::_initLightFields()
       DEFINE_LIGHT_FIELD( attenuationRatio, TypePoint3F, NULL );
       DEFINE_LIGHT_FIELD( attenuationRatio, TypePoint3F, NULL );
       DEFINE_LIGHT_FIELD( shadowType, TYPEID< ShadowType >(), ConsoleBaseType::getType( TYPEID< ShadowType >() )->getEnumTable() );
       DEFINE_LIGHT_FIELD( shadowType, TYPEID< ShadowType >(), ConsoleBaseType::getType( TYPEID< ShadowType >() )->getEnumTable() );
       DEFINE_LIGHT_FIELD( texSize, TypeS32, NULL );
       DEFINE_LIGHT_FIELD( texSize, TypeS32, NULL );
+      DEFINE_LIGHT_FIELD( iesProfile, TypeStringFilename, NULL );      
       DEFINE_LIGHT_FIELD( cookie, TypeStringFilename, NULL );      
       DEFINE_LIGHT_FIELD( cookie, TypeStringFilename, NULL );      
       DEFINE_LIGHT_FIELD( numSplits, TypeS32, NULL );
       DEFINE_LIGHT_FIELD( numSplits, TypeS32, NULL );
       DEFINE_LIGHT_FIELD( logWeight, TypeF32, NULL );
       DEFINE_LIGHT_FIELD( logWeight, TypeF32, NULL );
@@ -300,6 +301,9 @@ void AdvancedLightManager::_initLightFields()
       ADD_LIGHT_FIELD( "shadowType", TYPEID< ShadowType >(), shadowType,
       ADD_LIGHT_FIELD( "shadowType", TYPEID< ShadowType >(), shadowType,
          "The type of shadow to use on this light." );
          "The type of shadow to use on this light." );
 
 
+      ADD_LIGHT_FIELD("iesProfile", TypeStringFilename, iesProfile,
+         "A photometric profile for the light.");
+
       ADD_LIGHT_FIELD( "cookie", TypeStringFilename, cookie,
       ADD_LIGHT_FIELD( "cookie", TypeStringFilename, cookie,
          "A custom pattern texture which is projected from the light." );
          "A custom pattern texture which is projected from the light." );
 
 
@@ -496,6 +500,17 @@ bool AdvancedLightManager::setTextureStage(  const SceneData &sgData,
 
 
       return true;
       return true;
    }
    }
+   else if (currTexFlag == Material::PhotometricMask)
+   {
+      S32 reg = lsc->mIesProfileSC->getSamplerRegister();
+      if (reg != -1 && sgData.lights[0])
+      {
+         ShadowMapParams* p = sgData.lights[0]->getExtended<ShadowMapParams>();
+         GFX->setTexture(reg, p->getIesProfileTex());
+      }
+
+      return true;
+   }
 
 
    return false;
    return false;
 }
 }

+ 35 - 2
Engine/source/lighting/shadowMap/lightShadowMap.cpp

@@ -269,7 +269,8 @@ bool LightShadowMap::setTextureStage( U32 currTexFlag, LightingShaderConstants*
          GFX->setTexture( reg, mShadowMapTex);
          GFX->setTexture( reg, mShadowMapTex);
 
 
       return true;
       return true;
-   } else if ( currTexFlag == Material::DynamicLightMask )
+   }
+   else if ( currTexFlag == Material::DynamicLightMask )
    {
    {
       S32 reg = lsc->mCookieMapSC->getSamplerRegister();
       S32 reg = lsc->mCookieMapSC->getSamplerRegister();
    	if ( reg != -1 )
    	if ( reg != -1 )
@@ -284,6 +285,17 @@ bool LightShadowMap::setTextureStage( U32 currTexFlag, LightingShaderConstants*
 
 
       return true;
       return true;
    }
    }
+   else if (currTexFlag == Material::PhotometricMask)
+   {
+      S32 reg = lsc->mIesProfileSC->getSamplerRegister();
+      if (reg != -1)
+      {
+         ShadowMapParams* p = mLight->getExtended<ShadowMapParams>();
+         GFX->setTexture(reg, p->getIesProfileTex());
+      }
+
+      return true;
+   }
 
 
    return false;
    return false;
 }
 }
@@ -430,6 +442,7 @@ LightingShaderConstants::LightingShaderConstants()
       mShadowMapSC(NULL), 
       mShadowMapSC(NULL), 
       mShadowMapSizeSC(NULL), 
       mShadowMapSizeSC(NULL), 
       mCookieMapSC(NULL),
       mCookieMapSC(NULL),
+      mIesProfileSC(NULL),
       mRandomDirsConst(NULL),
       mRandomDirsConst(NULL),
       mShadowSoftnessConst(NULL), 
       mShadowSoftnessConst(NULL), 
       mAtlasXOffsetSC(NULL), 
       mAtlasXOffsetSC(NULL), 
@@ -490,6 +503,7 @@ void LightingShaderConstants::init(GFXShader* shader)
    mShadowMapSizeSC = shader->getShaderConstHandle("$shadowMapSize");
    mShadowMapSizeSC = shader->getShaderConstHandle("$shadowMapSize");
 
 
    mCookieMapSC = shader->getShaderConstHandle("$cookieMap");
    mCookieMapSC = shader->getShaderConstHandle("$cookieMap");
+   mIesProfileSC = shader->getShaderConstHandle("$iesProfile");
 
 
    mShadowSoftnessConst = shader->getShaderConstHandle("$shadowSoftness");
    mShadowSoftnessConst = shader->getShaderConstHandle("$shadowSoftness");
    mAtlasXOffsetSC = shader->getShaderConstHandle("$atlasXOffset");
    mAtlasXOffsetSC = shader->getShaderConstHandle("$atlasXOffset");
@@ -542,7 +556,8 @@ ShadowMapParams::ShadowMapParams( LightInfo *light )
    fadeStartDist = 75.0f;
    fadeStartDist = 75.0f;
    lastSplitTerrainOnly = false;
    lastSplitTerrainOnly = false;
    mQuery = GFX->createOcclusionQuery();
    mQuery = GFX->createOcclusionQuery();
-   cookie = StringTable->EmptyString();;
+   cookie = StringTable->EmptyString();
+   iesProfile = StringTable->EmptyString();
 
 
    _validate();
    _validate();
 }
 }
@@ -662,6 +677,22 @@ GFXTextureObject* ShadowMapParams::getCookieTex()
    return mCookieTex.getPointer();
    return mCookieTex.getPointer();
 }
 }
 
 
+GFXTextureObject* ShadowMapParams::getIesProfileTex()
+{
+   if (hasIesProfile() &&
+      (mIesTex.isNull() ||
+         iesProfile != StringTable->insert(mIesTex->getPath().c_str())))
+   {
+      mIesTex.set(iesProfile,
+         &GFXStaticTextureSRGBProfile,
+         "ShadowMapParams::getIesProfileTex()");
+   }
+   else if (!hasIesProfile())
+      mIesTex = NULL;
+
+   return mIesTex.getPointer();
+}
+
 GFXCubemap* ShadowMapParams::getCookieCubeTex()
 GFXCubemap* ShadowMapParams::getCookieCubeTex()
 {
 {
    if (  hasCookieTex() &&
    if (  hasCookieTex() &&
@@ -695,6 +726,7 @@ void ShadowMapParams::packUpdate( BitStream *stream ) const
    stream->write( texSize );
    stream->write( texSize );
 
 
    stream->writeString( cookie );
    stream->writeString( cookie );
+   stream->writeString( iesProfile );
 
 
    stream->write( numSplits );
    stream->write( numSplits );
    stream->write( logWeight );
    stream->write( logWeight );
@@ -725,6 +757,7 @@ void ShadowMapParams::unpackUpdate( BitStream *stream )
    stream->read( &texSize );
    stream->read( &texSize );
 
 
    cookie = stream->readSTString();
    cookie = stream->readSTString();
+   iesProfile = stream->readSTString();
 
 
    stream->read( &numSplits );
    stream->read( &numSplits );
    stream->read( &logWeight );
    stream->read( &logWeight );

+ 7 - 0
Engine/source/lighting/shadowMap/lightShadowMap.h

@@ -99,6 +99,7 @@ struct LightingShaderConstants
    GFXShaderConstHandle* mShadowMapSizeSC;
    GFXShaderConstHandle* mShadowMapSizeSC;
 
 
    GFXShaderConstHandle* mCookieMapSC;
    GFXShaderConstHandle* mCookieMapSC;
+   GFXShaderConstHandle* mIesProfileSC;
 
 
    GFXShaderConstHandle* mRandomDirsConst;
    GFXShaderConstHandle* mRandomDirsConst;
    GFXShaderConstHandle* mShadowSoftnessConst;
    GFXShaderConstHandle* mShadowSoftnessConst;
@@ -289,11 +290,14 @@ public:
    LightShadowMap* getOrCreateShadowMap();
    LightShadowMap* getOrCreateShadowMap();
 
 
    bool hasCookieTex() const { return cookie != StringTable->EmptyString(); }
    bool hasCookieTex() const { return cookie != StringTable->EmptyString(); }
+   bool hasIesProfile() const { return iesProfile != StringTable->EmptyString(); }
 
 
    GFXOcclusionQuery* getOcclusionQuery() const { return mQuery; }
    GFXOcclusionQuery* getOcclusionQuery() const { return mQuery; }
 
 
    GFXTextureObject* getCookieTex();
    GFXTextureObject* getCookieTex();
 
 
+   GFXTextureObject* getIesProfileTex();
+
    GFXCubemap* getCookieCubeTex();
    GFXCubemap* getCookieCubeTex();
 
 
    // Validates the parameters after a field is changed.
    // Validates the parameters after a field is changed.
@@ -313,6 +317,8 @@ protected:
 
 
    GFXCubemapHandle mCookieCubeTex;
    GFXCubemapHandle mCookieCubeTex;
 
 
+   GFXTexHandle mIesTex;
+
 public:
 public:
 
 
    // We're leaving these public for easy access 
    // We're leaving these public for easy access 
@@ -326,6 +332,7 @@ public:
 
 
    /// 
    /// 
    StringTableEntry cookie;
    StringTableEntry cookie;
+   StringTableEntry iesProfile;
 
 
    /// @}
    /// @}
 
 

+ 1 - 0
Engine/source/materials/materialDefinition.h

@@ -94,6 +94,7 @@ public:
       Misc,
       Misc,
       DynamicLight,
       DynamicLight,
       DynamicLightMask,
       DynamicLightMask,
+      PhotometricMask,
       NormalizeCube,
       NormalizeCube,
       TexTarget,
       TexTarget,
       AccuMap,
       AccuMap,

+ 8 - 0
Engine/source/materials/processedCustomMaterial.cpp

@@ -94,6 +94,14 @@ void ProcessedCustomMaterial::_setStageData()
          continue;
          continue;
       }
       }
 
 
+       if (filename.equal(String("$photometricmask"), String::NoCase))
+       {
+          rpd->mTexType[i] = Material::PhotometricMask;
+          rpd->mSamplerNames[i] = mCustomMaterial->mSamplerNames[i];
+          mMaxTex = i + 1;
+          continue;
+       }
+
       if(filename.equal(String("$lightmap"), String::NoCase))
       if(filename.equal(String("$lightmap"), String::NoCase))
       {
       {
          rpd->mTexType[i] = Material::Lightmap;
          rpd->mTexType[i] = Material::Lightmap;

+ 25 - 9
Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/pointLightP.hlsl

@@ -107,10 +107,13 @@ TORQUE_UNIFORM_SAMPLER2D(shadowMap, 1);
 #include "softShadow.hlsl"
 #include "softShadow.hlsl"
 TORQUE_UNIFORM_SAMPLER2D(colorBuffer, 3);
 TORQUE_UNIFORM_SAMPLER2D(colorBuffer, 3);
 TORQUE_UNIFORM_SAMPLER2D(matInfoBuffer, 4);
 TORQUE_UNIFORM_SAMPLER2D(matInfoBuffer, 4);
-#ifdef USE_COOKIE_TEX
 /// The texture for cookie rendering.
 /// The texture for cookie rendering.
+#ifdef SHADOW_CUBE
+TORQUE_UNIFORM_SAMPLERCUBE(cookieMap, 5);
+#else
 TORQUE_UNIFORM_SAMPLER2D(cookieMap, 5);
 TORQUE_UNIFORM_SAMPLER2D(cookieMap, 5);
 #endif
 #endif
+TORQUE_UNIFORM_SAMPLER2D(iesProfile, 6);
 
 
 uniform float4 rtParams0;
 uniform float4 rtParams0;
 uniform float4 lightColor;
 uniform float4 lightColor;
@@ -159,8 +162,8 @@ float4 main(   ConvexConnectP IN ) : SV_TARGET
 	{     
 	{     
       float distToLight = dist / lightRange;
       float distToLight = dist / lightRange;
       SurfaceToLight surfaceToLight = createSurfaceToLight(surface, L);
       SurfaceToLight surfaceToLight = createSurfaceToLight(surface, L);
-
-   float shadow = 1.0;
+      float3 lightCol = lightColor.rgb;
+      float shadow = 1.0;
    #ifndef NO_SHADOW
    #ifndef NO_SHADOW
    if (getFlag(surface.matFlag, 0)) //also skip if we don't recieve shadows
    if (getFlag(surface.matFlag, 0)) //also skip if we don't recieve shadows
    {
    {
@@ -176,8 +179,21 @@ float4 main(   ConvexConnectP IN ) : SV_TARGET
       #endif
       #endif
    }
    }
    #endif // !NO_SHADOW
    #endif // !NO_SHADOW
-   
-      float3 lightCol = lightColor.rgb;
+   #ifdef USE_COOKIE_TEX
+      // Lookup the cookie sample.
+      #ifdef SHADOW_CUBE
+      float4 cookie = TORQUE_TEXCUBE(cookieMap, mul(worldToLightProj, -surfaceToLight.L));
+      #else
+      float2 cookieCoord = decodeShadowCoord( mul( worldToLightProj, -surfaceToLight.L ) ).xy;
+      float4 cookie = TORQUE_TEX2D(cookieMap, cookieCoord);
+      #endif
+      // Multiply the light with the cookie tex.
+      lightCol *= cookie.rgb;
+      // Use a maximum channel luminance to attenuate 
+      // the lighting else we get specular in the dark
+      // regions of the cookie texture.
+      lightCol *= max(cookie.r, max(cookie.g, cookie.b));
+   #endif
    #ifdef DIFFUSE_LIGHT_VIZ
    #ifdef DIFFUSE_LIGHT_VIZ
       float attenuation = getDistanceAtt(surfaceToLight.Lu, radius);
       float attenuation = getDistanceAtt(surfaceToLight.Lu, radius);
       float3 factor = lightColor * max(surfaceToLight.NdotL, 0) * shadow * lightIntensity * attenuation;
       float3 factor = lightColor * max(surfaceToLight.NdotL, 0) * shadow * lightIntensity * attenuation;
@@ -210,13 +226,13 @@ float4 main(   ConvexConnectP IN ) : SV_TARGET
       //get punctual light contribution   
       //get punctual light contribution   
       lighting = getPunctualLight(surface, surfaceToLight, lightCol, lightBrightness, lightInvSqrRange, shadow);
       lighting = getPunctualLight(surface, surfaceToLight, lightCol, lightBrightness, lightInvSqrRange, shadow);
 
 
-   #ifdef USE_COOKIE_TEX
+   #ifdef UES_PHOTOMETRIC_MASK
       // Lookup the cookie sample.d
       // Lookup the cookie sample.d
       float cosTheta = dot(-surfaceToLight.L, lightDirection); 
       float cosTheta = dot(-surfaceToLight.L, lightDirection); 
       float angle = acos(cosTheta) * ( M_1OVER_PI_F); 
       float angle = acos(cosTheta) * ( M_1OVER_PI_F); 
-      float cookie = TORQUE_TEX2D(cookieMap, float2(angle, 0.0)).r; 
-      // Multiply the light with the cookie tex.
-      lighting *= cookie;
+      float iesMask = TORQUE_TEX2D(iesProfile, float2(angle, 0.0)).r; 
+      // Multiply the light with the iesMask tex.
+      lighting *= iesMask;
    #endif
    #endif
    }
    }
    
    

+ 20 - 9
Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/spotLightP.hlsl

@@ -42,11 +42,10 @@ TORQUE_UNIFORM_SAMPLER2D(shadowMap, 1);
 #include "softShadow.hlsl"
 #include "softShadow.hlsl"
 TORQUE_UNIFORM_SAMPLER2D(colorBuffer, 3);
 TORQUE_UNIFORM_SAMPLER2D(colorBuffer, 3);
 TORQUE_UNIFORM_SAMPLER2D(matInfoBuffer, 4);
 TORQUE_UNIFORM_SAMPLER2D(matInfoBuffer, 4);
-#ifdef USE_COOKIE_TEX
 /// The texture for cookie rendering.
 /// The texture for cookie rendering.
 TORQUE_UNIFORM_SAMPLER2D(cookieMap, 5);
 TORQUE_UNIFORM_SAMPLER2D(cookieMap, 5);
+TORQUE_UNIFORM_SAMPLER2D(iesProfile, 6);
 
 
-#endif
 uniform float4 rtParams0;
 uniform float4 rtParams0;
 
 
 uniform float  lightBrightness;
 uniform float  lightBrightness;
@@ -96,8 +95,7 @@ float4 main(   ConvexConnectP IN ) : SV_TARGET
 	if(dist < lightRange)
 	if(dist < lightRange)
 	{     
 	{     
       SurfaceToLight surfaceToLight = createSurfaceToLight(surface, L);
       SurfaceToLight surfaceToLight = createSurfaceToLight(surface, L);
-      float3 lightCol = lightColor.rgb;
-         
+      
       float shadow = 1.0; 
       float shadow = 1.0; 
       #ifndef NO_SHADOW      
       #ifndef NO_SHADOW      
       if (getFlag(surface.matFlag, 0)) //also skip if we don't recieve shadows
       if (getFlag(surface.matFlag, 0)) //also skip if we don't recieve shadows
@@ -109,10 +107,23 @@ float4 main(   ConvexConnectP IN ) : SV_TARGET
          //distance to light in shadow map space
          //distance to light in shadow map space
          float distToLight = pxlPosLightProj.z / lightRange;
          float distToLight = pxlPosLightProj.z / lightRange;
          shadow = softShadow_filter(TORQUE_SAMPLER2D_MAKEARG(shadowMap), ssPos.xy, shadowCoord, shadowSoftness, distToLight, surfaceToLight.NdotL, lightParams.y);
          shadow = softShadow_filter(TORQUE_SAMPLER2D_MAKEARG(shadowMap), ssPos.xy, shadowCoord, shadowSoftness, distToLight, surfaceToLight.NdotL, lightParams.y);
-         
       }
       }
       #endif
       #endif
 
 
+   float3 lightCol = lightColor.rgb;
+   #ifdef USE_COOKIE_TEX
+      float4 pxlPosLightProj = mul( worldToLightProj, float4( surface.P, 1 ) );
+      float2 cookieCoord = ( ( pxlPosLightProj.xy / pxlPosLightProj.w ) * 0.5 ) + float2( 0.5, 0.5 );
+      // Lookup the cookie sample.
+      float4 cookie = TORQUE_TEX2D(cookieMap, cookieCoord);
+      // Multiply the light with the cookie tex.
+      lightCol *= cookie.rgb;
+      // Use a maximum channel luminance to attenuate 
+      // the lighting else we get specular in the dark
+      // regions of the cookie texture.
+      lightCol *= max(cookie.r, max(cookie.g, cookie.b));
+   #endif
+
    #ifdef DIFFUSE_LIGHT_VIZ
    #ifdef DIFFUSE_LIGHT_VIZ
       float attenuation = getDistanceAtt(surfaceToLight.Lu, radius);
       float attenuation = getDistanceAtt(surfaceToLight.Lu, radius);
       float3 factor = lightColor * max(surfaceToLight.NdotL, 0) * shadow * lightIntensity * attenuation;
       float3 factor = lightColor * max(surfaceToLight.NdotL, 0) * shadow * lightIntensity * attenuation;
@@ -144,13 +155,13 @@ float4 main(   ConvexConnectP IN ) : SV_TARGET
 
 
       //get spot light contribution   
       //get spot light contribution   
       lighting = getSpotlight(surface, surfaceToLight, lightCol, lightBrightness, lightInvSqrRange, lightDirection, lightSpotParams, shadow);
       lighting = getSpotlight(surface, surfaceToLight, lightCol, lightBrightness, lightInvSqrRange, lightDirection, lightSpotParams, shadow);
-      #ifdef USE_COOKIE_TEX
+      #ifdef UES_PHOTOMETRIC_MASK
          // Lookup the cookie sample.d
          // Lookup the cookie sample.d
          float cosTheta = dot(-surfaceToLight.L, lightDirection); 
          float cosTheta = dot(-surfaceToLight.L, lightDirection); 
          float angle = acos(cosTheta) * ( M_1OVER_PI_F); 
          float angle = acos(cosTheta) * ( M_1OVER_PI_F); 
-         float cookie = TORQUE_TEX2D(cookieMap, float2(angle, 0.0)).r; 
-         // Multiply the light with the cookie tex.
-         lighting *= cookie;
+         float iesMask = TORQUE_TEX2D(iesProfile, float2(angle, 0.0)).r; 
+         // Multiply the light with the iesMask tex.
+         lighting *= iesMask;
       #endif 
       #endif 
    }
    }