Torque3D Documentation / _generateds / advancedLightingFeaturesHLSL.cpp

advancedLightingFeaturesHLSL.cpp

Engine/source/lighting/advanced/hlsl/advancedLightingFeaturesHLSL.cpp

More...

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> &macros, 
 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> &macros, 
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