advancedLightingFeaturesHLSL.cpp
Engine/source/lighting/advanced/hlsl/advancedLightingFeaturesHLSL.cpp
Detailed Description
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "platform/platform.h" 25#include "lighting/advanced/hlsl/advancedLightingFeaturesHLSL.h" 26 27#include "lighting/advanced/advancedLightBinManager.h" 28#include "shaderGen/langElement.h" 29#include "shaderGen/shaderOp.h" 30#include "shaderGen/conditionerFeature.h" 31#include "renderInstance/renderDeferredMgr.h" 32#include "materials/processedMaterial.h" 33#include "materials/materialFeatureTypes.h" 34 35 36void DeferredRTLightingFeatHLSL::processPixMacros( Vector<GFXShaderMacro> ¯os, 37 const MaterialFeatureData &fd ) 38{ 39 // Skip deferred features, and use forward shading instead 40 if ( !fd.features[MFT_isDeferred] ) 41 { 42 Parent::processPixMacros( macros, fd ); 43 return; 44 } 45 46 // Pull in the uncondition method for the light info buffer 47 NamedTexTarget *texTarget = NamedTexTarget::find( AdvancedLightBinManager::smBufferName ); 48 if ( texTarget && texTarget->getConditioner() ) 49 { 50 ConditionerMethodDependency *unconditionMethod = texTarget->getConditioner()->getConditionerMethodDependency(ConditionerFeature::UnconditionMethod); 51 unconditionMethod->createMethodMacro( String::ToLower( AdvancedLightBinManager::smBufferName ) + "Uncondition", macros ); 52 addDependency(unconditionMethod); 53 } 54} 55 56void DeferredRTLightingFeatHLSL::processVert( Vector<ShaderComponent*> &componentList, 57 const MaterialFeatureData &fd ) 58{ 59 // Skip deferred features, and use forward shading instead 60 if ( !fd.features[MFT_isDeferred] ) 61 { 62 Parent::processVert( componentList, fd ); 63 return; 64 } 65 66 // Pass screen space position to pixel shader to compute a full screen buffer uv 67 ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] ); 68 Var *ssPos = connectComp->getElement( RT_TEXCOORD ); 69 ssPos->setName( "screenspacePos" ); 70 ssPos->setStructName( "OUT" ); 71 ssPos->setType( "float4" ); 72 73 Var *outPosition = (Var*) LangElement::find( "hpos" ); 74 AssertFatal( outPosition, "No hpos, ohnoes." ); 75 76 output = new GenOp( " @ = @;\r\n", ssPos, outPosition ); 77} 78 79void DeferredRTLightingFeatHLSL::processPix( Vector<ShaderComponent*> &componentList, 80 const MaterialFeatureData &fd ) 81{ 82 // Skip deferred features, and use forward shading instead 83 84 if ( !fd.features[MFT_isDeferred] ) 85 { 86 Parent::processPix(componentList, fd); 87 return; 88 } 89 90 MultiLine *meta = new MultiLine; 91 92 ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>(componentList[C_CONNECTOR]); 93 Var *ssPos = connectComp->getElement(RT_TEXCOORD); 94 ssPos->setName("screenspacePos"); 95 ssPos->setStructName("IN"); 96 ssPos->setType("float4"); 97 98 Var *uvScene = new Var; 99 uvScene->setType("float2"); 100 uvScene->setName("uvScene"); 101 LangElement *uvSceneDecl = new DecOp(uvScene); 102 103 String rtParamName = String::ToString("rtParams%s", "diffuseLightingBuffer"); 104 Var *rtParams = (Var*)LangElement::find(rtParamName); 105 if (!rtParams) 106 { 107 rtParams = new Var; 108 rtParams->setType("float4"); 109 rtParams->setName(rtParamName); 110 rtParams->uniform = true; 111 rtParams->constSortPos = cspPass; 112 } 113 114 meta->addStatement( new GenOp( " @ = @.xy / @.w;\r\n", uvSceneDecl, ssPos, ssPos ) ); // get the screen coord... its -1 to +1 115 meta->addStatement( new GenOp( " @ = ( @ + 1.0 ) / 2.0;\r\n", uvScene, uvScene ) ); // get the screen coord to 0 to 1 116 meta->addStatement( new GenOp( " @.y = 1.0 - @.y;\r\n", uvScene, uvScene ) ); // flip the y axis 117 meta->addStatement( new GenOp( " @ = ( @ * @.zw ) + @.xy;\r\n", uvScene, uvScene, rtParams, rtParams) ); // scale it down and offset it to the rt size 118 119 // create texture var 120 Var *lightInfoBuffer = new Var; 121 lightInfoBuffer->setType( "SamplerState" ); 122 lightInfoBuffer->setName( "lightInfoBuffer" ); 123 lightInfoBuffer->uniform = true; 124 lightInfoBuffer->sampler = true; 125 lightInfoBuffer->constNum = Var::getTexUnitNum(); // used as texture unit num here 126 127 Var* lightBufferTex = new Var; 128 lightBufferTex->setName("lightInfoBufferTex"); 129 lightBufferTex->setType("Texture2D"); 130 lightBufferTex->uniform = true; 131 lightBufferTex->texture = true; 132 lightBufferTex->constNum = lightInfoBuffer->constNum; 133 134 // Declare the RTLighting variables in this feature, they will either be assigned 135 // in this feature, or in the tonemap/lightmap feature 136 Var *d_lightcolor = new Var( "d_lightcolor", "float3" ); 137 meta->addStatement( new GenOp( " @;\r\n", new DecOp( d_lightcolor ) ) ); 138 139 Var *d_NL_Att = new Var( "d_NL_Att", "float" ); 140 meta->addStatement( new GenOp( " @;\r\n", new DecOp( d_NL_Att ) ) ); 141 142 Var *d_specular = new Var( "d_specular", "float" ); 143 meta->addStatement( new GenOp( " @;\r\n", new DecOp( d_specular ) ) ); 144 145 146 // Perform the uncondition here. 147 String unconditionLightInfo = String::ToLower( AdvancedLightBinManager::smBufferName ) + "Uncondition"; 148 meta->addStatement(new GenOp(avar(" %s(@.Sample(@, @), @, @, @);\r\n", 149 unconditionLightInfo.c_str()), lightBufferTex, lightInfoBuffer, uvScene, d_lightcolor, d_NL_Att, d_specular)); 150 151 // This is kind of weak sauce 152 if( !fd.features[MFT_VertLit] && !fd.features[MFT_ToneMap] && !fd.features[MFT_LightMap] && !fd.features[MFT_SubSurface] ) 153 meta->addStatement( new GenOp( " @;\r\n", assignColor( new GenOp( "float4(@, 1.0)", d_lightcolor ), Material::Mul ) ) ); 154 155 output = meta; 156} 157 158ShaderFeature::Resources DeferredRTLightingFeatHLSL::getResources( const MaterialFeatureData &fd ) 159{ 160 // Skip deferred features, and use forward shading instead 161 if ( !fd.features[MFT_isDeferred] ) 162 return Parent::getResources( fd ); 163 164 // HACK: See DeferredRTLightingFeatHLSL::setTexData. 165 mLastTexIndex = 0; 166 167 Resources res; 168 res.numTex = 1; 169 res.numTexReg = 1; 170 return res; 171} 172 173void DeferredRTLightingFeatHLSL::setTexData( Material::StageData &stageDat, 174 const MaterialFeatureData &fd, 175 RenderPassData &passData, 176 U32 &texIndex ) 177{ 178 // Skip deferred features, and use forward shading instead 179 if ( !fd.features[MFT_isDeferred] ) 180 { 181 Parent::setTexData( stageDat, fd, passData, texIndex ); 182 return; 183 } 184 185 NamedTexTarget *texTarget = NamedTexTarget::find( AdvancedLightBinManager::smBufferName ); 186 if( texTarget ) 187 { 188 // HACK: We store this for use in DeferredRTLightingFeatHLSL::processPix() 189 // which cannot deduce the texture unit itself. 190 mLastTexIndex = texIndex; 191 192 passData.mTexType[ texIndex ] = Material::TexTarget; 193 passData.mSamplerNames[ texIndex ]= "diffuseLightingBuffer"; 194 passData.mTexSlot[ texIndex++ ].texTarget = texTarget; 195 } 196} 197 198 199void DeferredBumpFeatHLSL::processVert( Vector<ShaderComponent*> &componentList, 200 const MaterialFeatureData &fd ) 201{ 202 if( fd.features[MFT_DeferredConditioner] ) 203 { 204 // There is an output conditioner active, so we need to supply a transform 205 // to the pixel shader. 206 MultiLine *meta = new MultiLine; 207 208 // We need the view to tangent space transform in the pixel shader. 209 getOutViewToTangent( componentList, meta, fd ); 210 211 const bool useTexAnim = fd.features[MFT_TexAnim]; 212 // Make sure there are texcoords 213 if( !fd.features[MFT_Parallax] && !fd.features[MFT_DiffuseMap]) 214 { 215 216 getOutTexCoord( "texCoord", 217 "float2", 218 useTexAnim, 219 meta, 220 componentList ); 221 } 222 223 const bool useFoliageTexCoord = fd.features[MFT_Foliage]; 224 225 if ( fd.features.hasFeature( MFT_DetailNormalMap ) ) 226 addOutDetailTexCoord( componentList, 227 meta, 228 useTexAnim, useFoliageTexCoord); 229 230 output = meta; 231 } 232 else if ( fd.materialFeatures[MFT_NormalsOut] || 233 !fd.features[MFT_isDeferred] || 234 !fd.features[MFT_RTLighting] ) 235 { 236 Parent::processVert( componentList, fd ); 237 return; 238 } 239 else 240 { 241 output = NULL; 242 } 243} 244 245void DeferredBumpFeatHLSL::processPix( Vector<ShaderComponent*> &componentList, 246 const MaterialFeatureData &fd ) 247{ 248 // NULL output in case nothing gets handled 249 output = NULL; 250 251 if( fd.features[MFT_DeferredConditioner] ) 252 { 253 MultiLine *meta = new MultiLine; 254 255 Var *viewToTangent = getInViewToTangent( componentList ); 256 257 // create texture var 258 Var *bumpMap = getNormalMapTex(); 259 Var *texCoord = getInTexCoord("texCoord", "float2", componentList); 260 261 Var *bumpMapTex = (Var*)LangElement::find("bumpMapTex"); 262 LangElement *texOp = new GenOp("@.Sample(@, @)", bumpMapTex, bumpMap, texCoord); 263 264 // create bump normal 265 Var *bumpNorm = new Var; 266 bumpNorm->setName( "bumpNormal" ); 267 bumpNorm->setType( "float4" ); 268 269 LangElement *bumpNormDecl = new DecOp( bumpNorm ); 270 meta->addStatement( expandNormalMap( texOp, bumpNormDecl, bumpNorm, fd ) ); 271 272 // If we have a detail normal map we add the xy coords of 273 // it to the base normal map. This gives us the effect we 274 // want with few instructions and minial artifacts. 275 if ( fd.features.hasFeature( MFT_DetailNormalMap ) ) 276 { 277 bumpMap = new Var; 278 bumpMap->setType( "SamplerState" ); 279 bumpMap->setName( "detailBumpMap" ); 280 bumpMap->uniform = true; 281 bumpMap->sampler = true; 282 bumpMap->constNum = Var::getTexUnitNum(); 283 284 Var* detailNormalTex = new Var; 285 detailNormalTex->setName("detailBumpMapTex"); 286 detailNormalTex->setType("Texture2D"); 287 detailNormalTex->uniform = true; 288 detailNormalTex->texture = true; 289 detailNormalTex->constNum = bumpMap->constNum; 290 291 texCoord = getInTexCoord("detCoord", "float2", componentList); 292 293 texOp = new GenOp("@.Sample(@, @)", detailNormalTex, bumpMap, texCoord); 294 295 Var *detailBump = new Var; 296 detailBump->setName( "detailBump" ); 297 detailBump->setType( "float4" ); 298 meta->addStatement( expandNormalMap( texOp, new DecOp( detailBump ), detailBump, fd ) ); 299 300 Var *detailBumpScale = new Var; 301 detailBumpScale->setType( "float" ); 302 detailBumpScale->setName( "detailBumpStrength" ); 303 detailBumpScale->uniform = true; 304 detailBumpScale->constSortPos = cspPass; 305 meta->addStatement( new GenOp( " @.xy += @.xy * @;\r\n", bumpNorm, detailBump, detailBumpScale ) ); 306 } 307 308 // This var is read from GBufferConditionerHLSL and 309 // used in the deferred output. 310 // 311 // By using the 'half' type here we get a bunch of partial 312 // precision optimized code on further operations on the normal 313 // which helps alot on older Geforce cards. 314 // 315 Var *gbNormal = new Var; 316 gbNormal->setName( "gbNormal" ); 317 gbNormal->setType( "half3" ); 318 LangElement *gbNormalDecl = new DecOp( gbNormal ); 319 320 // Normalize is done later... 321 // Note: The reverse mul order is intentional. Affine matrix. 322 meta->addStatement( new GenOp( " @ = (half3)mul( @.xyz, @ );\r\n", gbNormalDecl, bumpNorm, viewToTangent ) ); 323 324 output = meta; 325 return; 326 } 327 else if (fd.features[MFT_AccuMap]) 328 { 329 Var *bumpSample = (Var *)LangElement::find( "bumpSample" ); 330 if (bumpSample == NULL) 331 { 332 MultiLine *meta = new MultiLine; 333 334 Var *texCoord = getInTexCoord("texCoord", "float2", componentList); 335 336 Var *bumpMap = getNormalMapTex(); 337 338 bumpSample = new Var; 339 bumpSample->setType("float4"); 340 bumpSample->setName("bumpSample"); 341 LangElement *bumpSampleDecl = new DecOp(bumpSample); 342 343 Var *bumpMapTex = (Var *)LangElement::find("bumpMapTex"); 344 output = new GenOp(" @ = @.Sample(@, @);\r\n", bumpSampleDecl, bumpMapTex, bumpMap, texCoord); 345 346 if ( fd.features.hasFeature( MFT_DetailNormalMap ) ) 347 { 348 bumpMap = (Var*)LangElement::find( "detailBumpMap" ); 349 if ( !bumpMap ) 350 { 351 bumpMap = new Var; 352 bumpMap->setType( "sampler2D" ); 353 bumpMap->setName( "detailBumpMap" ); 354 bumpMap->uniform = true; 355 bumpMap->sampler = true; 356 bumpMap->constNum = Var::getTexUnitNum(); 357 } 358 359 bumpMapTex = (Var*)LangElement::find("detailBumpMap"); 360 if (!bumpMapTex) 361 { 362 bumpMap->setType("SamplerState"); 363 bumpMapTex = new Var; 364 bumpMapTex->setName("detailBumpMapTex"); 365 bumpMapTex->setType("Texture2D"); 366 bumpMapTex->uniform = true; 367 bumpMapTex->texture = true; 368 bumpMapTex->constNum = bumpMap->constNum; 369 } 370 371 texCoord = getInTexCoord( "detCoord", "float2", componentList ); 372 LangElement *texOp = new GenOp("@.Sample(@, @)", bumpMap, bumpMapTex, texCoord); 373 374 Var *detailBump = new Var; 375 detailBump->setName( "detailBump" ); 376 detailBump->setType( "float4" ); 377 meta->addStatement( expandNormalMap( texOp, new DecOp( detailBump ), detailBump, fd ) ); 378 379 Var *detailBumpScale = new Var; 380 detailBumpScale->setType( "float" ); 381 detailBumpScale->setName( "detailBumpStrength" ); 382 detailBumpScale->uniform = true; 383 detailBumpScale->constSortPos = cspPass; 384 meta->addStatement( new GenOp( " @.xy += @.xy * @;\r\n", bumpSample, detailBump, detailBumpScale ) ); 385 } 386 387 output = meta; 388 389 return; 390 } 391 } 392 else if ( fd.materialFeatures[MFT_NormalsOut] || 393 !fd.features[MFT_isDeferred] || 394 !fd.features[MFT_RTLighting] ) 395 { 396 Parent::processPix( componentList, fd ); 397 return; 398 } 399 else if (!fd.features[MFT_OrmMap] ) 400 { 401 Var *bumpSample = (Var *)LangElement::find( "bumpSample" ); 402 if( bumpSample == NULL ) 403 { 404 Var *texCoord = getInTexCoord( "texCoord", "float2", componentList ); 405 406 Var *bumpMap = getNormalMapTex(); 407 Var *bumpMapTex = (Var *)LangElement::find("bumpMapTex"); 408 409 bumpSample = new Var; 410 bumpSample->setType("float4"); 411 bumpSample->setName("bumpSample"); 412 413 LangElement *bumpSampleDecl = new DecOp(bumpSample); 414 output = new GenOp(" @ = @.Sample(@, @);\r\n", bumpSampleDecl, bumpMapTex, bumpMap, texCoord); 415 416 return; 417 } 418 } 419 420 output = NULL; 421} 422 423ShaderFeature::Resources DeferredBumpFeatHLSL::getResources( const MaterialFeatureData &fd ) 424{ 425 if ( fd.materialFeatures[MFT_NormalsOut] || 426 !fd.features[MFT_isDeferred] || 427 fd.features[MFT_Parallax] || 428 !fd.features[MFT_RTLighting] ) 429 return Parent::getResources( fd ); 430 431 Resources res; 432 if(!fd.features[MFT_OrmMap]) 433 { 434 res.numTex = 1; 435 res.numTexReg = 1; 436 437 if ( fd.features[MFT_DeferredConditioner] && 438 fd.features.hasFeature( MFT_DetailNormalMap ) ) 439 { 440 res.numTex += 1; 441 if ( !fd.features.hasFeature( MFT_DetailMap ) ) 442 res.numTexReg += 1; 443 } 444 } 445 446 return res; 447} 448 449void DeferredBumpFeatHLSL::setTexData( Material::StageData &stageDat, 450 const MaterialFeatureData &fd, 451 RenderPassData &passData, 452 U32 &texIndex ) 453{ 454 if ( fd.materialFeatures[MFT_NormalsOut] || 455 !fd.features[MFT_isDeferred] || 456 !fd.features[MFT_RTLighting] ) 457 { 458 Parent::setTexData( stageDat, fd, passData, texIndex ); 459 return; 460 } 461 462 if ( !fd.features[MFT_DeferredConditioner] && fd.features[MFT_AccuMap] ) 463 { 464 passData.mTexType[ texIndex ] = Material::Bump; 465 passData.mSamplerNames[ texIndex ] = "bumpMap"; 466 passData.mTexSlot[ texIndex++ ].texObject = stageDat.getTex( MFT_NormalMap ); 467 468 if ( fd.features.hasFeature( MFT_DetailNormalMap ) ) 469 { 470 passData.mTexType[ texIndex ] = Material::DetailBump; 471 passData.mSamplerNames[texIndex] = "detailBumpMap"; 472 passData.mTexSlot[ texIndex++ ].texObject = stageDat.getTex( MFT_DetailNormalMap ); 473 } 474 } 475 else if ( !fd.features[MFT_Parallax] && !fd.features[MFT_OrmMap] && 476 ( fd.features[MFT_DeferredConditioner]) ) 477 { 478 passData.mTexType[ texIndex ] = Material::Bump; 479 passData.mSamplerNames[ texIndex ] = "bumpMap"; 480 passData.mTexSlot[ texIndex++ ].texObject = stageDat.getTex( MFT_NormalMap ); 481 482 if ( fd.features[MFT_DeferredConditioner] && 483 fd.features.hasFeature( MFT_DetailNormalMap ) ) 484 { 485 passData.mTexType[ texIndex ] = Material::DetailBump; 486 passData.mSamplerNames[ texIndex ] = "detailBumpMap"; 487 passData.mTexSlot[ texIndex++ ].texObject = stageDat.getTex( MFT_DetailNormalMap ); 488 } 489 } 490} 491 492ShaderFeature::Resources DeferredMinnaertHLSL::getResources( const MaterialFeatureData &fd ) 493{ 494 Resources res; 495 if( fd.features[MFT_isDeferred] && fd.features[MFT_RTLighting] ) 496 { 497 res.numTex = 1; 498 res.numTexReg = 1; 499 } 500 return res; 501} 502 503void DeferredMinnaertHLSL::setTexData( Material::StageData &stageDat, 504 const MaterialFeatureData &fd, 505 RenderPassData &passData, 506 U32 &texIndex ) 507{ 508 if( fd.features[MFT_isDeferred] && fd.features[MFT_RTLighting] ) 509 { 510 NamedTexTarget *texTarget = NamedTexTarget::find(RenderDeferredMgr::BufferName); 511 if ( texTarget ) 512 { 513 passData.mTexType[texIndex] = Material::TexTarget; 514 passData.mSamplerNames[texIndex] = "deferredBuffer"; 515 passData.mTexSlot[ texIndex++ ].texTarget = texTarget; 516 } 517 } 518} 519 520void DeferredMinnaertHLSL::processPixMacros( Vector<GFXShaderMacro> ¯os, 521 const MaterialFeatureData &fd ) 522{ 523 if( fd.features[MFT_isDeferred] && fd.features[MFT_RTLighting] ) 524 { 525 // Pull in the uncondition method for the g buffer 526 NamedTexTarget *texTarget = NamedTexTarget::find( RenderDeferredMgr::BufferName ); 527 if ( texTarget && texTarget->getConditioner() ) 528 { 529 ConditionerMethodDependency *unconditionMethod = texTarget->getConditioner()->getConditionerMethodDependency(ConditionerFeature::UnconditionMethod); 530 unconditionMethod->createMethodMacro( String::ToLower(RenderDeferredMgr::BufferName) + "Uncondition", macros ); 531 addDependency(unconditionMethod); 532 } 533 } 534} 535 536void DeferredMinnaertHLSL::processVert( Vector<ShaderComponent*> &componentList, 537 const MaterialFeatureData &fd ) 538{ 539 // If there is no deferred information, bail on this feature 540 if( !fd.features[MFT_isDeferred] || !fd.features[MFT_RTLighting] ) 541 { 542 output = NULL; 543 return; 544 } 545 546 // Make sure we pass the world space position to the 547 // pixel shader so we can calculate a view vector. 548 MultiLine *meta = new MultiLine; 549 addOutWsPosition( componentList, fd.features[MFT_UseInstancing], meta ); 550 output = meta; 551} 552 553void DeferredMinnaertHLSL::processPix( Vector<ShaderComponent*> &componentList, 554 const MaterialFeatureData &fd ) 555{ 556 // If there is no deferred information, bail on this feature 557 if( !fd.features[MFT_isDeferred] || !fd.features[MFT_RTLighting] ) 558 { 559 output = NULL; 560 return; 561 } 562 563 Var *minnaertConstant = new Var; 564 minnaertConstant->setType( "float" ); 565 minnaertConstant->setName( "minnaertConstant" ); 566 minnaertConstant->uniform = true; 567 minnaertConstant->constSortPos = cspPotentialPrimitive; 568 569 // create texture var 570 Var *deferredBuffer = new Var; 571 deferredBuffer->setType( "SamplerState" ); 572 deferredBuffer->setName( "deferredBuffer" ); 573 deferredBuffer->uniform = true; 574 deferredBuffer->sampler = true; 575 deferredBuffer->constNum = Var::getTexUnitNum(); // used as texture unit num here 576 577 Var* deferredTex = new Var; 578 deferredTex->setName("deferredTex"); 579 deferredTex->setType("Texture2D"); 580 deferredTex->uniform = true; 581 deferredTex->texture = true; 582 deferredTex->constNum = deferredBuffer->constNum; 583 584 // Texture coord 585 Var *uvScene = (Var*) LangElement::find( "uvScene" ); 586 AssertFatal(uvScene != NULL, "Unable to find UVScene, no RTLighting feature?"); 587 588 MultiLine *meta = new MultiLine; 589 590 // Get the world space view vector. 591 Var *wsViewVec = getWsView( getInWsPosition( componentList ), meta ); 592 593 String unconditionDeferredMethod = String::ToLower(RenderDeferredMgr::BufferName) + "Uncondition"; 594 595 Var *d_NL_Att = (Var*)LangElement::find( "d_NL_Att" ); 596 597 meta->addStatement(new GenOp(avar(" float4 normalDepth = %s(@, ,@, @);\r\n", unconditionDeferredMethod.c_str()), deferredBuffer, deferredTex, uvScene)); 598 599 meta->addStatement( new GenOp( " float vDotN = dot(normalDepth.xyz, @);\r\n", wsViewVec ) ); 600 meta->addStatement( new GenOp( " float Minnaert = pow( @, @) * pow(vDotN, 1.0 - @);\r\n", d_NL_Att, minnaertConstant, minnaertConstant ) ); 601 meta->addStatement( new GenOp( " @;\r\n", assignColor( new GenOp( "float4(Minnaert, Minnaert, Minnaert, 1.0)" ), Material::Mul ) ) ); 602 603 output = meta; 604} 605 606 607void DeferredSubSurfaceHLSL::processPix( Vector<ShaderComponent*> &componentList, 608 const MaterialFeatureData &fd ) 609{ 610 611 Var *subSurfaceParams = new Var; 612 subSurfaceParams->setType( "float4" ); 613 subSurfaceParams->setName( "subSurfaceParams" ); 614 subSurfaceParams->uniform = true; 615 subSurfaceParams->constSortPos = cspPotentialPrimitive; 616 617 Var *d_lightcolor = (Var*)LangElement::find( "d_lightcolor" ); 618 Var *d_NL_Att = (Var*)LangElement::find( "d_NL_Att" ); 619 620 MultiLine *meta = new MultiLine; 621 Var* targ = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::DefaultTarget)); 622 if (fd.features[MFT_isDeferred]) 623 { 624 targ = (Var*)LangElement::find(getOutputTargetVarName(ShaderFeature::RenderTarget3)); 625 meta->addStatement(new GenOp(" @.rgb += @.rgb*@.a;\r\n", targ, subSurfaceParams, subSurfaceParams)); 626 output = meta; 627 return; 628 } 629 630 output = meta; 631} 632