terrFeatureHLSL.cpp
Engine/source/terrain/hlsl/terrFeatureHLSL.cpp
Public Variables
Detailed Description
Public Variables
MODULE_END
MODULE_INIT
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 "terrain/hlsl/terrFeatureHLSL.h" 26 27#include "terrain/terrFeatureTypes.h" 28#include "materials/materialFeatureTypes.h" 29#include "materials/materialFeatureData.h" 30#include "materials/processedMaterial.h" 31#include "gfx/gfxDevice.h" 32#include "shaderGen/langElement.h" 33#include "shaderGen/shaderOp.h" 34#include "shaderGen/featureMgr.h" 35#include "shaderGen/shaderGen.h" 36#include "core/module.h" 37 38namespace 39{ 40 void register_hlsl_shader_features_for_terrain(GFXAdapterType type) 41 { 42 if (type != Direct3D9 && type != Direct3D9_360 && type != Direct3D11) 43 return; 44 45 FEATUREMGR->registerFeature( MFT_TerrainBaseMap, new TerrainBaseMapFeatHLSL ); 46 FEATUREMGR->registerFeature( MFT_TerrainParallaxMap, new NamedFeatureHLSL( "Terrain Parallax Texture" ) ); 47 FEATUREMGR->registerFeature( MFT_TerrainDetailMap, new TerrainDetailMapFeatHLSL ); 48 FEATUREMGR->registerFeature( MFT_TerrainNormalMap, new TerrainNormalMapFeatHLSL ); 49 FEATUREMGR->registerFeature( MFT_TerrainMacroMap, new TerrainMacroMapFeatHLSL ); 50 FEATUREMGR->registerFeature( MFT_TerrainLightMap, new TerrainLightMapFeatHLSL ); 51 FEATUREMGR->registerFeature( MFT_TerrainSideProject, new NamedFeatureHLSL( "Terrain Side Projection" ) ); 52 FEATUREMGR->registerFeature( MFT_TerrainAdditive, new TerrainAdditiveFeatHLSL ); 53 FEATUREMGR->registerFeature( MFT_DeferredTerrainBaseMap, new TerrainBaseMapFeatHLSL ); 54 FEATUREMGR->registerFeature( MFT_DeferredTerrainMacroMap, new TerrainMacroMapFeatHLSL ); 55 FEATUREMGR->registerFeature( MFT_DeferredTerrainDetailMap, new TerrainDetailMapFeatHLSL ); 56 FEATUREMGR->registerFeature( MFT_DeferredTerrainBlankInfoMap, new TerrainBlankInfoMapFeatHLSL ); 57 } 58}; 59 60MODULE_BEGIN( TerrainFeatHLSL ) 61 62 MODULE_INIT_AFTER( ShaderGen ) 63 64 MODULE_INIT 65 { 66 SHADERGEN->getFeatureInitSignal().notify(®ister_hlsl_shader_features_for_terrain); 67 } 68 69MODULE_END; 70 71 72TerrainFeatHLSL::TerrainFeatHLSL() 73 : mTorqueDep( "shaders/common/torque.hlsl" ) 74{ 75 addDependency( &mTorqueDep ); 76} 77 78Var* TerrainFeatHLSL::_getUniformVar( const char *name, const char *type, ConstantSortPosition csp ) 79{ 80 Var *theVar = (Var*)LangElement::find( name ); 81 if ( !theVar ) 82 { 83 theVar = new Var; 84 theVar->setType( type ); 85 theVar->setName( name ); 86 theVar->uniform = true; 87 theVar->constSortPos = csp; 88 } 89 90 return theVar; 91} 92 93Var* TerrainFeatHLSL::_getInDetailCoord( Vector<ShaderComponent*> &componentList ) 94{ 95 String name( String::ToString( "detCoord%d", getProcessIndex() ) ); 96 Var *inDet = (Var*)LangElement::find( name ); 97 98 if ( !inDet ) 99 { 100 ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] ); 101 102 inDet = connectComp->getElement( RT_TEXCOORD ); 103 inDet->setName( name ); 104 inDet->setStructName( "IN" ); 105 inDet->setType( "float4" ); 106 inDet->mapsToSampler = true; 107 } 108 109 return inDet; 110} 111 112Var* TerrainFeatHLSL::_getInMacroCoord( Vector<ShaderComponent*> &componentList ) 113{ 114 String name( String::ToString( "macroCoord%d", getProcessIndex() ) ); 115 Var *inDet = (Var*)LangElement::find( name ); 116 117 if ( !inDet ) 118 { 119 ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] ); 120 121 inDet = connectComp->getElement( RT_TEXCOORD ); 122 inDet->setName( name ); 123 inDet->setStructName( "IN" ); 124 inDet->setType( "float4" ); 125 inDet->mapsToSampler = true; 126 } 127 128 return inDet; 129} 130 131Var* TerrainFeatHLSL::_getNormalMapTex() 132{ 133 String name(String::ToString("normalMap%d", getProcessIndex())); 134 Var *normalMap = (Var*)LangElement::find(name); 135 136 if (!normalMap) 137 { 138 normalMap = new Var; 139 if (mIsDirect3D11) 140 normalMap->setType("SamplerState"); 141 else 142 normalMap->setType("sampler2D"); 143 144 normalMap->setName(name); 145 normalMap->uniform = true; 146 normalMap->sampler = true; 147 normalMap->constNum = Var::getTexUnitNum(); 148 } 149 150 return normalMap; 151} 152 153Var* TerrainFeatHLSL::_getDetailIdStrengthParallax() 154{ 155 String name( String::ToString( "detailIdStrengthParallax%d", getProcessIndex() ) ); 156 157 Var *detailInfo = (Var*)LangElement::find( name ); 158 if ( !detailInfo ) 159 { 160 detailInfo = new Var; 161 detailInfo->setType( "float3" ); 162 detailInfo->setName( name ); 163 detailInfo->uniform = true; 164 detailInfo->constSortPos = cspPotentialPrimitive; 165 } 166 167 return detailInfo; 168} 169 170Var* TerrainFeatHLSL::_getMacroIdStrengthParallax() 171{ 172 String name( String::ToString( "macroIdStrengthParallax%d", getProcessIndex() ) ); 173 174 Var *detailInfo = (Var*)LangElement::find( name ); 175 if ( !detailInfo ) 176 { 177 detailInfo = new Var; 178 detailInfo->setType( "float3" ); 179 detailInfo->setName( name ); 180 detailInfo->uniform = true; 181 detailInfo->constSortPos = cspPotentialPrimitive; 182 } 183 184 return detailInfo; 185} 186 187 188void TerrainBaseMapFeatHLSL::processVert( Vector<ShaderComponent*> &componentList, 189 const MaterialFeatureData &fd ) 190{ 191 MultiLine *meta = new MultiLine; 192 output = meta; 193 194 // Generate the incoming texture var. 195 Var *inTex; 196 { 197 Var *inPos = (Var*)LangElement::find( "inPosition" ); 198 if ( !inPos ) 199 inPos = (Var*)LangElement::find( "position" ); 200 201 inTex = new Var( "texCoord", "float3" ); 202 203 Var *oneOverTerrainSize = _getUniformVar( "oneOverTerrainSize", "float", cspPass ); 204 205 // NOTE: The y coord here should be negative to have 206 // the texture maps not end up flipped which also caused 207 // normal and parallax mapping to be incorrect. 208 // 209 // This mistake early in development means that the layer 210 // id bilinear blend depends on it being that way. 211 // 212 // So instead i fixed this by flipping the base and detail 213 // coord y scale to compensate when rendering. 214 // 215 meta->addStatement( new GenOp( " @ = @.xyz * float3( @, @, -@ );\r\n", 216 new DecOp( inTex ), inPos, oneOverTerrainSize, oneOverTerrainSize, oneOverTerrainSize ) ); 217 } 218 219 ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] ); 220 221 // Pass the texture coord to the pixel shader. 222 Var *outTex = connectComp->getElement( RT_TEXCOORD ); 223 outTex->setName( "outTexCoord" ); 224 outTex->setStructName( "OUT" ); 225 outTex->setType( "float3" ); 226 outTex->mapsToSampler = true; 227 meta->addStatement( new GenOp( " @.xy = @.xy;\r\n", outTex, inTex ) ); 228 229 // If this shader has a side projected layer then we 230 // pass the dot product between the +Y and the normal 231 // thru outTexCoord.z for use in blending the textures. 232 if ( fd.features.hasFeature( MFT_TerrainSideProject ) ) 233 { 234 Var *inNormal = (Var*)LangElement::find( "normal" ); 235 meta->addStatement( 236 new GenOp( " @.z = pow( abs( dot( normalize( float3( @.x, @.y, 0 ) ), float3( 0, 1, 0 ) ) ), 10.0 );\r\n", 237 outTex, inNormal, inNormal ) ); 238 } 239 else 240 meta->addStatement( new GenOp( " @.z = 0;\r\n", outTex ) ); 241 242 // HACK: This is sort of lazy... we generate the tanget 243 // vector here so that we're sure it exists in the parallax 244 // and normal features which will expect "T" to exist. 245 // 246 // If this shader doesn't use it the shader compiler will 247 // optimize away this code. 248 // 249 Var *inTangentZ = getVertTexCoord( "tcTangentZ" ); 250 Var *inTanget = new Var( "T", "float3" ); 251 Var *squareSize = _getUniformVar( "squareSize", "float", cspPass ); 252 meta->addStatement( new GenOp( " @ = normalize( float3( @, 0, @ ) );\r\n", 253 new DecOp( inTanget ), squareSize, inTangentZ ) ); 254} 255 256void TerrainBaseMapFeatHLSL::processPix( Vector<ShaderComponent*> &componentList, 257 const MaterialFeatureData &fd ) 258{ 259 // grab connector texcoord register 260 Var *texCoord = getInTexCoord( "texCoord", "float3", true, componentList ); 261 262 // create texture var 263 Var *diffuseMap = new Var; 264 diffuseMap->setType( "sampler2D" ); 265 diffuseMap->setName( "baseTexMap" ); 266 diffuseMap->uniform = true; 267 diffuseMap->sampler = true; 268 diffuseMap->constNum = Var::getTexUnitNum(); // used as texture unit num here 269 270 MultiLine *meta = new MultiLine; 271 272 Var *baseColor = new Var; 273 baseColor->setType( "float4" ); 274 baseColor->setName( "baseColor" ); 275 if (mIsDirect3D11) 276 { 277 diffuseMap->setType("SamplerState"); 278 Var *diffuseTex = new Var; 279 diffuseTex->setType("Texture2D"); 280 diffuseTex->setName("baseTexture"); 281 diffuseTex->uniform = true; 282 diffuseTex->texture = true; 283 diffuseTex->constNum = diffuseMap->constNum; 284 meta->addStatement(new GenOp(" @ = @.Sample( @, @.xy );\r\n", new DecOp(baseColor), diffuseTex, diffuseMap, texCoord)); 285 } 286 else 287 { 288 meta->addStatement(new GenOp(" @ = tex2D( @, @.xy );\r\n", new DecOp(baseColor), diffuseMap, texCoord)); 289 } 290 291 meta->addStatement(new GenOp(" @ = toLinear(@);\r\n", baseColor, baseColor)); 292 293 ShaderFeature::OutputTarget target = ShaderFeature::DefaultTarget; 294 295 if (fd.features.hasFeature(MFT_isDeferred)) 296 { 297 target= ShaderFeature::RenderTarget1; 298 } 299 300 meta->addStatement( new GenOp( " @;\r\n", assignColor( baseColor, Material::Mul,NULL,target ) ) ); 301 output = meta; 302} 303 304ShaderFeature::Resources TerrainBaseMapFeatHLSL::getResources( const MaterialFeatureData &fd ) 305{ 306 Resources res; 307 res.numTexReg = 1; 308 res.numTex = 1; 309 310 return res; 311} 312 313U32 TerrainBaseMapFeatHLSL::getOutputTargets( const MaterialFeatureData &fd ) const 314{ 315 return fd.features[MFT_DeferredTerrainBaseMap] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget; 316} 317 318TerrainDetailMapFeatHLSL::TerrainDetailMapFeatHLSL() 319 : mTorqueDep( "shaders/common/torque.hlsl" ), 320 mTerrainDep( "shaders/common/terrain/terrain.hlsl" ) 321 322{ 323 addDependency( &mTorqueDep ); 324 addDependency( &mTerrainDep ); 325} 326 327void TerrainDetailMapFeatHLSL::processVert( Vector<ShaderComponent*> &componentList, 328 const MaterialFeatureData &fd ) 329{ 330 const S32 detailIndex = getProcessIndex(); 331 332 // Grab incoming texture coords... the base map feature 333 // made sure this was created. 334 Var *inTex = (Var*)LangElement::find( "texCoord" ); 335 AssertFatal( inTex, "The texture coord is missing!" ); 336 337 // Grab the input position. 338 Var *inPos = (Var*)LangElement::find( "inPosition" ); 339 if ( !inPos ) 340 inPos = (Var*)LangElement::find( "position" ); 341 342 // Get the object space eye position. 343 Var *eyePos = _getUniformVar( "eyePos", "float3", cspPotentialPrimitive ); 344 345 MultiLine *meta = new MultiLine; 346 347 // If we have parallax mapping then make sure we've sent 348 // the negative view vector to the pixel shader. 349 if ( fd.features.hasFeature( MFT_TerrainParallaxMap ) && 350 !LangElement::find( "outNegViewTS" ) ) 351 { 352 // Get the object to tangent transform which 353 // will consume 3 output registers. 354 Var *objToTangentSpace = getOutObjToTangentSpace( componentList, meta, fd ); 355 356 // Now use a single output register to send the negative 357 // view vector in tangent space to the pixel shader. 358 ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] ); 359 Var *outNegViewTS = connectComp->getElement( RT_TEXCOORD ); 360 outNegViewTS->setName( "outNegViewTS" ); 361 outNegViewTS->setStructName( "OUT" ); 362 outNegViewTS->setType( "float3" ); 363 meta->addStatement( new GenOp( " @ = mul( @, float3( @ - @.xyz ) );\r\n", 364 outNegViewTS, objToTangentSpace, eyePos, inPos ) ); 365 } 366 367 // Get the distance from the eye to this vertex. 368 Var *dist = (Var*)LangElement::find( "dist" ); 369 if ( !dist ) 370 { 371 dist = new Var; 372 dist->setType( "float" ); 373 dist->setName( "dist" ); 374 375 meta->addStatement( new GenOp( " @ = distance( @.xyz, @ );\r\n", 376 new DecOp( dist ), inPos, eyePos ) ); 377 } 378 379 // grab connector texcoord register 380 ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] ); 381 Var *outTex = connectComp->getElement( RT_TEXCOORD ); 382 outTex->setName( String::ToString( "detCoord%d", detailIndex ) ); 383 outTex->setStructName( "OUT" ); 384 outTex->setType( "float4" ); 385 outTex->mapsToSampler = true; 386 387 // Get the detail scale and fade info. 388 Var *detScaleAndFade = new Var; 389 detScaleAndFade->setType( "float4" ); 390 detScaleAndFade->setName( String::ToString( "detailScaleAndFade%d", detailIndex ) ); 391 detScaleAndFade->uniform = true; 392 detScaleAndFade->constSortPos = cspPotentialPrimitive; 393 394 // Setup the detail coord. 395 // 396 // NOTE: You see here we scale the texture coord by 'xyx' 397 // to generate the detail coord. This y is here because 398 // its scale is flipped to correct for the non negative y 399 // in texCoord. 400 // 401 // See TerrainBaseMapFeatHLSL::processVert(). 402 // 403 meta->addStatement( new GenOp( " @.xyz = @ * @.xyx;\r\n", outTex, inTex, detScaleAndFade ) ); 404 405 // And sneak the detail fade thru the w detailCoord. 406 meta->addStatement( new GenOp( " @.w = clamp( ( @.z - @ ) * @.w, 0.0, 1.0 );\r\n", 407 outTex, detScaleAndFade, dist, detScaleAndFade ) ); 408 409 output = meta; 410} 411 412void TerrainDetailMapFeatHLSL::processPix( Vector<ShaderComponent*> &componentList, 413 const MaterialFeatureData &fd ) 414{ 415 const S32 detailIndex = getProcessIndex(); 416 Var *inTex = getVertTexCoord( "texCoord" ); 417 418 MultiLine *meta = new MultiLine; 419 420 // We need the negative tangent space view vector 421 // as in parallax mapping we step towards the camera. 422 Var *negViewTS = (Var*)LangElement::find( "negViewTS" ); 423 if ( !negViewTS && 424 fd.features.hasFeature( MFT_TerrainParallaxMap ) ) 425 { 426 Var *inNegViewTS = (Var*)LangElement::find( "outNegViewTS" ); 427 if ( !inNegViewTS ) 428 { 429 ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] ); 430 inNegViewTS = connectComp->getElement( RT_TEXCOORD ); 431 inNegViewTS->setName( "outNegViewTS" ); 432 inNegViewTS->setStructName( "IN" ); 433 inNegViewTS->setType( "float3" ); 434 } 435 436 negViewTS = new Var( "negViewTS", "float3" ); 437 meta->addStatement( new GenOp( " @ = normalize( @ );\r\n", new DecOp( negViewTS ), inNegViewTS ) ); 438 } 439 440 // Get the layer samples. 441 Var *layerSample = (Var*)LangElement::find( "layerSample" ); 442 if ( !layerSample ) 443 { 444 layerSample = new Var; 445 layerSample->setType( "float4" ); 446 layerSample->setName( "layerSample" ); 447 448 // Get the layer texture var 449 Var *layerTex = new Var; 450 layerTex->setType( "sampler2D" ); 451 layerTex->setName( "layerTex" ); 452 layerTex->uniform = true; 453 layerTex->sampler = true; 454 layerTex->constNum = Var::getTexUnitNum(); 455 456 if (mIsDirect3D11) 457 { 458 layerTex->setType("SamplerState"); 459 Var* layerTexObj = new Var; 460 layerTexObj->setName("layerTexObj"); 461 layerTexObj->setType("Texture2D"); 462 layerTexObj->uniform = true; 463 layerTexObj->texture = true; 464 layerTexObj->constNum = layerTex->constNum; 465 // Read the layer texture to get the samples. 466 meta->addStatement(new GenOp(" @ = round( @.Sample( @, @.xy ) * 255.0f );\r\n", 467 new DecOp(layerSample), layerTexObj, layerTex, inTex)); 468 } 469 else 470 { 471 // Read the layer texture to get the samples. 472 meta->addStatement(new GenOp(" @ = round( tex2D( @, @.xy ) * 255.0f );\r\n", 473 new DecOp(layerSample), layerTex, inTex)); 474 } 475 } 476 477 Var *layerSize = (Var*)LangElement::find( "layerSize" ); 478 if ( !layerSize ) 479 { 480 layerSize = new Var; 481 layerSize->setType( "float" ); 482 layerSize->setName( "layerSize" ); 483 layerSize->uniform = true; 484 layerSize->constSortPos = cspPass; 485 } 486 487 // Grab the incoming detail coord. 488 Var *inDet = _getInDetailCoord( componentList ); 489 490 // Get the detail id. 491 Var *detailInfo = _getDetailIdStrengthParallax(); 492 493 // Create the detail blend var. 494 Var *detailBlend = new Var; 495 detailBlend->setType( "float" ); 496 detailBlend->setName( String::ToString( "detailBlend%d", detailIndex ) ); 497 498 // Calculate the blend for this detail texture. 499 meta->addStatement( new GenOp( " @ = calcBlend( @.x, @.xy, @, @ );\r\n", 500 new DecOp( detailBlend ), detailInfo, inTex, layerSize, layerSample ) ); 501 502 // Get a var and accumulate the blend amount. 503 Var *blendTotal = (Var*)LangElement::find( "blendTotal" ); 504 if ( !blendTotal ) 505 { 506 blendTotal = new Var; 507 blendTotal->setName( "blendTotal" ); 508 blendTotal->setType( "float" ); 509 meta->addStatement( new GenOp( " @ = 0;\r\n", new DecOp( blendTotal ) ) ); 510 } 511 512 // Add to the blend total. 513 514 meta->addStatement(new GenOp(" @ = max( @, @ );\r\n", blendTotal, blendTotal, detailBlend)); 515 516 // If we had a parallax feature... then factor in the parallax 517 // amount so that it fades out with the layer blending. 518 if (fd.features.hasFeature(MFT_TerrainParallaxMap, detailIndex)) 519 { 520 // Get the rest of our inputs. 521 Var *normalMap = _getNormalMapTex(); 522 523 if (mIsDirect3D11) 524 { 525 String name(String::ToString("normalMapTex%d", getProcessIndex())); 526 Var *normalMapTex = (Var*)LangElement::find(name); 527 528 if (!normalMapTex) 529 { 530 normalMapTex = new Var; 531 normalMapTex->setName(String::ToString("normalMapTex%d", getProcessIndex())); 532 normalMapTex->setType("Texture2D"); 533 normalMapTex->uniform = true; 534 normalMapTex->texture = true; 535 normalMapTex->constNum = normalMap->constNum; 536 } 537 538 // Call the library function to do the rest. 539 if (fd.features.hasFeature(MFT_IsDXTnm, detailIndex)) 540 { 541 meta->addStatement(new GenOp(" @.xy += parallaxOffsetDxtnm( @, @, @.xy, @, @.z * @ );\r\n", 542 inDet, normalMapTex, normalMap, inDet, negViewTS, detailInfo, detailBlend)); 543 } 544 else 545 { 546 meta->addStatement(new GenOp(" @.xy += parallaxOffset( @, @, @.xy, @, @.z * @ );\r\n", 547 inDet, normalMapTex, normalMap, inDet, negViewTS, detailInfo, detailBlend)); 548 } 549 550 } 551 else 552 { 553 // Call the library function to do the rest. 554 if (fd.features.hasFeature(MFT_IsDXTnm, detailIndex)) 555 { 556 meta->addStatement(new GenOp(" @.xy += parallaxOffsetDxtnm( @, @.xy, @, @.z * @ );\r\n", 557 inDet, normalMap, inDet, negViewTS, detailInfo, detailBlend)); 558 } 559 else 560 { 561 meta->addStatement(new GenOp(" @.xy += parallaxOffset( @, @.xy, @, @.z * @ );\r\n", 562 inDet, normalMap, inDet, negViewTS, detailInfo, detailBlend)); 563 } 564 } 565 } 566 567 Var *detailColor = (Var*)LangElement::find( "detailColor" ); 568 if ( !detailColor ) 569 { 570 detailColor = new Var; 571 detailColor->setType( "float4" ); 572 detailColor->setName( "detailColor" ); 573 meta->addStatement( new GenOp( " @;\r\n", new DecOp( detailColor ) ) ); 574 } 575 576 // Get the detail texture. 577 Var *detailMap = new Var; 578 detailMap->setType( "sampler2D" ); 579 detailMap->setName( String::ToString( "detailMap%d", detailIndex ) ); 580 detailMap->uniform = true; 581 detailMap->sampler = true; 582 detailMap->constNum = Var::getTexUnitNum(); // used as texture unit num here 583 584 // If we're using SM 3.0 then take advantage of 585 // dynamic branching to skip layers per-pixel. 586 587 588 if ( GFX->getPixelShaderVersion() >= 3.0f ) 589 meta->addStatement( new GenOp( " if ( @ > 0.0f )\r\n", detailBlend ) ); 590 591 meta->addStatement( new GenOp( " {\r\n" ) ); 592 593 // Note that we're doing the standard greyscale detail 594 // map technique here which can darken and lighten the 595 // diffuse texture. 596 // 597 // We take two color samples and lerp between them for 598 // side projection layers... else a single sample. 599 // 600 601 //Sampled detail texture that is not expanded 602 if (mIsDirect3D11) 603 { 604 detailMap->setType("SamplerState"); 605 Var* detailTex = new Var; 606 detailTex->setName(String::ToString("detailTex%d", detailIndex)); 607 detailTex->setType("Texture2D"); 608 detailTex->uniform = true; 609 detailTex->texture = true; 610 detailTex->constNum = detailMap->constNum; 611 612 if (fd.features.hasFeature(MFT_TerrainSideProject, detailIndex)) 613 { 614 615 meta->addStatement(new GenOp(" @ = ( lerp( @.Sample( @, @.yz ), @.Sample( @, @.xz ), @.z ) * 2.0 ) - 1.0;\r\n", 616 detailColor, detailTex, detailMap, inDet, detailTex, detailMap, inDet, inTex)); 617 } 618 else 619 { 620 meta->addStatement(new GenOp(" @ = ( @.Sample( @, @.xy ) * 2.0 ) - 1.0;\r\n", 621 detailColor, detailTex, detailMap, inDet)); 622 } 623 } 624 else 625 { 626 if (fd.features.hasFeature(MFT_TerrainSideProject, detailIndex)) 627 { 628 629 meta->addStatement(new GenOp(" @ = ( lerp( tex2D( @, @.yz ), tex2D( @, @.xz ), @.z ) * 2.0 ) - 1.0;\r\n", 630 detailColor, detailMap, inDet, detailMap, inDet, inTex)); 631 } 632 else 633 { 634 meta->addStatement(new GenOp(" @ = ( tex2D( @, @.xy ) * 2.0 ) - 1.0;\r\n", 635 detailColor, detailMap, inDet)); 636 } 637 } 638 639 meta->addStatement( new GenOp( " @ *= @.y * @.w;\r\n", 640 detailColor, detailInfo, inDet ) ); 641 642 ShaderFeature::OutputTarget target = ShaderFeature::DefaultTarget; 643 644 if(fd.features.hasFeature( MFT_DeferredTerrainDetailMap )) 645 target= ShaderFeature::RenderTarget1; 646 647 Var *outColor = (Var*)LangElement::find( getOutputTargetVarName(target) ); 648 649 meta->addStatement( new GenOp( " @ += @ * @;\r\n", 650 outColor, detailColor, detailBlend)); 651 652 meta->addStatement( new GenOp( " }\r\n" ) ); 653 654 output = meta; 655} 656 657ShaderFeature::Resources TerrainDetailMapFeatHLSL::getResources( const MaterialFeatureData &fd ) 658{ 659 Resources res; 660 661 if ( getProcessIndex() == 0 ) 662 { 663 // If this is the first detail pass then we 664 // samples from the layer tex. 665 res.numTex += 1; 666 667 // If this material also does parallax then it 668 // will generate the negative view vector and the 669 // worldToTanget transform. 670 if ( fd.features.hasFeature( MFT_TerrainParallaxMap ) ) 671 res.numTexReg += 4; 672 } 673 674 // sample from the detail texture for diffuse coloring. 675 res.numTex += 1; 676 677 // If we have parallax for this layer then we'll also 678 // be sampling the normal map for the parallax heightmap. 679 if ( fd.features.hasFeature( MFT_TerrainParallaxMap, getProcessIndex() ) ) 680 res.numTex += 1; 681 682 // Finally we always send the detail texture 683 // coord to the pixel shader. 684 res.numTexReg += 1; 685 686 return res; 687} 688 689U32 TerrainDetailMapFeatHLSL::getOutputTargets( const MaterialFeatureData &fd ) const 690{ 691 return fd.features[MFT_DeferredTerrainDetailMap] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget; 692} 693 694 695TerrainMacroMapFeatHLSL::TerrainMacroMapFeatHLSL() 696 : mTorqueDep( "shaders/common/torque.hlsl" ), 697 mTerrainDep( "shaders/common/terrain/terrain.hlsl" ) 698 699{ 700 addDependency( &mTorqueDep ); 701 addDependency( &mTerrainDep ); 702} 703 704 705void TerrainMacroMapFeatHLSL::processVert( Vector<ShaderComponent*> &componentList, 706 const MaterialFeatureData &fd ) 707{ 708 const S32 detailIndex = getProcessIndex(); 709 710 // Grab incoming texture coords... the base map feature 711 // made sure this was created. 712 Var *inTex = (Var*)LangElement::find( "texCoord" ); 713 AssertFatal( inTex, "The texture coord is missing!" ); 714 715 // Grab the input position. 716 Var *inPos = (Var*)LangElement::find( "inPosition" ); 717 if ( !inPos ) 718 inPos = (Var*)LangElement::find( "position" ); 719 720 // Get the object space eye position. 721 Var *eyePos = _getUniformVar( "eyePos", "float3", cspPotentialPrimitive ); 722 723 MultiLine *meta = new MultiLine; 724 725 // Get the distance from the eye to this vertex. 726 Var *dist = (Var*)LangElement::find( "macroDist" ); 727 if ( !dist ) 728 { 729 dist = new Var; 730 dist->setType( "float" ); 731 dist->setName( "macroDist" ); 732 733 meta->addStatement( new GenOp( " @ = distance( @.xyz, @ );\r\n", 734 new DecOp( dist ), inPos, eyePos ) ); 735 } 736 737 // grab connector texcoord register 738 ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] ); 739 Var *outTex = connectComp->getElement( RT_TEXCOORD ); 740 outTex->setName( String::ToString( "macroCoord%d", detailIndex ) ); 741 outTex->setStructName( "OUT" ); 742 outTex->setType( "float4" ); 743 outTex->mapsToSampler = true; 744 745 // Get the detail scale and fade info. 746 Var *detScaleAndFade = new Var; 747 detScaleAndFade->setType( "float4" ); 748 detScaleAndFade->setName( String::ToString( "macroScaleAndFade%d", detailIndex ) ); 749 detScaleAndFade->uniform = true; 750 detScaleAndFade->constSortPos = cspPotentialPrimitive; 751 752 // Setup the detail coord. 753 meta->addStatement( new GenOp( " @.xyz = @ * @.xyx;\r\n", outTex, inTex, detScaleAndFade ) ); 754 755 // And sneak the detail fade thru the w detailCoord. 756 meta->addStatement( new GenOp( " @.w = clamp( ( @.z - @ ) * @.w, 0.0, 1.0 );\r\n", 757 outTex, detScaleAndFade, dist, detScaleAndFade ) ); 758 759 output = meta; 760} 761 762 763void TerrainMacroMapFeatHLSL::processPix( Vector<ShaderComponent*> &componentList, 764 const MaterialFeatureData &fd ) 765{ 766 const S32 detailIndex = getProcessIndex(); 767 Var *inTex = getVertTexCoord( "texCoord" ); 768 769 MultiLine *meta = new MultiLine; 770 771 // We need the negative tangent space view vector 772 // as in parallax mapping we step towards the camera. 773 Var *negViewTS = (Var*)LangElement::find( "negViewTS" ); 774 if ( !negViewTS && 775 fd.features.hasFeature( MFT_TerrainParallaxMap ) ) 776 { 777 Var *inNegViewTS = (Var*)LangElement::find( "outNegViewTS" ); 778 if ( !inNegViewTS ) 779 { 780 ShaderConnector *connectComp = dynamic_cast<ShaderConnector *>( componentList[C_CONNECTOR] ); 781 inNegViewTS = connectComp->getElement( RT_TEXCOORD ); 782 inNegViewTS->setName( "outNegViewTS" ); 783 inNegViewTS->setStructName( "IN" ); 784 inNegViewTS->setType( "float3" ); 785 } 786 787 negViewTS = new Var( "negViewTS", "float3" ); 788 meta->addStatement( new GenOp( " @ = normalize( @ );\r\n", new DecOp( negViewTS ), inNegViewTS ) ); 789 } 790 791 // Get the layer samples. 792 Var *layerSample = (Var*)LangElement::find( "layerSample" ); 793 if ( !layerSample ) 794 { 795 layerSample = new Var; 796 layerSample->setType( "float4" ); 797 layerSample->setName( "layerSample" ); 798 799 // Get the layer texture var 800 Var *layerTex = new Var; 801 layerTex->setType( "sampler2D" ); 802 layerTex->setName( "macrolayerTex" ); 803 layerTex->uniform = true; 804 layerTex->sampler = true; 805 layerTex->constNum = Var::getTexUnitNum(); 806 807 // Read the layer texture to get the samples. 808 if (mIsDirect3D11) 809 { 810 layerTex->setType("SamplerState"); 811 Var *layerTexObj = new Var; 812 layerTexObj->setType("Texture2D"); 813 layerTexObj->setName("macroLayerTexObj"); 814 layerTexObj->uniform = true; 815 layerTexObj->texture = true; 816 layerTexObj->constNum = layerTex->constNum; 817 meta->addStatement(new GenOp(" @ = round( @.Sample( @, @.xy ) * 255.0f );\r\n", 818 new DecOp(layerSample), layerTexObj, layerTex, inTex)); 819 } 820 else 821 meta->addStatement(new GenOp(" @ = round( tex2D( @, @.xy ) * 255.0f );\r\n", 822 new DecOp(layerSample), layerTex, inTex)); 823 } 824 825 Var *layerSize = (Var*)LangElement::find( "layerSize" ); 826 if ( !layerSize ) 827 { 828 layerSize = new Var; 829 layerSize->setType( "float" ); 830 layerSize->setName( "layerSize" ); 831 layerSize->uniform = true; 832 layerSize->constSortPos = cspPass; 833 } 834 835 // Grab the incoming detail coord. 836 Var *inDet = _getInMacroCoord( componentList ); 837 838 // Get the detail id. 839 Var *detailInfo = _getMacroIdStrengthParallax(); 840 841 // Create the detail blend var. 842 Var *detailBlend = new Var; 843 detailBlend->setType( "float" ); 844 detailBlend->setName( String::ToString( "macroBlend%d", detailIndex ) ); 845 846 // Calculate the blend for this detail texture. 847 meta->addStatement( new GenOp( " @ = calcBlend( @.x, @.xy, @, @ );\r\n", 848 new DecOp( detailBlend ), detailInfo, inTex, layerSize, layerSample ) ); 849 850 // Get a var and accumulate the blend amount. 851 Var *blendTotal = (Var*)LangElement::find( "blendTotal" ); 852 if ( !blendTotal ) 853 { 854 blendTotal = new Var; 855 blendTotal->setName( "blendTotal" ); 856 blendTotal->setType( "float" ); 857 meta->addStatement( new GenOp( " @ = 0;\r\n", new DecOp( blendTotal ) ) ); 858 } 859 860 // Add to the blend total. 861 meta->addStatement(new GenOp(" @ = max( @, @ );\r\n", blendTotal, blendTotal, detailBlend)); 862 863 Var *detailColor = (Var*)LangElement::find( "macroColor" ); 864 if ( !detailColor ) 865 { 866 detailColor = new Var; 867 detailColor->setType( "float4" ); 868 detailColor->setName( "macroColor" ); 869 meta->addStatement( new GenOp( " @;\r\n", new DecOp( detailColor ) ) ); 870 } 871 872 // Get the detail texture. 873 Var *detailMap = new Var; 874 detailMap->setType( "sampler2D" ); 875 detailMap->setName( String::ToString( "macroMap%d", detailIndex ) ); 876 detailMap->uniform = true; 877 detailMap->sampler = true; 878 detailMap->constNum = Var::getTexUnitNum(); // used as texture unit num here 879 880 //Create texture object for directx 11 881 Var *detailTex = NULL; 882 if (mIsDirect3D11) 883 { 884 detailMap->setType("SamplerState"); 885 detailTex = new Var; 886 detailTex->setName(String::ToString("macroMapTex%d", detailIndex)); 887 detailTex->setType("Texture2D"); 888 detailTex->uniform = true; 889 detailTex->texture = true; 890 detailTex->constNum = detailMap->constNum; 891 892 } 893 894 // If we're using SM 3.0 then take advantage of 895 // dynamic branching to skip layers per-pixel. 896 if ( GFX->getPixelShaderVersion() >= 3.0f ) 897 meta->addStatement( new GenOp( " if ( @ > 0.0f )\r\n", detailBlend ) ); 898 899 meta->addStatement( new GenOp( " {\r\n" ) ); 900 901 // Note that we're doing the standard greyscale detail 902 // map technique here which can darken and lighten the 903 // diffuse texture. 904 // 905 // We take two color samples and lerp between them for 906 // side projection layers... else a single sample. 907 // 908 if (fd.features.hasFeature(MFT_TerrainSideProject, detailIndex)) 909 { 910 if (mIsDirect3D11) 911 { 912 meta->addStatement(new GenOp(" @ = ( lerp( @.Sample( @, @.yz ), @.Sample( @, @.xz ), @.z ) * 2.0 ) - 1.0;\r\n", 913 detailColor, detailTex, detailMap, inDet, detailTex, detailMap, inDet, inTex)); 914 } 915 else 916 meta->addStatement(new GenOp(" @ = ( lerp( tex2D( @, @.yz ), tex2D( @, @.xz ), @.z ) * 2.0 ) - 1.0;\r\n", 917 detailColor, detailMap, inDet, detailMap, inDet, inTex)); 918 } 919 else 920 { 921 if (mIsDirect3D11) 922 meta->addStatement(new GenOp(" @ = ( @.Sample( @, @.xy ) * 2.0 ) - 1.0;\r\n", 923 detailColor, detailTex, detailMap, inDet)); 924 else 925 meta->addStatement(new GenOp(" @ = ( tex2D( @, @.xy ) * 2.0 ) - 1.0;\r\n", 926 detailColor, detailMap, inDet)); 927 } 928 929 meta->addStatement( new GenOp( " @ *= @.y * @.w;\r\n", 930 detailColor, detailInfo, inDet ) ); 931 932 ShaderFeature::OutputTarget target = ShaderFeature::DefaultTarget; 933 934 if(fd.features.hasFeature(MFT_DeferredTerrainMacroMap)) 935 target= ShaderFeature::RenderTarget1; 936 937 Var *outColor = (Var*)LangElement::find( getOutputTargetVarName(target) ); 938 939 meta->addStatement(new GenOp(" @ += @ * @;\r\n", 940 outColor, detailColor, detailBlend)); 941 942 meta->addStatement( new GenOp( " }\r\n" ) ); 943 944 output = meta; 945} 946 947ShaderFeature::Resources TerrainMacroMapFeatHLSL::getResources( const MaterialFeatureData &fd ) 948{ 949 Resources res; 950 951 if ( getProcessIndex() == 0 ) 952 { 953 // If this is the first detail pass then we 954 // samples from the layer tex. 955 res.numTex += 1; 956 } 957 958 res.numTex += 1; 959 960 // Finally we always send the detail texture 961 // coord to the pixel shader. 962 res.numTexReg += 1; 963 964 return res; 965} 966 967U32 TerrainMacroMapFeatHLSL::getOutputTargets( const MaterialFeatureData &fd ) const 968{ 969 return fd.features[MFT_DeferredTerrainMacroMap] ? ShaderFeature::RenderTarget1 : ShaderFeature::DefaultTarget; 970} 971 972void TerrainNormalMapFeatHLSL::processVert( Vector<ShaderComponent*> &componentList, 973 const MaterialFeatureData &fd ) 974{ 975 // We only need to process normals during the prepass. 976 if ( !fd.features.hasFeature( MFT_PrePassConditioner ) ) 977 return; 978 979 MultiLine *meta = new MultiLine; 980 981 // Make sure the world to tangent transform 982 // is created and available for the pixel shader. 983 getOutViewToTangent( componentList, meta, fd ); 984 985 output = meta; 986} 987 988void TerrainNormalMapFeatHLSL::processPix( Vector<ShaderComponent*> &componentList, 989 const MaterialFeatureData &fd ) 990{ 991 992 MultiLine *meta = new MultiLine; 993 994 Var *viewToTangent = getInViewToTangent( componentList ); 995 996 // This var is read from GBufferConditionerHLSL and 997 // used in the prepass output. 998 Var *gbNormal = (Var*)LangElement::find( "gbNormal" ); 999 if ( !gbNormal ) 1000 { 1001 gbNormal = new Var; 1002 gbNormal->setName( "gbNormal" ); 1003 gbNormal->setType( "float3" ); 1004 meta->addStatement( new GenOp( " @ = @[2];\r\n", new DecOp( gbNormal ), viewToTangent ) ); 1005 } 1006 1007 const S32 normalIndex = getProcessIndex(); 1008 1009 Var *detailBlend = (Var*)LangElement::find( String::ToString( "detailBlend%d", normalIndex ) ); 1010 AssertFatal( detailBlend, "The detail blend is missing!" ); 1011 1012 // If we're using SM 3.0 then take advantage of 1013 // dynamic branching to skip layers per-pixel. 1014 if ( GFX->getPixelShaderVersion() >= 3.0f ) 1015 meta->addStatement( new GenOp( " if ( @ > 0.0f )\r\n", detailBlend ) ); 1016 1017 meta->addStatement( new GenOp( " {\r\n" ) ); 1018 1019 // Get the normal map texture. 1020 Var *normalMap = _getNormalMapTex(); 1021 1022 /// Get the texture coord. 1023 Var *inDet = _getInDetailCoord( componentList ); 1024 Var *inTex = getVertTexCoord( "texCoord" ); 1025 1026 // Sample the normal map. 1027 // 1028 // We take two normal samples and lerp between them for 1029 // side projection layers... else a single sample. 1030 LangElement *texOp; 1031 if (mIsDirect3D11) 1032 { 1033 String name(String::ToString("normalMapTex%d", getProcessIndex())); 1034 Var *normalMapTex = (Var*)LangElement::find(name); 1035 if (!normalMapTex) 1036 { 1037 normalMapTex = new Var; 1038 normalMapTex->setName(String::ToString("normalMapTex%d", getProcessIndex())); 1039 normalMapTex->setType("Texture2D"); 1040 normalMapTex->uniform = true; 1041 normalMapTex->texture = true; 1042 normalMapTex->constNum = normalMap->constNum; 1043 } 1044 if (fd.features.hasFeature(MFT_TerrainSideProject, normalIndex)) 1045 { 1046 texOp = new GenOp("lerp( @.Sample( @, @.yz ), @.Sample( @, @.xz ), @.z )", 1047 normalMapTex, normalMap, inDet, normalMapTex, normalMap, inDet, inTex); 1048 } 1049 else 1050 texOp = new GenOp("@.Sample(@, @.xy)", normalMapTex, normalMap, inDet); 1051 1052 } 1053 1054 else 1055 { 1056 if (fd.features.hasFeature(MFT_TerrainSideProject, normalIndex)) 1057 { 1058 texOp = new GenOp("lerp( tex2D( @, @.yz ), tex2D( @, @.xz ), @.z )", 1059 normalMap, inDet, normalMap, inDet, inTex); 1060 } 1061 else 1062 texOp = new GenOp("tex2D(@, @.xy)", normalMap, inDet); 1063 } 1064 1065 // create bump normal 1066 Var *bumpNorm = new Var; 1067 bumpNorm->setName( "bumpNormal" ); 1068 bumpNorm->setType( "float4" ); 1069 1070 LangElement *bumpNormDecl = new DecOp( bumpNorm ); 1071 meta->addStatement( expandNormalMap( texOp, bumpNormDecl, bumpNorm, fd ) ); 1072 1073 // Normalize is done later... 1074 // Note: The reverse mul order is intentional. Affine matrix. 1075 meta->addStatement( new GenOp( " @ = lerp( @, mul( @.xyz, @ ), min( @, @.w ) );\r\n", 1076 gbNormal, gbNormal, bumpNorm, viewToTangent, detailBlend, inDet ) ); 1077 1078 // End the conditional block. 1079 meta->addStatement( new GenOp( " }\r\n" ) ); 1080 1081 // If this is the last normal map then we 1082 // can test to see the total blend value 1083 // to see if we should clip the result. 1084 //if ( fd.features.getNextFeatureIndex( MFT_TerrainNormalMap, normalIndex ) == -1 ) 1085 //meta->addStatement( new GenOp( " clip( @ - 0.0001f );\r\n", blendTotal ) ); 1086 1087 output = meta; 1088} 1089 1090ShaderFeature::Resources TerrainNormalMapFeatHLSL::getResources( const MaterialFeatureData &fd ) 1091{ 1092 Resources res; 1093 1094 // We only need to process normals during the prepass. 1095 if ( fd.features.hasFeature( MFT_PrePassConditioner ) ) 1096 { 1097 // If this is the first normal map and there 1098 // are no parallax features then we will 1099 // generate the worldToTanget transform. 1100 if ( !fd.features.hasFeature( MFT_TerrainParallaxMap ) && 1101 ( getProcessIndex() == 0 || !fd.features.hasFeature( MFT_TerrainNormalMap, getProcessIndex() - 1 ) ) ) 1102 res.numTexReg = 3; 1103 1104 res.numTex = 1; 1105 } 1106 1107 return res; 1108} 1109 1110void TerrainLightMapFeatHLSL::processPix( Vector<ShaderComponent*> &componentList, 1111 const MaterialFeatureData &fd ) 1112{ 1113 // grab connector texcoord register 1114 Var *inTex = (Var*)LangElement::find( "texCoord" ); 1115 if ( !inTex ) 1116 return; 1117 1118 // Get the lightmap texture. 1119 Var *lightMap = new Var; 1120 lightMap->setType( "sampler2D" ); 1121 lightMap->setName( "lightMapTex" ); 1122 lightMap->uniform = true; 1123 lightMap->sampler = true; 1124 lightMap->constNum = Var::getTexUnitNum(); 1125 1126 MultiLine *meta = new MultiLine; 1127 1128 // Find or create the lightMask value which is read by 1129 // RTLighting to mask out the lights. 1130 // 1131 // The first light is always the sunlight so we apply 1132 // the shadow mask to only the first channel. 1133 // 1134 Var *lightMask = (Var*)LangElement::find( "lightMask" ); 1135 if ( !lightMask ) 1136 { 1137 lightMask = new Var( "lightMask", "float4" ); 1138 meta->addStatement( new GenOp( " @ = 1;\r\n", new DecOp( lightMask ) ) ); 1139 } 1140 1141 if (mIsDirect3D11) 1142 { 1143 lightMap->setType("SamplerState"); 1144 Var* lightMapTex = new Var; 1145 lightMapTex->setName("lightMapTexObj"); 1146 lightMapTex->setType("Texture2D"); 1147 lightMapTex->uniform = true; 1148 lightMapTex->texture = true; 1149 lightMapTex->constNum = lightMap->constNum; 1150 meta->addStatement(new GenOp(" @[0] = @.Sample( @, @.xy ).r;\r\n", lightMask, lightMapTex, lightMap, inTex)); 1151 } 1152 else 1153 meta->addStatement(new GenOp(" @[0] = tex2D( @, @.xy ).r;\r\n", lightMask, lightMap, inTex)); 1154 1155 output = meta; 1156} 1157 1158ShaderFeature::Resources TerrainLightMapFeatHLSL::getResources( const MaterialFeatureData &fd ) 1159{ 1160 Resources res; 1161 res.numTex = 1; 1162 return res; 1163} 1164 1165void TerrainAdditiveFeatHLSL::processPix( Vector<ShaderComponent*> &componentList, 1166 const MaterialFeatureData &fd ) 1167{ 1168 Var *color = NULL; 1169 Var *normal = NULL; 1170 if (fd.features[MFT_DeferredTerrainDetailMap]) 1171 { 1172 color = (Var*) LangElement::find( getOutputTargetVarName(ShaderFeature::RenderTarget1) ); 1173 normal = (Var*) LangElement::find( getOutputTargetVarName(ShaderFeature::DefaultTarget) ); 1174 } 1175 else 1176 color = (Var*) LangElement::find( getOutputTargetVarName(ShaderFeature::DefaultTarget) ); 1177 1178 Var *blendTotal = (Var*)LangElement::find( "blendTotal" ); 1179 if ( !color || !blendTotal ) 1180 return; 1181 1182 MultiLine *meta = new MultiLine; 1183 1184 meta->addStatement( new GenOp( " clip( @ - 0.0001 );\r\n", blendTotal ) ); 1185 meta->addStatement( new GenOp( " @.a = @;\r\n", color, blendTotal ) ); 1186 1187 if (normal) 1188 meta->addStatement(new GenOp(" @.a = @;\r\n", normal, blendTotal)); 1189 1190 output = meta; 1191} 1192 1193//standard matInfo map contains data of the form .r = bitflags, .g = (will contain AO), 1194//.b = specular strength, a= spec power. 1195//here, it's merely a cutout for now, so that lightmapping (target3) doesn't get mangled. 1196//we'll most likely revisit that later. possibly several ways... 1197 1198U32 TerrainBlankInfoMapFeatHLSL::getOutputTargets(const MaterialFeatureData &fd) const 1199{ 1200 return fd.features[MFT_DeferredTerrainBaseMap] ? ShaderFeature::RenderTarget2 : ShaderFeature::RenderTarget1; 1201} 1202 1203void TerrainBlankInfoMapFeatHLSL::processPix(Vector<ShaderComponent*> &componentList, 1204 const MaterialFeatureData &fd) 1205{ 1206 // search for material var 1207 Var *material; 1208 OutputTarget targ = RenderTarget1; 1209 if (fd.features[MFT_isDeferred]) 1210 { 1211 targ = RenderTarget2; 1212 } 1213 material = (Var*)LangElement::find(getOutputTargetVarName(targ)); 1214 1215 MultiLine * meta = new MultiLine; 1216 if (!material) 1217 { 1218 // create color var 1219 material = new Var; 1220 material->setType("fragout"); 1221 material->setName(getOutputTargetVarName(targ)); 1222 material->setStructName("OUT"); 1223 } 1224 1225 meta->addStatement(new GenOp(" @ = float4(0.0,0.0,0.0,0.0001);\r\n", material)); 1226 1227 output = meta; 1228} 1229
