customFeatureHLSL.cpp
Engine/source/shaderGen/HLSL/customFeatureHLSL.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 "customFeatureHLSL.h" 25#include "shaderGen/shaderFeature.h" 26#include "shaderGen/shaderOp.h" 27#include "shaderGen/featureMgr.h" 28//#include "materials/materialFeatureTypes.h" 29//#include "gfx/gfxDevice.h" 30//#include "materials/processedMaterial.h" 31 32//**************************************************************************** 33// Accu Texture 34//**************************************************************************** 35void CustomFeatureHLSL::processVert(Vector<ShaderComponent*>& componentList, 36 const MaterialFeatureData& fd) 37{ 38 /*MultiLine *meta = new MultiLine; 39 getOutTexCoord( "texCoord", 40 "float2", 41 false, 42 meta, 43 componentList ); 44 45 getOutObjToTangentSpace( componentList, meta, fd ); 46 47 output = meta;*/ 48 49 meta = new MultiLine; 50 51 mFeatureData = fd; 52 mComponentList = componentList; 53 54 mOutputState = VertexOutput; 55 56 if (mOwner->isMethod("processVertHLSL")) 57 Con::executef(mOwner, "processVertHLSL"); 58 59 output = meta; 60} 61 62void CustomFeatureHLSL::processPix(Vector<ShaderComponent*>& componentList, 63 const MaterialFeatureData& fd) 64{ 65 meta = new MultiLine; 66 67 mFeatureData = fd; 68 mComponentList = componentList; 69 70 mOutputState = PixelOutput; 71 72 /*MultiLine *meta = new MultiLine; 73 74 output = meta; 75 76 // OUT.col 77 Var *color = (Var*) LangElement::find( "col1" ); 78 if (!color) 79 { 80 output = new GenOp(" //NULL COLOR!"); 81 return; 82 } 83 84 // accu map 85 Var *accuMap = new Var; 86 accuMap->setType("SamplerState"); 87 88 accuMap->setName( "accuMap" ); 89 accuMap->uniform = true; 90 accuMap->sampler = true; 91 accuMap->constNum = Var::getTexUnitNum(); // used as texture unit num here 92 93 // accuColor var 94 Var *accuColor = new Var; 95 accuColor->setType( "float4" ); 96 accuColor->setName( "accuColor" ); 97 LangElement *colorAccuDecl = new DecOp( accuColor ); 98 99 // plc (placement) 100 Var *accuPlc = new Var; 101 accuPlc->setType( "float4" ); 102 accuPlc->setName( "plc" ); 103 LangElement *plcAccu = new DecOp( accuPlc ); 104 105 // accu constants 106 Var *accuScale = (Var*)LangElement::find( "accuScale" ); 107 if ( !accuScale ) 108 { 109 accuScale = new Var; 110 accuScale->setType( "float" ); 111 accuScale->setName( "accuScale" ); 112 accuScale->uniform = true; 113 accuScale->sampler = false; 114 accuScale->constSortPos = cspPotentialPrimitive; 115 } 116 Var *accuDirection = (Var*)LangElement::find( "accuDirection" ); 117 if ( !accuDirection ) 118 { 119 accuDirection = new Var; 120 accuDirection->setType( "float" ); 121 accuDirection->setName( "accuDirection" ); 122 accuDirection->uniform = true; 123 accuDirection->sampler = false; 124 accuDirection->constSortPos = cspPotentialPrimitive; 125 } 126 Var *accuStrength = (Var*)LangElement::find( "accuStrength" ); 127 if ( !accuStrength ) 128 { 129 accuStrength = new Var; 130 accuStrength->setType( "float" ); 131 accuStrength->setName( "accuStrength" ); 132 accuStrength->uniform = true; 133 accuStrength->sampler = false; 134 accuStrength->constSortPos = cspPotentialPrimitive; 135 } 136 Var *accuCoverage = (Var*)LangElement::find( "accuCoverage" ); 137 if ( !accuCoverage ) 138 { 139 accuCoverage = new Var; 140 accuCoverage->setType( "float" ); 141 accuCoverage->setName( "accuCoverage" ); 142 accuCoverage->uniform = true; 143 accuCoverage->sampler = false; 144 accuCoverage->constSortPos = cspPotentialPrimitive; 145 } 146 Var *accuSpecular = (Var*)LangElement::find( "accuSpecular" ); 147 if ( !accuSpecular ) 148 { 149 accuSpecular = new Var; 150 accuSpecular->setType( "float" ); 151 accuSpecular->setName( "accuSpecular" ); 152 accuSpecular->uniform = true; 153 accuSpecular->sampler = false; 154 accuSpecular->constSortPos = cspPotentialPrimitive; 155 } 156 157 Var *inTex = getInTexCoord( "texCoord", "float2", componentList ); 158 Var *accuVec = getInTexCoord( "accuVec", "float3", componentList ); 159 Var *bumpNorm = (Var *)LangElement::find( "bumpSample" ); 160 if( bumpNorm == NULL ) 161 { 162 bumpNorm = (Var *)LangElement::find( "bumpNormal" ); 163 if (!bumpNorm) 164 return; 165 } 166 167 // get the accu pixel color 168 169 Var *accuMapTex = new Var; 170 accuMapTex->setType("Texture2D"); 171 accuMapTex->setName("accuMapTex"); 172 accuMapTex->uniform = true; 173 accuMapTex->texture = true; 174 accuMapTex->constNum = accuMap->constNum; 175 meta->addStatement(new GenOp(" @ = @.Sample(@, @ * @);\r\n", colorAccuDecl, accuMapTex, accuMap, inTex, accuScale)); 176 177 // scale up normals 178 meta->addStatement( new GenOp( " @.xyz = @.xyz * 2.0 - 0.5;\r\n", bumpNorm, bumpNorm ) ); 179 180 // assign direction 181 meta->addStatement( new GenOp( " @.z *= @*2.0;\r\n", accuVec, accuDirection ) ); 182 183 // saturate based on strength 184 meta->addStatement( new GenOp( " @ = saturate( dot( @.xyz, @.xyz * pow(@, 5) ) );\r\n", plcAccu, bumpNorm, accuVec, accuStrength ) ); 185 186 // add coverage 187 meta->addStatement( new GenOp( " @.a += (2 * pow(@/2, 5)) - 0.5;\r\n", accuPlc, accuCoverage ) ); 188 189 // clamp to a sensible value 190 meta->addStatement( new GenOp( " @.a = clamp(@.a, 0, 1);\r\n", accuPlc, accuPlc ) ); 191 192 // light 193 Var *lightColor = (Var*) LangElement::find( "d_lightcolor" ); 194 if(lightColor != NULL) 195 meta->addStatement( new GenOp( " @ *= float4(@, 1.0);\r\n\r\n", accuColor, lightColor ) ); 196 197 // lerp with current pixel - use the accu alpha as well 198 meta->addStatement( new GenOp( " @ = lerp( @, @, @.a * @.a);\r\n", color, color, accuColor, accuPlc, accuColor ) ); 199 200 // the result should always be opaque 201 meta->addStatement( new GenOp( " @.a = 1.0;\r\n", color ) );*/ 202 if (mOwner->isMethod("processPixelHLSL")) 203 Con::executef(mOwner, "processPixelHLSL"); 204 205 output = meta; 206} 207 208void CustomFeatureHLSL::setTexData(Material::StageData& stageDat, 209 const MaterialFeatureData& fd, 210 RenderPassData& passData, 211 U32& texIndex) 212{ 213 //GFXTextureObject *tex = stageDat.getTex( MFT_AccuMap ); 214 //if ( tex ) 215 //{ 216 //passData.mSamplerNames[ texIndex ] = "AccuMap"; 217 //passData.mTexType[ texIndex++ ] = Material::AccuMap; 218 //} 219 220 if (mOwner->isMethod("setTextureData")) 221 Con::executef(mOwner, "setTextureData"); 222} 223 224void CustomFeatureHLSL::addUniform(String name, String type, String defaultValue, U32 arraySize) 225{ 226 //do the var/arg fetching here 227 Var* newVar = (Var*)LangElement::find(name.c_str()); 228 if (!newVar) 229 { 230 VarHolder newVarHolder(name, type, ""); 231 newVarHolder.arraySize = arraySize; 232 newVarHolder.sampler = false; 233 newVarHolder.uniform = true; 234 newVarHolder.constSortPos = cspPotentialPrimitive; 235 236 mVars.push_back(newVarHolder); 237 238 mOwner->mAddedShaderConstants.push_back(StringTable->insert(name.c_str())); 239 } 240} 241 242void CustomFeatureHLSL::addSampler(String name, String type, U32 arraySize) 243{ 244 //do the var/arg fetching here 245 Var* newVar = (Var*)LangElement::find(name.c_str()); 246 if (!newVar) 247 { 248 //As far as I know, it's always SamplerState regardless of the texture's type 249 VarHolder newVarHolder(name, "SamplerState", ""); 250 newVarHolder.arraySize = arraySize; 251 newVarHolder.sampler = true; 252 newVarHolder.uniform = true; 253 newVarHolder.constNum = Var::getTexUnitNum(); // used as texture unit num here 254 255 mVars.push_back(newVarHolder); 256 257 mOwner->mAddedShaderConstants.push_back(StringTable->insert(name.c_str())); 258 } 259} 260 261void CustomFeatureHLSL::addTexture(String name, String type, String samplerState, U32 arraySize) 262{ 263 //do the var/arg fetching here 264 Var* newVar = (Var*)LangElement::find(name.c_str()); 265 if (!newVar) 266 { 267 //go find our sampler state var 268 U32 constNum = 0; 269 270 Var* samplerStateVar = (Var*)LangElement::find(samplerState.c_str()); 271 if (!samplerStateVar) 272 { 273 //check our holder vars 274 bool foundHolder = false; 275 for (U32 v = 0; v < mVars.size(); v++) 276 { 277 if (mVars[v].varName == samplerState) 278 { 279 constNum = mVars[v].constNum; 280 foundHolder = true; 281 break; 282 } 283 } 284 285 if (!foundHolder) 286 { 287 Con::errorf("CustomShaderFeature::addTexture: Unable to find texture's sampler state!"); 288 return; 289 } 290 } 291 else 292 { 293 constNum = samplerStateVar->constNum; 294 } 295 296 VarHolder newVarHolder(name, type, ""); 297 newVarHolder.arraySize = arraySize; 298 newVarHolder.texture = true; 299 newVarHolder.uniform = true; 300 newVarHolder.constNum = constNum; // used as texture unit num here 301 302 mVars.push_back(newVarHolder); 303 304 mOwner->mAddedShaderConstants.push_back(StringTable->insert(name.c_str())); 305 } 306} 307 308void CustomFeatureHLSL::addVariable(String name, String type, String defaultValue) 309{ 310 //do the var/arg fetching here 311 Var* newVar = (Var*)LangElement::find(name.c_str()); 312 if (!newVar) 313 { 314 if (!defaultValue.isEmpty()) 315 { 316 char declareStatement[128]; 317 dSprintf(declareStatement, 128, " @ = %s;\n", defaultValue.c_str()); 318 319 newVar = new Var(name, type); 320 LangElement* newVarDecl = new DecOp(newVar); 321 meta->addStatement(new GenOp(declareStatement, newVarDecl)); 322 } 323 else 324 { 325 VarHolder newVarHolder(name, type, defaultValue); 326 327 mVars.push_back(newVarHolder); 328 } 329 } 330} 331 332void CustomFeatureHLSL::addConnector(String name, String type, String elementName) 333{ 334 // grab connector texcoord register 335 ShaderConnector* connectComp = dynamic_cast<ShaderConnector*>(mComponentList[C_CONNECTOR]); 336 337 //Get element 338 S32 element = -1; 339 340 if (elementName == String("RT_POSITION")) 341 element = RT_POSITION; 342 else if (elementName == String("RT_NORMAL")) 343 element = RT_NORMAL; 344 else if (elementName == String("RT_BINORMAL")) 345 element = RT_BINORMAL; 346 else if (elementName == String("RT_TANGENT")) 347 element = RT_TANGENT; 348 else if (elementName == String("RT_TANGENTW")) 349 element = RT_TANGENTW; 350 else if (elementName == String("RT_COLOR")) 351 element = RT_COLOR; 352 else if (elementName == String("RT_TEXCOORD")) 353 element = RT_TEXCOORD; 354 else if (elementName == String("RT_VPOS")) 355 element = RT_VPOS; 356 else if (elementName == String("RT_SVPOSITION")) 357 element = RT_SVPOSITION; 358 else if (elementName == String("RT_BLENDINDICES")) 359 element = RT_BLENDINDICES; 360 else if (elementName == String("RT_BLENDWEIGHT")) 361 element = RT_BLENDWEIGHT; 362 363 if (element == -1) 364 { 365 Con::errorf("CustomShaderFeatureHLSL::addConnector - Invalid element type %s", elementName.c_str()); 366 return; 367 } 368 369 VarHolder newVarHolder(name, type, ""); 370 371 newVarHolder.elementId = element; 372 373 if (mOutputState == VertexOutput) 374 newVarHolder.structName = "OUT"; 375 else if (mOutputState == PixelOutput) 376 newVarHolder.structName = "IN"; 377 378 mVars.push_back(newVarHolder); 379} 380 381void CustomFeatureHLSL::addVertTexCoord(String name) 382{ 383 VarHolder newVarHolder(name, "", ""); 384 newVarHolder.texCoord = true; 385 386 mVars.push_back(newVarHolder); 387} 388 389void CustomFeatureHLSL::writeLine(String format, S32 argc, ConsoleValueRef * argv) 390{ 391 //do the var/arg fetching here 392 Vector<Var*> varList; 393 bool declarationStatement = false; 394 395 for (U32 i = 0; i < argc; i++) 396 { 397 String varName = argv[i].getStringValue(); 398 Var* newVar = (Var*)LangElement::find(varName.c_str()); 399 if (!newVar) 400 { 401 //ok, check our existing var holders, see if we just haven't utilized it yet 402 for (U32 v = 0; v < mVars.size(); v++) 403 { 404 if (mVars[v].varName == varName) 405 { 406 if (!mVars[v].texCoord) 407 { 408 if (mVars[v].elementId != -1) 409 { 410 ShaderConnector* connectComp = dynamic_cast<ShaderConnector*>(mComponentList[C_CONNECTOR]); 411 Var* newDeclVar = connectComp->getElement((RegisterType)mVars[v].elementId); 412 newDeclVar->setName(mVars[v].varName); 413 newDeclVar->setStructName(mVars[v].structName); 414 newDeclVar->setType(mVars[v].type); 415 416 newVar = newDeclVar; 417 } 418 else 419 { 420 Var* newDeclVar = new Var(mVars[v].varName, mVars[v].type); 421 422 newDeclVar->arraySize = mVars[v].arraySize; 423 newDeclVar->uniform = mVars[v].uniform; 424 newDeclVar->sampler = mVars[v].sampler; 425 newDeclVar->texture = mVars[v].texture; 426 newDeclVar->constNum = mVars[v].constNum; 427 newDeclVar->constSortPos = mVars[v].constSortPos; 428 429 if (!newDeclVar->uniform) 430 { 431 LangElement* newVarDecl = new DecOp(newDeclVar); 432 newVar = (Var*)newVarDecl; 433 434 declarationStatement = true; 435 } 436 else 437 { 438 newVar = newDeclVar; 439 } 440 } 441 } 442 else 443 { 444 newVar = getVertTexCoord(mVars[v].varName); 445 } 446 447 mVars.erase(v); 448 break; 449 } 450 } 451 452 if (!newVar) 453 { 454 //couldn't find that variable, bail out 455 Con::errorf("CustomShaderFeature::writeLine: unable to find variable %s, meaning it was not declared before being used!", argv[i].getStringValue()); 456 return; 457 } 458 } 459 460 varList.push_back(newVar); 461 } 462 463 //not happy about it, but do a trampoline here to pass along the args 464 465 switch (varList.size()) 466 { 467 case 0: 468 meta->addStatement(new GenOp(format + "\n")); 469 break; 470 case 1: 471 meta->addStatement(new GenOp(format + "\n", varList[0])); 472 break; 473 case 2: 474 meta->addStatement(new GenOp(format + "\n", varList[0], varList[1])); 475 break; 476 case 3: 477 meta->addStatement(new GenOp(format + "\n", varList[0], varList[1], varList[2])); 478 break; 479 case 4: 480 meta->addStatement(new GenOp(format + "\n", varList[0], varList[1], varList[2], varList[3])); 481 break; 482 case 5: 483 meta->addStatement(new GenOp(format + "\n", varList[0], varList[1], varList[2], varList[3], varList[4])); 484 break; 485 } 486} 487 488bool CustomFeatureHLSL::hasFeature(String name) 489{ 490 for (U32 i = 0; i < mFeatureData.materialFeatures.getCount(); i++) 491 { 492 String featureName = mFeatureData.materialFeatures.getAt(i).getName(); 493 if (name == featureName) 494 return true; 495 } 496 497 return false; 498} 499