Przeglądaj źródła

Merge branch 'PBR_PR' of https://github.com/rextimmy/Torque3D into PBR_PR

Azaezel 6 lat temu
rodzic
commit
567b30b44a
52 zmienionych plików z 1063 dodań i 595 usunięć
  1. 1 1
      Engine/source/T3D/lighting/reflectionProbe.cpp
  2. 3 0
      Engine/source/gfx/bitmap/ddsData.h
  3. 21 48
      Engine/source/lighting/probeManager.cpp
  4. 11 1
      Engine/source/postFx/postEffect.cpp
  5. 1 0
      Engine/source/postFx/postEffect.h
  6. 1 0
      Templates/Full/game/art/pbr/copper/About these PBR files.txt
  7. BIN
      Templates/Full/game/art/pbr/copper/oxidized-copper-albedo.png
  8. BIN
      Templates/Full/game/art/pbr/copper/oxidized-copper-metal.png
  9. BIN
      Templates/Full/game/art/pbr/copper/oxidized-copper-normal-ue.png
  10. BIN
      Templates/Full/game/art/pbr/copper/oxidized-coppper-roughness.png
  11. BIN
      Templates/Full/game/art/pbr/floor/FloorEbony_ao.png
  12. BIN
      Templates/Full/game/art/pbr/floor/FloorEbony_basecolor.png
  13. BIN
      Templates/Full/game/art/pbr/floor/FloorEbony_metal.png
  14. BIN
      Templates/Full/game/art/pbr/floor/FloorEbony_normal.png
  15. BIN
      Templates/Full/game/art/pbr/floor/FloorEbony_rough.png
  16. BIN
      Templates/Full/game/art/pbr/gold/albedo.png
  17. BIN
      Templates/Full/game/art/pbr/gold/metallic.png
  18. BIN
      Templates/Full/game/art/pbr/gold/normal.png
  19. BIN
      Templates/Full/game/art/pbr/gold/roughness.png
  20. 1 0
      Templates/Full/game/art/pbr/greasy/About these PBR files.txt
  21. BIN
      Templates/Full/game/art/pbr/greasy/greasy-pan-2-albedo.png
  22. BIN
      Templates/Full/game/art/pbr/greasy/greasy-pan-2-metal.png
  23. BIN
      Templates/Full/game/art/pbr/greasy/greasy-pan-2-normal.png
  24. BIN
      Templates/Full/game/art/pbr/greasy/greasy-pan-2-roughness.png
  25. BIN
      Templates/Full/game/art/pbr/plastic/ao.png
  26. BIN
      Templates/Full/game/art/pbr/plastic/metallic.png
  27. BIN
      Templates/Full/game/art/pbr/plastic/plastic_A.dds
  28. BIN
      Templates/Full/game/art/pbr/plastic/plastic_N.dds
  29. BIN
      Templates/Full/game/art/pbr/plastic/roughness.png
  30. BIN
      Templates/Full/game/art/pbr/rusted_iron/albedo.png
  31. BIN
      Templates/Full/game/art/pbr/rusted_iron/ao.png
  32. BIN
      Templates/Full/game/art/pbr/rusted_iron/metallic.png
  33. BIN
      Templates/Full/game/art/pbr/rusted_iron/normal.png
  34. BIN
      Templates/Full/game/art/pbr/rusted_iron/roughness.png
  35. 105 0
      Templates/Full/game/art/shapes/floor/floor.dae
  36. 14 0
      Templates/Full/game/art/shapes/floor/materials.cs
  37. 80 0
      Templates/Full/game/art/shapes/material_ball/material_ball.dae
  38. 77 0
      Templates/Full/game/art/shapes/material_ball/materials.cs
  39. 10 0
      Templates/Full/game/art/shapes/sphere/materials.cs
  40. 79 0
      Templates/Full/game/art/shapes/sphere/sphere.dae
  41. BIN
      Templates/Full/game/core/art/brdfTexture.dds
  42. 8 6
      Templates/Full/game/core/scripts/client/lighting/advanced/shaders.cs
  43. 289 0
      Templates/Full/game/levels/Pbr Mat Test.mis
  44. 97 0
      Templates/Full/game/shaders/common/brdf.hlsl
  45. 111 224
      Templates/Full/game/shaders/common/lighting.hlsl
  46. 15 23
      Templates/Full/game/shaders/common/lighting/advanced/deferredShadingP.hlsl
  47. 3 6
      Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeP.hlsl
  48. 25 106
      Templates/Full/game/shaders/common/lighting/advanced/skylightP.hlsl
  49. 52 137
      Templates/Full/game/shaders/common/lighting/advanced/vectorLightP.hlsl
  50. 37 40
      Templates/Full/game/shaders/common/shaderModel.hlsl
  51. 18 3
      Templates/Full/game/shaders/common/shaderModelAutoGen.hlsl
  52. 4 0
      Templates/Full/game/shaders/common/torque.hlsl

+ 1 - 1
Engine/source/T3D/lighting/reflectionProbe.cpp

@@ -616,7 +616,7 @@ bool ReflectionProbe::createClientResources()
    //brdf lookup resources
    //make the brdf lookup texture the same size as the prefilter texture
    
-   String brdfPath = Con::getVariable("$Core::BRDFTexture", "core/art/brdfTexture.DDS");
+   String brdfPath = Con::getVariable("$Core::BRDFTexture", "core/art/brdfTexture.dds");
 
    mBrdfTexture = TEXMGR->createTexture(brdfPath, &GFXTexturePersistentProfile);// TEXMGR->createTexture(mPrefilterSize, mPrefilterSize, GFXFormatR16G16B16A16F, &GFXRenderTargetProfile, 1, 0);
 

+ 3 - 0
Engine/source/gfx/bitmap/ddsData.h

@@ -619,6 +619,7 @@ namespace dds
          //float
          case D3DFMT_R16F:          return GFXFormatR16F;
          case D3DFMT_R32F:          return GFXFormatR32F;
+         case D3DFMT_G16R16F:       return GFXFormatR16G16F;
          case D3DFMT_A16B16G16R16F: return GFXFormatR16G16B16A16F;
          case D3DFMT_A32B32G32R32F: return GFXFormatR32G32B32A32F;
          //compressed
@@ -655,6 +656,7 @@ namespace dds
          //float
          case DXGI_FORMAT_R16_FLOAT:            return GFXFormatR16F;
          case DXGI_FORMAT_R32_FLOAT:            return GFXFormatR32F;
+         case DXGI_FORMAT_R16G16_FLOAT:         return GFXFormatR16G16F;
          case DXGI_FORMAT_R16G16B16A16_FLOAT:   return GFXFormatR16G16B16A16F;
          case DXGI_FORMAT_R32G32B32A32_FLOAT:   return GFXFormatR32G32B32A32F;
          //compressed
@@ -731,6 +733,7 @@ namespace dds
          case D3DFMT_ATI2: return GFXFormatBC5;
          case D3DFMT_A16B16G16R16F: return GFXFormatR16G16B16A16F;
          case D3DFMT_A32B32G32R32F: return GFXFormatR32G32B32A32F;
+         case D3DFMT_G16R16F: return GFXFormatR16G16F;
          default:
          {
             Con::errorf("dds::getGFXFormatFourcc: unknown format");

+ 21 - 48
Engine/source/lighting/probeManager.cpp

@@ -592,7 +592,7 @@ ProbeManager::SkylightMaterialInfo* ProbeManager::getSkylightMaterial()
 	if (!mSkylightMaterial)
 
 		// Now create the material info object.
-		mSkylightMaterial = new SkylightMaterialInfo("SklyightMaterial",
+		mSkylightMaterial = new SkylightMaterialInfo("SkyLightMaterial",
 			getGFXVertexFormat<GFXVertexPC>());
 
 	return mSkylightMaterial;
@@ -896,62 +896,35 @@ void ProbeManager::ReflectProbeMaterialInfo::setProbeParameters(const ProbeRende
 	matParams->setSafe(attenuation, attenParams);
 
 	NamedTexTarget* deferredTexTarget = NamedTexTarget::find("deferred");
+   NamedTexTarget* matInfoTexTarget = NamedTexTarget::find("matinfo");
+   NamedTexTarget* colorTexTarget = NamedTexTarget::find("color");
 
-	GFXTextureObject *deferredTexObject = deferredTexTarget->getTexture();
-	if (!deferredTexObject) return;
-
-	GFX->setTexture(0, deferredTexObject);
-
-	NamedTexTarget* matInfoTexTarget = NamedTexTarget::find("matinfo");
-
-	GFXTextureObject *matInfoTexObject = matInfoTexTarget->getTexture();
-	if (!matInfoTexObject) return;
-
-	GFX->setTexture(1, matInfoTexObject);
-
-	if (probeInfo->mCubemap && !probeInfo->mCubemap->isNull())
-	{
-		GFX->setCubeTexture(2, probeInfo->mCubemap->getPointer());
-	}
-	else
-	{
-		GFX->setCubeTexture(2, NULL);
-	}
-
-	if (probeInfo->mIrradianceCubemap && !probeInfo->mIrradianceCubemap->isNull())
-	{
-		GFX->setCubeTexture(3, probeInfo->mIrradianceCubemap->getPointer());
-	}
-	else
-	{
-		GFX->setCubeTexture(3, NULL);
-	}
-
-	if (probeInfo->mBRDFTexture && !probeInfo->mBRDFTexture->isNull())
-	{
-		GFX->setTexture(4, probeInfo->mBRDFTexture->getPointer());
-	}
-	else
-	{
-		GFX->setTexture(4, NULL);
-	}
+   if (!deferredTexTarget || !matInfoTexTarget || !colorTexTarget)
+   {
+      Con::errorf("ProbeManager::ReflectProbeMaterialInfo::setProbeParameters: Could not retrieve gbuffer");
+      return;
+   }
 
-   if (probeInfo->mCubemap->isValid())
-      matParams->setSafe(cubeMips, mPow(probeInfo->mCubemap->getPointer()->getMipMapLevels(), 2.0f));
-   else
-      matParams->setSafe(cubeMips, F32(0.0));
+   //set textures
+   GFX->setTexture(0, deferredTexTarget->getTexture());
+	GFX->setTexture(1, matInfoTexTarget->getTexture());
+   GFX->setTexture(2, colorTexTarget->getTexture());
+   GFX->setCubeTexture(3, probeInfo->mCubemap->getPointer());
+   GFX->setCubeTexture(4, probeInfo->mIrradianceCubemap->getPointer());
+   GFX->setTexture(5, probeInfo->mBRDFTexture->getPointer());
 
+   //set material params
+   matParams->setSafe(cubeMips, mPow(probeInfo->mCubemap->getPointer()->getMipMapLevels(), 2.0f));
 	matParams->setSafe(eyePosWorld, renderState->getCameraPosition());
 	matParams->setSafe(bbMin, probeInfo->mBounds.minExtents);
 	matParams->setSafe(bbMax, probeInfo->mBounds.maxExtents);
-
 	matParams->setSafe(useSphereMode, probeInfo->mProbeShapeType == ProbeRenderInst::Sphere ? 1.0f : 0.0f);
 
 	//SH Terms
 	//static AlignedArray<Point3F> shTermsArray(9, sizeof(Point3F));
 	//dMemset(shTermsArray.getBuffer(), 0, shTermsArray.getBufferSize());
 
-	for (U32 i = 0; i < 9; i++)
+	/*for (U32 i = 0; i < 9; i++)
 	{
 		matParams->setSafe(shTerms[i], probeInfo->mSHTerms[i]);
 	}
@@ -959,7 +932,7 @@ void ProbeManager::ReflectProbeMaterialInfo::setProbeParameters(const ProbeRende
 	for (U32 i = 0; i < 5; i++)
 	{
 		matParams->setSafe(shConsts[i], probeInfo->mSHConstants[i]);
-	}
+	}*/
 
    const MatrixF worldToObjectXfm = probeInfo->mTransform;
    MaterialParameterHandle *worldToObjMat = matInstance->getMaterialParameterHandle("$worldToObj");
@@ -996,11 +969,11 @@ ProbeManager::SkylightMaterialInfo::SkylightMaterialInfo(const String &matName,
 
 	eyePosWorld = matInstance->getMaterialParameterHandle("$eyePosWorld");
 
-	for (U32 i = 0; i < 9; i++)
+	/*for (U32 i = 0; i < 9; i++)
 		shTerms[i] = matInstance->getMaterialParameterHandle(String::ToString("$SHTerms%d", i));
 
 	for (U32 i = 0; i < 5; i++)
-		shConsts[i] = matInstance->getMaterialParameterHandle(String::ToString("$SHConsts%d", i));
+		shConsts[i] = matInstance->getMaterialParameterHandle(String::ToString("$SHConsts%d", i));*/
 }
 
 ProbeManager::SkylightMaterialInfo::~SkylightMaterialInfo()

+ 11 - 1
Engine/source/postFx/postEffect.cpp

@@ -309,7 +309,8 @@ PostEffect::PostEffect()
       mCameraForwardSC( NULL ),
       mAccumTimeSC( NULL ),
       mDeltaTimeSC( NULL ),
-      mInvCameraMatSC( NULL )
+      mInvCameraMatSC( NULL ),
+      mMatCameraToWorldSC( NULL)
 {
    dMemset( mTexSRGB, 0, sizeof(bool) * NumTextures);
    dMemset( mActiveTextures, 0, sizeof( GFXTextureObject* ) * NumTextures );
@@ -615,6 +616,8 @@ void PostEffect::_setupConstants( const SceneRenderState *state )
       mDeltaTimeSC = mShader->getShaderConstHandle( "$deltaTime" );
 
       mInvCameraMatSC = mShader->getShaderConstHandle( "$invCameraMat" );
+
+      mMatCameraToWorldSC = mShader->getShaderConstHandle("$cameraToWorld");
    }
 
    // Set up shader constants for source image size
@@ -749,6 +752,13 @@ void PostEffect::_setupConstants( const SceneRenderState *state )
       mShaderConsts->set( mAmbientColorSC, ambientColor );
    }
 
+   if (mMatCameraToWorldSC->isValid())
+   {
+      MatrixF tempMat = thisFrame.worldToCamera;
+      tempMat.inverse();
+      mShaderConsts->set(mMatCameraToWorldSC, tempMat);
+   }
+
    mShaderConsts->setSafe( mAccumTimeSC, MATMGR->getTotalTime() );
    mShaderConsts->setSafe( mDeltaTimeSC, MATMGR->getDeltaTime() );
 

+ 1 - 0
Engine/source/postFx/postEffect.h

@@ -142,6 +142,7 @@ protected:
    GFXShaderConstHandle *mAccumTimeSC;
    GFXShaderConstHandle *mDeltaTimeSC;
    GFXShaderConstHandle *mInvCameraMatSC;
+   GFXShaderConstHandle *mMatCameraToWorldSC;
 
    bool mAllowReflectPass;
 

+ 1 - 0
Templates/Full/game/art/pbr/copper/About these PBR files.txt

@@ -0,0 +1 @@
+These texture files were created by FreePBR.com and may be used freely in your video games and 3d work at no cost. They may not however be redistributed on other websites or anywhere else other than FreePBR.com. We think that is more than fair. :) We also would greatly appreciate it if some sorrt of credit was given if you do indeed use these textures in a published game. Other than that, keep on creating and have fun. :)

BIN
Templates/Full/game/art/pbr/copper/oxidized-copper-albedo.png


BIN
Templates/Full/game/art/pbr/copper/oxidized-copper-metal.png


BIN
Templates/Full/game/art/pbr/copper/oxidized-copper-normal-ue.png


BIN
Templates/Full/game/art/pbr/copper/oxidized-coppper-roughness.png


BIN
Templates/Full/game/art/pbr/floor/FloorEbony_ao.png


BIN
Templates/Full/game/art/pbr/floor/FloorEbony_basecolor.png


BIN
Templates/Full/game/art/pbr/floor/FloorEbony_metal.png


BIN
Templates/Full/game/art/pbr/floor/FloorEbony_normal.png


BIN
Templates/Full/game/art/pbr/floor/FloorEbony_rough.png


BIN
Templates/Full/game/art/pbr/gold/albedo.png


BIN
Templates/Full/game/art/pbr/gold/metallic.png


BIN
Templates/Full/game/art/pbr/gold/normal.png


BIN
Templates/Full/game/art/pbr/gold/roughness.png


+ 1 - 0
Templates/Full/game/art/pbr/greasy/About these PBR files.txt

@@ -0,0 +1 @@
+These texture files were created by FreePBR.com and may be used freely in your video games and 3d work at no cost. They may not however be redistributed on other websites or anywhere else other than FreePBR.com. We think that is more than fair. :) We also would greatly appreciate it if some sorrt of credit was given if you do indeed use these textures in a published game. Other than that, keep on creating and have fun. :)

BIN
Templates/Full/game/art/pbr/greasy/greasy-pan-2-albedo.png


BIN
Templates/Full/game/art/pbr/greasy/greasy-pan-2-metal.png


BIN
Templates/Full/game/art/pbr/greasy/greasy-pan-2-normal.png


BIN
Templates/Full/game/art/pbr/greasy/greasy-pan-2-roughness.png


BIN
Templates/Full/game/art/pbr/plastic/ao.png


BIN
Templates/Full/game/art/pbr/plastic/metallic.png


BIN
Templates/Full/game/art/pbr/plastic/plastic_A.dds


BIN
Templates/Full/game/art/pbr/plastic/plastic_N.dds


BIN
Templates/Full/game/art/pbr/plastic/roughness.png


BIN
Templates/Full/game/art/pbr/rusted_iron/albedo.png


BIN
Templates/Full/game/art/pbr/rusted_iron/ao.png


BIN
Templates/Full/game/art/pbr/rusted_iron/metallic.png


BIN
Templates/Full/game/art/pbr/rusted_iron/normal.png


BIN
Templates/Full/game/art/pbr/rusted_iron/roughness.png


Plik diff jest za duży
+ 105 - 0
Templates/Full/game/art/shapes/floor/floor.dae


+ 14 - 0
Templates/Full/game/art/shapes/floor/materials.cs

@@ -0,0 +1,14 @@
+
+singleton Material(Floor_Material)
+{
+   mapTo = "floor_mat";
+   diffuseMap[0] = "art/pbr/floor/FloorEbony_basecolor.png";
+   normalMap[0] = "art/pbr/floor/FloorEbony_normal.png";
+   roughMap[0] = "art/pbr/floor/FloorEbony_rough.png";
+   aoMap[0] = "art/pbr/floor/FloorEbony_ao.png";
+   metalMap[0] = "art/pbr/floor/FloorEbony_metal.png";
+   invertSmoothness[0] = "1";
+   useAnisotropic[0] = "1";
+   translucentBlendOp = "None";
+   materialTag0 = "pbr";
+};

Plik diff jest za duży
+ 80 - 0
Templates/Full/game/art/shapes/material_ball/material_ball.dae


+ 77 - 0
Templates/Full/game/art/shapes/material_ball/materials.cs

@@ -0,0 +1,77 @@
+
+singleton Material(Mat_base_material_ball)
+{
+   mapTo = "base_material_ball";
+   diffuseColor[0] = "1 1 1 1";
+   smoothness[0] = "1";
+   metalness[0] = "1";
+   translucentBlendOp = "None";
+   materialTag0 = "pbr";
+};
+
+singleton Material(Mat_gold_material_ball)
+{
+   mapTo = "gold_material_ball";
+   diffuseMap[0] = "art/pbr/gold/albedo.png";
+   normalMap[0] = "art/pbr/gold/normal.png";
+   roughMap[0] = "art/pbr/gold/roughness.png";
+   metalMap[0] = "art/pbr/gold/metallic.png";
+   invertSmoothness[0] = "1";
+   useAnisotropic[0] = "1";
+   translucentBlendOp = "None";
+   materialTag0 = "pbr";
+};
+
+singleton Material(Mat_plastic_material_ball)
+{
+   mapTo = "plastic_material_ball";
+   diffuseMap[0] = "art/pbr/plastic/plastic_A.dds";
+   normalMap[0] = "art/pbr/plastic/plastic_N.dds";
+   roughMap[0] = "art/pbr/plastic/roughness.png";
+   aoMap[0] = "art/pbr/plastic/ao.png";
+   metalMap[0] = "art/pbr/plastic/metallic.png";
+   useAnisotropic[0] = "1";
+   translucentBlendOp = "None";
+   invertSmoothness[0] = "1";
+   materialTag0 = "pbr";
+};
+
+singleton Material(Mat_iron_material_ball)
+{
+   mapTo = "iron_material_ball";
+   diffuseMap[0] = "art/pbr/rusted_iron/albedo.png";
+   normalMap[0] = "art/pbr/rusted_iron/normal.png";
+   roughMap[0] = "art/pbr/rusted_iron/roughness.png";
+   aoMap[0] = "art/pbr/rusted_iron/ao.png";
+   metalMap[0] = "art/pbr/rusted_iron/metallic.png";
+   invertSmoothness[0] = "1";
+   useAnisotropic[0] = "1";
+   translucentBlendOp = "None";
+   materialTag0 = "pbr";
+};
+
+singleton Material(Mat_greasy_material_ball)
+{
+   mapTo = "greasy_material_ball";
+   diffuseMap[0] = "art/pbr/greasy/greasy-pan-2-albedo.png";
+   normalMap[0] = "art/pbr/greasy/greasy-pan-2-normal.png";
+   roughMap[0] = "art/pbr/greasy/greasy-pan-2-roughness.png";
+   metalMap[0] = "art/pbr/greasy/greasy-pan-2-metal.png";
+   invertSmoothness[0] = "1";
+   useAnisotropic[0] = "1";
+   translucentBlendOp = "None";
+   materialTag0 = "pbr";
+};
+
+singleton Material(Mat_copper_material_ball)
+{
+   mapTo = "copper_material_ball";
+   diffuseMap[0] = "art/pbr/copper/oxidized-copper-albedo.png";
+   normalMap[0] = "art/pbr/copper/oxidized-copper-normal-ue.png";
+   roughMap[0] = "art/pbr/copper/oxidized-coppper-roughness.png";
+   metalMap[0] = "art/pbr/copper/oxidized-copper-metal.png";
+   invertSmoothness[0] = "1";
+   useAnisotropic[0] = "1";
+   translucentBlendOp = "None";
+   materialTag0 = "pbr";
+};

+ 10 - 0
Templates/Full/game/art/shapes/sphere/materials.cs

@@ -0,0 +1,10 @@
+singleton Material(Sphere_material)
+{
+   mapTo = "Sphere_mat";
+   diffuseColor[0] = "1 0 0 1";
+   smoothness[0] = "1";
+   metalness[0] = "1";
+   useAnisotropic[0] = "1";
+   materialTag0 = "Miscellaneous";
+};
+

Plik diff jest za duży
+ 79 - 0
Templates/Full/game/art/shapes/sphere/sphere.dae


BIN
Templates/Full/game/core/art/brdfTexture.dds


+ 8 - 6
Templates/Full/game/core/scripts/client/lighting/advanced/shaders.cs

@@ -386,7 +386,7 @@ new ShaderData( BRDFLookupShader )
    pixVersion = 3.0;
 };
 
-new ShaderData( SklyightShader )
+new ShaderData( SkyLightShader )
 {
    DXVertexShaderFile = "shaders/common/lighting/advanced/convexGeometryV.hlsl";
    DXPixelShaderFile  = "shaders/common/lighting/advanced/skylightP.hlsl";
@@ -396,20 +396,22 @@ new ShaderData( SklyightShader )
 
    samplerNames[0] = "$deferredBuffer";
    samplerNames[1] = "$matInfoBuffer";
-   samplerNames[2] = "$cubeMap";
-   samplerNames[3] = "$irradianceCubemap";
-   samplerNames[4] = "$BRDFTexture";
+   samplerNames[2] = "$colorBuffer";
+   samplerNames[3] = "$cubeMap";
+   samplerNames[4] = "$irradianceCubemap";
+   samplerNames[5] = "$BRDFTexture";
    
    pixVersion = 3.0;
 };
 
-new CustomMaterial( SklyightMaterial )
+new CustomMaterial( SkyLightMaterial )
 {
-   shader = SklyightShader;
+   shader = SkyLightShader;
    stateBlock = AL_ProbeState;
    
    sampler["deferredBuffer"] = "#deferred";
    sampler["matInfoBuffer"] = "#matinfo";
+   sampler["colorBuffer"] = "#color";
    
    pixVersion = 3.0;
 };

+ 289 - 0
Templates/Full/game/levels/Pbr Mat Test.mis

@@ -0,0 +1,289 @@
+//--- OBJECT WRITE BEGIN ---
+new SimGroup(MissionGroup) {
+   canSave = "1";
+   canSaveDynamicFields = "1";
+      cdTrack = "2";
+      CTF_scoreLimit = "5";
+      enabled = "1";
+      musicTrack = "lush";
+
+   new LevelInfo(theLevelInfo) {
+      nearClip = "0.1";
+      visibleDistance = "1000";
+      visibleGhostDistance = "0";
+      decalBias = "0.0015";
+      fogColor = "0.6 0.6 0.7 1";
+      fogDensity = "0";
+      fogDensityOffset = "700";
+      fogAtmosphereHeight = "0";
+      canvasClearColor = "0 0 0 255";
+      ambientLightBlendPhase = "1";
+      ambientLightBlendCurve = "0 0 -1 -1";
+      soundAmbience = "AudioAmbienceDefault";
+      soundDistanceModel = "Linear";
+      canSave = "1";
+      canSaveDynamicFields = "1";
+         desc0 = "PBR Mat Test";
+         enabled = "1";
+         levelName = "A PBR Mat test";
+   };
+   new SkyBox(theSky) {
+      Material = "HdrSky";
+      drawBottom = "1";
+      fogBandHeight = "0";
+      position = "-10.0787 0 0";
+      rotation = "1 0 0 0";
+      scale = "1 1 1";
+      canSave = "1";
+      canSaveDynamicFields = "1";
+   };
+   new Sun(theSun) {
+      azimuth = "15";
+      elevation = "160";
+      color = "1 1 1 1";
+      ambient = "0 0 0 1";
+      brightness = "2";
+      castShadows = "1";
+      staticRefreshFreq = "250";
+      dynamicRefreshFreq = "8";
+      coronaEnabled = "1";
+      coronaMaterial = "Corona_Mat";
+      coronaScale = "0.5";
+      coronaTint = "1 1 1 1";
+      coronaUseLightColor = "1";
+      flareType = "SunFlareExample";
+      flareScale = "1";
+      attenuationRatio = "0 1 1";
+      shadowType = "PSSM";
+      texSize = "1024";
+      overDarkFactor = "2000 1000 500 100";
+      shadowDistance = "400";
+      shadowSoftness = "0.15";
+      numSplits = "4";
+      logWeight = "0.91";
+      fadeStartDistance = "0";
+      lastSplitTerrainOnly = "0";
+      representedInLightmap = "0";
+      shadowDarkenColor = "0 0 0 -1";
+      includeLightmappedGeometryInShadow = "0";
+      position = "4.38005 139.658 -22.3993";
+      rotation = "1 0 0 0";
+      scale = "1 1 1";
+      canSave = "1";
+      canSaveDynamicFields = "1";
+         Direction = "1 1 -1";
+   };
+   new SimGroup(PlayerDropPoints) {
+      canSave = "1";
+      canSaveDynamicFields = "1";
+         enabled = "1";
+
+      new SpawnSphere() {
+         autoSpawn = "0";
+         spawnTransform = "0";
+         radius = "0.5";
+         sphereWeight = "1";
+         indoorWeight = "1";
+         outdoorWeight = "1";
+         isAIControlled = "0";
+         dataBlock = "SpawnSphereMarker";
+         position = "-9.39606 10.3721 3.14272";
+         rotation = "0 0 -1 90.6035";
+         scale = "1 1 1";
+         canSave = "1";
+         canSaveDynamicFields = "1";
+            enabled = "1";
+            homingCount = "0";
+            lockCount = "0";
+      };
+   };
+   new Skylight(theSkyLight) {
+      enabled = "1";
+      ProbeShape = "Box";
+      radius = "10";
+      posOffset = "0 0 0";
+      ReflectionMode = "Baked Cubemap";
+      reflectionPath = "levels/Timmy Test/probes/";
+      Bake = "0";
+      position = "8.74661 10.1457 2.48852";
+      rotation = "1 0 0 0";
+      scale = "1 1 1";
+      canSave = "1";
+      canSaveDynamicFields = "1";
+      persistentId = "247d7009-db8a-11e8-87b8-ed691a78e155";
+   };
+   new TSStatic() {
+      shapeName = "art/shapes/material_ball/material_ball.dae";
+      skin = "iron";
+      playAmbient = "1";
+      meshCulling = "0";
+      originSort = "0";
+      CollisionType = "Collision Mesh";
+      DecalType = "Collision Mesh";
+      allowPlayerStep = "0";
+      alphaFadeEnable = "0";
+      alphaFadeStart = "100";
+      alphaFadeEnd = "150";
+      alphaFadeInverse = "0";
+      renderNormals = "0";
+      forceDetail = "-1";
+      ignoreZodiacs = "0";
+      useGradientRange = "0";
+      gradientRange = "0 180";
+      invertGradientRange = "0";
+      position = "-14.1145 15.7844 2.76337";
+      rotation = "1 0 0 0";
+      scale = "1 1 1";
+      canSave = "1";
+      canSaveDynamicFields = "1";
+   };
+   new TSStatic() {
+      shapeName = "art/shapes/material_ball/material_ball.dae";
+      skin = "plastic";
+      playAmbient = "1";
+      meshCulling = "0";
+      originSort = "0";
+      CollisionType = "Collision Mesh";
+      DecalType = "Collision Mesh";
+      allowPlayerStep = "0";
+      alphaFadeEnable = "0";
+      alphaFadeStart = "100";
+      alphaFadeEnd = "150";
+      alphaFadeInverse = "0";
+      renderNormals = "0";
+      forceDetail = "-1";
+      ignoreZodiacs = "0";
+      useGradientRange = "0";
+      gradientRange = "0 180";
+      invertGradientRange = "0";
+      position = "-16.3895 15.7844 2.76337";
+      rotation = "1 0 0 0";
+      scale = "1 1 1";
+      canSave = "1";
+      canSaveDynamicFields = "1";
+   };
+   new TSStatic() {
+      shapeName = "art/shapes/material_ball/material_ball.dae";
+      skin = "gold";
+      playAmbient = "1";
+      meshCulling = "0";
+      originSort = "0";
+      CollisionType = "Collision Mesh";
+      DecalType = "Collision Mesh";
+      allowPlayerStep = "0";
+      alphaFadeEnable = "0";
+      alphaFadeStart = "100";
+      alphaFadeEnd = "150";
+      alphaFadeInverse = "0";
+      renderNormals = "0";
+      forceDetail = "-1";
+      ignoreZodiacs = "0";
+      useGradientRange = "0";
+      gradientRange = "0 180";
+      invertGradientRange = "0";
+      position = "-11.9028 15.7844 2.76337";
+      rotation = "1 0 0 0";
+      scale = "1 1 1";
+      canSave = "1";
+      canSaveDynamicFields = "1";
+   };
+   new TSStatic() {
+      shapeName = "art/shapes/material_ball/material_ball.dae";
+      skin = "greasy";
+      playAmbient = "1";
+      meshCulling = "0";
+      originSort = "0";
+      CollisionType = "Collision Mesh";
+      DecalType = "Collision Mesh";
+      allowPlayerStep = "0";
+      alphaFadeEnable = "0";
+      alphaFadeStart = "100";
+      alphaFadeEnd = "150";
+      alphaFadeInverse = "0";
+      renderNormals = "0";
+      forceDetail = "-1";
+      ignoreZodiacs = "0";
+      useGradientRange = "0";
+      gradientRange = "0 180";
+      invertGradientRange = "0";
+      position = "-9.71689 15.7844 2.76337";
+      rotation = "1 0 0 0";
+      scale = "1 1 1";
+      canSave = "1";
+      canSaveDynamicFields = "1";
+   };
+   new TSStatic() {
+      shapeName = "art/shapes/material_ball/material_ball.dae";
+      skin = "copper";
+      playAmbient = "1";
+      meshCulling = "0";
+      originSort = "0";
+      CollisionType = "Collision Mesh";
+      DecalType = "Collision Mesh";
+      allowPlayerStep = "0";
+      alphaFadeEnable = "0";
+      alphaFadeStart = "100";
+      alphaFadeEnd = "150";
+      alphaFadeInverse = "0";
+      renderNormals = "0";
+      forceDetail = "-1";
+      ignoreZodiacs = "0";
+      useGradientRange = "0";
+      gradientRange = "0 180";
+      invertGradientRange = "0";
+      position = "-7.6275 15.7844 2.76337";
+      rotation = "1 0 0 0";
+      scale = "1 1 1";
+      canSave = "1";
+      canSaveDynamicFields = "1";
+   };
+   new TSStatic(floor) {
+      shapeName = "art/shapes/floor/floor.dae";
+      playAmbient = "1";
+      meshCulling = "0";
+      originSort = "0";
+      CollisionType = "Collision Mesh";
+      DecalType = "Collision Mesh";
+      allowPlayerStep = "0";
+      alphaFadeEnable = "0";
+      alphaFadeStart = "100";
+      alphaFadeEnd = "150";
+      alphaFadeInverse = "0";
+      renderNormals = "0";
+      forceDetail = "-1";
+      ignoreZodiacs = "0";
+      useGradientRange = "0";
+      gradientRange = "0 180";
+      invertGradientRange = "0";
+      position = "-11.7037 15.245 1.7387";
+      rotation = "1 0 0 0";
+      scale = "1 1 1";
+      canSave = "1";
+      canSaveDynamicFields = "1";
+   };
+   new TSStatic() {
+      shapeName = "art/shapes/sphere/sphere.dae";
+      playAmbient = "1";
+      meshCulling = "0";
+      originSort = "0";
+      CollisionType = "Collision Mesh";
+      DecalType = "Collision Mesh";
+      allowPlayerStep = "0";
+      alphaFadeEnable = "0";
+      alphaFadeStart = "100";
+      alphaFadeEnd = "150";
+      alphaFadeInverse = "0";
+      renderNormals = "0";
+      forceDetail = "-1";
+      ignoreZodiacs = "0";
+      useGradientRange = "0";
+      gradientRange = "0 180";
+      invertGradientRange = "0";
+      position = "-10.15 -3.23709 3.47759";
+      rotation = "1 0 0 0";
+      scale = "1 1 1";
+      canSave = "1";
+      canSaveDynamicFields = "1";
+   };
+};
+//--- OBJECT WRITE END ---

+ 97 - 0
Templates/Full/game/shaders/common/brdf.hlsl

@@ -0,0 +1,97 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2018 GarageGames, LLC
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#ifndef BRDF_HLSL
+#define BRDF_HLSL
+
+#include "./torque.hlsl"
+
+// BRDF from Frostbite presentation:
+// Moving Frostbite to Physically Based Rendering// S´ebastien Lagarde - Electronic Arts Frostbite
+// Charles de Rousiers - Electronic Arts Frostbite
+// SIGGRAPH 2014
+
+float3 F_Schlick(in float3 f0, in float f90, in float u)
+{
+	return f0 + (f90 - f0) * pow(1.f - u, 5.f);
+}
+
+float3 F_Fresnel(float3 SpecularColor, float VoH)
+{
+	float3 SpecularColorSqrt = sqrt(min(SpecularColor, float3(0.99, 0.99, 0.99)));
+	float3 n = (1 + SpecularColorSqrt) / (1 - SpecularColorSqrt);
+	float3 g = sqrt(n*n + VoH*VoH - 1);
+	return 0.5 * sqr((g - VoH) / (g + VoH)) * (1 + sqr(((g + VoH)*VoH - 1) / ((g - VoH)*VoH + 1)));
+}
+
+float3 FresnelSchlickRoughness(float cosTheta, float3 F0, float roughness)
+{
+	float3 ret = float3(0.0, 0.0, 0.0);
+	float powTheta = pow(1.0 - cosTheta, 5.0);
+	float invRough = float(1.0 - roughness);
+
+	ret.x = F0.x + (max(invRough, F0.x) - F0.x) * powTheta;
+	ret.y = F0.y + (max(invRough, F0.y) - F0.y) * powTheta;
+	ret.z = F0.z + (max(invRough, F0.z) - F0.z) * powTheta;
+
+	return ret;
+}
+
+float Fr_DisneyDiffuse(float NdotV, float NdotL, float LdotH, float linearRoughness)
+{
+	float energyBias = lerp(0, 0.5, linearRoughness);
+	float energyFactor = lerp(1.0, 1.0 / 1.51, linearRoughness);
+	float fd90 = energyBias + 2.0 * LdotH*LdotH * linearRoughness;
+	float3 f0 = float3(1.0f, 1.0f, 1.0f);
+	float lightScatter = F_Schlick(f0, fd90, NdotL).r;
+	float viewScatter = F_Schlick(f0, fd90, NdotV).r;
+
+	return lightScatter * viewScatter * energyFactor;
+}
+
+float V_SmithGGXCorrelated(float NdotL, float NdotV, float alphaG2)
+{
+	// Original formulation of G_SmithGGX Correlated 
+	// lambda_v = (-1 + sqrt(alphaG2 * (1 - NdotL2) / NdotL2 + 1)) * 0.5f; 
+	// lambda_l = (-1 + sqrt(alphaG2 * (1 - NdotV2) / NdotV2 + 1)) * 0.5f; 
+	// G_SmithGGXCorrelated = 1 / (1 + lambda_v + lambda_l); 
+	// V_SmithGGXCorrelated = G_SmithGGXCorrelated / (4.0f * NdotL * NdotV); 
+
+
+	// This is the optimized version 
+	//float alphaG2 = alphaG * alphaG;
+
+	// Caution: the "NdotL *" and "NdotV *" are explicitely inversed , this is not a mistake. 
+	float Lambda_GGXV = NdotL * sqrt((-NdotV * alphaG2 + NdotV) * NdotV + alphaG2);
+	float Lambda_GGXL = NdotV * sqrt((-NdotL * alphaG2 + NdotL) * NdotL + alphaG2);
+
+	return 0.5f / (Lambda_GGXV + Lambda_GGXL);
+}
+
+float D_GGX(float NdotH, float m2)
+{
+	// Divide by PI is apply later 
+	//float m2 = m * m;
+	float f = (NdotH * m2 - NdotH) * NdotH + 1;
+	return m2 / (f * f);
+}
+
+#endif

+ 111 - 224
Templates/Full/game/shaders/common/lighting.hlsl

@@ -21,6 +21,8 @@
 //-----------------------------------------------------------------------------
 
 #include "./torque.hlsl"
+#include "./brdf.hlsl"
+#include "./shaderModelAutoGen.hlsl"
 
 #ifndef TORQUE_SHADERGEN
 
@@ -37,141 +39,20 @@ uniform float4 inLightColor[4];
 #endif
 
 uniform float4 ambient;
-#define ambientCameraFactor 0.3
 uniform float smoothness;
 uniform float metalness;
 uniform float4 albedo;
 
 #endif // !TORQUE_SHADERGEN
 
-
-float3 F_schlick( in float3 f0, in float3 f90, in float u )
-{
-	//
-    //  F( v, h ) =  F0 + ( 1.0 - F0 ) *  pow( 1.0f - HdotV,  5.0f )
-    //
-    //
-    //  where 
-    //
-    //  F0 = BaseColor * nDotL
-    //
-    //  Dielectric materials always have a range of 0.02 < F0 < 0.05 , use a stock value of 0.04 ( roughly plastics )
-    //
-
-	return f0 + ( f90 - f0 ) * pow( 1.0f - u ,  5.0f );
-}
-
-float Fr_DisneyDiffuse ( float NdotV , float NdotL , float LdotH , float linearRoughness )
+//deferred lighting output
+struct LightTargetOutput
 {
-	float energyBias = lerp (0 , 0.5 , linearRoughness );
-	float energyFactor = lerp (1.0 , 1.0 / 1.51 , linearRoughness );
-	float fd90 = energyBias + 2.0 * LdotH * LdotH * linearRoughness ;
-	float3 f0 = float3 ( 1.0f , 1.0f , 1.0f );
-	float lightScatter = F_schlick( f0 , fd90 , NdotL ).r;
-	float viewScatter = F_schlick(f0 , fd90 , NdotV ).r;
-
-	return lightScatter * viewScatter * energyFactor;
-}
-
-float SmithGGX( float NdotL, float NdotV, float alpha )
-{
-    //
-    // G( L, V, h ) = G( L ) G( V )
-    //
-    //                    nDotL
-    // G( L ) = _________________________
-    //             nDotL ( 1 - k ) + k
-    //
-    //         
-    //                     NdotV
-    // G( V ) = _________________________
-    //             NdotV ( 1 - k ) + k
-    //
-    //
-    //               pow( ( Roughness + 1 ), 2)
-    //  , Where  k = __________________________     ( unreal 4 )
-    //                          8
-    //
-	
-	float alphaSqr = alpha * alpha;
-
-	//float GGX_V = NdotL * sqrt ( ( - NdotV * alphaSqr + NdotV ) * NdotV + alphaSqr );
-	//float GGX_L = NdotV * sqrt ( ( - NdotL * alphaSqr + NdotL ) * NdotL + alphaSqr );
-	
-	float GGX_V = NdotL + sqrt ( ( - NdotV * alphaSqr + NdotV ) * NdotV + alphaSqr );
-	float GGX_L = NdotV + sqrt ( ( - NdotL * alphaSqr + NdotL ) * NdotL + alphaSqr );
-	
-	return rcp( GGX_V + GGX_L ); 
-	//return 0.5f / ( GGX_V + GGX_L ); 
-}
-
-float D_GGX( float NdotH , float alpha )
-{
-    //
-    // or GGX ( disney / unreal 4 )
-    //
-    //  alpha = pow( roughness, 2 );
-    //
-    //                                    pow( alpha, 2 )
-    //  D( h ) = ________________________________________________________________      
-    //           PI pow( pow( NdotH , 2 ) ( pow( alpha, 2 ) - 1 ) + 1 ), 2 )
-    //
-
-	float alphaSqr = alpha*alpha;
-	float f = ( NdotH * alphaSqr - NdotH ) * NdotH + 1;
-	return alphaSqr / ( M_PI_F * (f * f) );
-}
-
-float4 EvalBDRF( float3 baseColor, float3 lightColor, float3 toLight, float3 position, float3 normal,  float roughness, float metallic )
-{
-	//
-    //  Microfacet Specular Cook-Torrance
-    //
-    //                D( h ) F( v, h ) G( l, v, h )
-    //    f( l, v ) = ____________________________
-    //                 4 ( dot( n, l ) dot( n, v )
-    //                 
-    //
-
-	float3 L = normalize( toLight );
-	float3 V = normalize( -position );
-	float3 H = normalize( L + V );
-	float3 N = normal;
-	
-	float NdotV = abs( dot( N, V ) ) + 1e-5f;
-	float NdotH = saturate( dot( N, H ) );
-	float NdotL = saturate( dot( N, L ) );
-	float LdotH = saturate( dot( L, H ) );
-	
-	float VdotH = saturate( dot( V, H ) );
-
-	if ( NdotL == 0 ) 
-		return float4( 0.0f, 0.0f, 0.0f, 0.0f ); 
-	
-	float alpha = roughness;
-	float visLinAlpha = alpha * alpha;
-	
-	float3 f0 = baseColor;
-	float  metal = metallic;
-	
-	float3 F_conductor= F_schlick( f0, float3( 1.0, 1.0, 1.0 ), VdotH );
-	float3 F_dielec   = F_schlick( float3( 0.04, 0.04, 0.04 ), float3( 1.0, 1.0, 1.0 ), VdotH );
-	float  Vis        = SmithGGX( NdotL, NdotV, visLinAlpha );
-	float  D          = D_GGX( NdotH, visLinAlpha );
-	
-	float3 Fr_dielec    = D * F_dielec * Vis; 
-	float3 Fr_conductor = D * F_conductor * Vis; 
-	
-	float3 Fd = Fr_DisneyDiffuse( NdotV , NdotL , LdotH , visLinAlpha ) / M_PI_F ;
-   float3 specular = ( 1.0f - metal ) * Fr_dielec + metal * Fr_conductor;
-	float3 diffuse  = ( 1.0f - metal ) * Fd * f0;
-   
-   float3 ret = ( diffuse + specular + lightColor) * NdotL;
-	
-	float FR = saturate(length(specular));
-	return float4(ret,FR);
-}
+    float4 spec: TORQUE_TARGET0;
+    float4 diffuse: TORQUE_TARGET1;
+};
 
+//TODO fix compute 4 lights
 void compute4Lights( float3 wsView, 
                      float3 wsPosition, 
                      float3 wsNormal,
@@ -194,115 +75,121 @@ void compute4Lights( float3 wsView,
                      out float4 outDiffuse,
                      out float4 outSpecular )
 {
-   // NOTE: The light positions and spotlight directions
-   // are stored in SoA order, so inLightPos[0] is the
-   // x coord for all 4 lights... inLightPos[1] is y... etc.
-   //
-   // This is the key to fully utilizing the vector units and
-   // saving a huge amount of instructions.
-   //
-   // For example this change saved more than 10 instructions 
-   // over a simple for loop for each light.
-   
-   int i;
-
-   float4 lightVectors[3];
-   for ( i = 0; i < 3; i++ )
-      lightVectors[i] = wsPosition[i] - inLightPos[i];
-
-   // Accumulate the dot product between the light 
-   // vector and the normal.
-   //
-   // The normal is negated because it faces away from
-   // the surface and the light faces towards the
-   // surface... this keeps us from needing to flip
-   // the light vector direction which complicates
-   // the spot light calculations.
-   //
-   // We normalize the result a little later.
-   //
-   float4 nDotL = 0;
-   for ( i = 0; i < 3; i++ )
-      nDotL += lightVectors[i] * -wsNormal[i];
-
-   float4 squareDists = 0;
-   for ( i = 0; i < 3; i++ )
-      squareDists += lightVectors[i] * lightVectors[i];
-   half4 correction = (half4)rsqrt( squareDists );
-   nDotL = saturate( nDotL * correction );
-
-   // First calculate a simple point light linear 
-   // attenuation factor.
-   //
-   // If this is a directional light the inverse
-   // radius should be greater than the distance
-   // causing the attenuation to have no affect.
-   //
-   float4 atten = saturate( 1.0 - ( squareDists * inLightInvRadiusSq ) );
 
-   #ifndef TORQUE_BL_NOSPOTLIGHT
-
-      // The spotlight attenuation factor.  This is really
-      // fast for what it does... 6 instructions for 4 spots.
-
-      float4 spotAtten = 0;
-      for ( i = 0; i < 3; i++ )
-         spotAtten += lightVectors[i] * inLightSpotDir[i];
+   outDiffuse = float4(0,0,0,0);
+   outSpecular = float4(0,0,0,0);
+}
 
-      float4 cosAngle = ( spotAtten * correction ) - inLightSpotAngle;
-      atten *= saturate( cosAngle * inLightSpotFalloff );
+struct Surface
+{
+	float3 P;				// world space position
+	float3 N;				// world space normal
+	float3 V;				// world space view vector
+	float4 baseColor;		// base color [0 -> 1] (rgba)
+	float metalness;		// metalness [0:dielectric -> 1:metal]
+	float roughness;		// roughness: [0:smooth -> 1:rough] (linear)
+	float roughness_brdf; // roughness remapped from linear to BRDF
+   float depth;         // depth: [0:near -> 1:far] (linear)
+   float ao;            // ambient occlusion [0 -> 1]
+   float matFlag;       // material flag - use getFlag to retreive 
+
+	float NdotV;			// cos(angle between normal and view vector)
+	float3 f0;				// fresnel value (rgb)
+	float3 albedo;			// diffuse light absorbtion value (rgb)
+	float3 R;				// reflection vector
+	float3 F;				// fresnel term computed from f0, N and V
+
+	inline void Update()
+	{
+		NdotV = abs(dot(N, V)) + 1e-5f; // avoid artifact
+
+		albedo = baseColor.rgb * (1.0 - metalness);
+		f0 = lerp(float3_splat(0.04), baseColor.rgb, metalness);
+
+		R = -reflect(V, N);
+		float f90 = saturate(50.0 * dot(f0, 0.33));
+		F = F_Schlick(f0, f90, NdotV);
+	}
+};
+
+inline Surface CreateSurface(TORQUE_SAMPLER2D(gbufferTex0), TORQUE_SAMPLER2D(gbufferTex1), TORQUE_SAMPLER2D(gbufferTex2), in float2 uv, in float3 wsEyePos, in float3 wsEyeRay, in float4x4 invView)
+{
+	Surface surface;
+
+   float4 gbuffer0 = UnpackDepthNormal(TORQUE_SAMPLER2D_MAKEARG(gbufferTex0), uv);
+   float4 gbuffer1 = TORQUE_TEX2DLOD(gbufferTex1, float4(uv,0,0));
+   float4 gbuffer2 = TORQUE_TEX2DLOD(gbufferTex2, float4(uv,0,0));
+
+   surface.depth = gbuffer0.a;
+	surface.P = wsEyePos + wsEyeRay * surface.depth;
+	surface.N = mul(invView, float4(gbuffer0.xyz,0)).xyz;
+	surface.V = normalize(wsEyePos - surface.P);
+	surface.baseColor = gbuffer1;
+   const float minRoughness=1e-4;
+	surface.roughness = clamp(1.0 - gbuffer2.b, minRoughness, 1.0); //torque uses smoothness so we convert to roughness. Should really clamp during gbuffer pass though
+	surface.roughness_brdf = surface.roughness * surface.roughness;
+	surface.metalness = gbuffer2.a;
+   surface.ao = gbuffer2.g;
+   surface.matFlag = gbuffer2.r;
+
+	surface.Update();
+	return surface;
+}
 
-   #endif
-   
-   // Get the final light intensity.
-   float4 intensity = nDotL * atten;
+struct SurfaceToLight
+{
+	float3 L;				// surface to light vector
+	float3 H;				// half-vector between view vector and light vector
+	float NdotL;			// cos(angle between N and L)
+	float HdotV;			// cos(angle between H and V) = HdotL = cos(angle between H and L)
+	float NdotH;			// cos(angle between N and H)
+};
+
+inline SurfaceToLight CreateSurfaceToLight(in Surface surface, in float3 L)
+{
+	SurfaceToLight surfaceToLight;
 
-   // Combine the light colors for output.
-   float4 lightColor = 0;
-   for ( i = 0; i < 4; i++ )
-      lightColor += intensity[i] * inLightColor[i];
-      
-   float3 toLight = 0;
-   for ( i = 0; i < 3; i++ )
-      toLight += lightVectors[i].rgb;
+	surfaceToLight.L = normalize(L);
+	surfaceToLight.H = normalize(surface.V + surfaceToLight.L);
+	surfaceToLight.NdotL = saturate(dot(surfaceToLight.L, surface.N));
+	surfaceToLight.HdotV = saturate(dot(surfaceToLight.H, surface.V));
+	surfaceToLight.NdotH = saturate(dot(surfaceToLight.H, surface.N));
 
-   outDiffuse = float4(albedo.rgb*(1.0-metalness),albedo.a);
-   outSpecular = EvalBDRF( float3( 1.0, 1.0, 1.0 ), lightColor.rgb, toLight, wsPosition, wsNormal, smoothness, metalness );
+	return surfaceToLight;
 }
 
-float G1V(float dotNV, float k)
+float3 BRDF_GetSpecular(in Surface surface, in SurfaceToLight surfaceToLight)
 {
-	return 1.0f/(dotNV*(1.0f-k)+k);
+	float f90 = saturate(50.0 * dot(surface.f0, 0.33));
+	float3 F = F_Schlick(surface.f0, f90, surfaceToLight.HdotV);
+	float Vis = V_SmithGGXCorrelated(surface.NdotV, surfaceToLight.NdotL, surface.roughness_brdf);
+	float D = D_GGX(surfaceToLight.NdotH, surface.roughness_brdf);
+	float3 Fr = D * F * Vis / M_PI_F;
+	return Fr;
 }
 
-float3 directSpecular(float3 N, float3 V, float3 L, float roughness, float F0)
+float BRDF_GetDiffuse(in Surface surface, in SurfaceToLight surfaceToLight)
 {
-	float alpha = roughness*roughness;
-
-	//TODO don't need to calculate all this again timmy!!!!!!
-    float3 H = normalize(V + L);
-    float dotNL = clamp(dot(N,L), 0.0, 1.0);
-    float dotNV = clamp(dot(N,V), 0.0, 1.0);
-    float dotNH = clamp(dot(N,H), 0.0, 1.0);
-	float dotHV = clamp(dot(H,V), 0.0, 1.0);
-	float dotLH = clamp(dot(L,H), 0.0, 1.0);
-
-	float F, D, vis;
+   //getting some banding with disney method, using lambert instead - todo do some futher testing
+	float Fd = 1.0 / M_PI_F;//Fr_DisneyDiffuse(surface.NdotV, surfaceToLight.NdotL, surfaceToLight.HdotV, surface.roughness) / M_PI_F;
+	return Fd;
+}
 
-	// D
-	float alphaSqr = alpha*alpha;
-	float pi = 3.14159f;
-	float denom = dotNH * dotNH *(alphaSqr-1.0) + 1.0f;
-	D = alphaSqr/(pi * denom * denom);
+struct LightResult
+{
+   float3 diffuse;
+   float3 spec;
+};
 
-	// F
-	float dotLH5 = pow(1.0f-dotLH,5);
-	F = F0 + (1.0-F0)*(dotLH5);
+inline LightResult GetDirectionalLight(in Surface surface, in SurfaceToLight surfaceToLight, float3 lightColor, float lightIntensity, float shadow)
+{
+   LightResult result;
+   float3 factor = lightColor * max(surfaceToLight.NdotL, 0) * shadow * lightIntensity;
+   result.diffuse = BRDF_GetDiffuse(surface,surfaceToLight) * factor;
+   result.spec = BRDF_GetSpecular(surface,surfaceToLight) * factor;
 
-	// V
-	float k = alpha/2.0f;
-	vis = G1V(dotNL,k)*G1V(dotNV,k);
+   result.diffuse = max(0.0f, result.diffuse);
+   result.spec = max(0.0f, result.spec);
 
-	float specular = dotNL * D * F * vis;
-	return float3(specular,specular,specular);
-}
+   return result;
+}

+ 15 - 23
Templates/Full/game/shaders/common/lighting/advanced/deferredShadingP.hlsl

@@ -20,9 +20,9 @@
 // IN THE SOFTWARE.
 //-----------------------------------------------------------------------------
 
-#include "../../shaderModelAutoGen.hlsl"
 #include "../../postfx/postFx.hlsl"
 #include "shaders/common/torque.hlsl"
+#include "shaders/common/lighting.hlsl"
 
 TORQUE_UNIFORM_SAMPLER2D(colorBufferTex,0);
 TORQUE_UNIFORM_SAMPLER2D(diffuseLightingBuffer,1);
@@ -30,31 +30,23 @@ TORQUE_UNIFORM_SAMPLER2D(matInfoTex,2);
 TORQUE_UNIFORM_SAMPLER2D(specularLightingBuffer,3);
 TORQUE_UNIFORM_SAMPLER2D(deferredTex,4);
 
-float4 main( PFXVertToPix IN ) : TORQUE_TARGET0
-{        
-   float depth = TORQUE_DEFERRED_UNCONDITION( deferredTex, IN.uv0 ).w;
+uniform float4x4 cameraToWorld;
+uniform float3 eyePosWorld;
 
-   if (depth>0.9999)
+//TODO add in emission
+float4 main( PFXVertToPix IN ) : TORQUE_TARGET0
+{
+   //create surface
+   Surface surface = CreateSurface( TORQUE_SAMPLER2D_MAKEARG(deferredTex), TORQUE_SAMPLER2D_MAKEARG(colorBufferTex),TORQUE_SAMPLER2D_MAKEARG(matInfoTex),
+                                    IN.uv0, eyePosWorld, IN.wsEyeRay, cameraToWorld);
+   //sky check
+   if (surface.depth>0.9999)
       return float4(0,0,0,0);
-
-   float3 albedo = TORQUE_TEX2D( colorBufferTex, IN.uv0 ).rgb; //albedo
-   float4 matInfo = TORQUE_TEX2D(matInfoTex, IN.uv0); //flags|smoothness|ao|metallic
-
-   bool emissive = getFlag(matInfo.r, 0);
-   if (emissive)
-   {
-      return float4(albedo, 1.0);
-   }
 	  
-   float4 diffuse = TORQUE_TEX2D( diffuseLightingBuffer, IN.uv0 ); //shadowmap*specular
-   float4 specular = TORQUE_TEX2D( specularLightingBuffer, IN.uv0 ); //environment mapping*lightmaps
-   
-   float metalness = matInfo.a;
-   
-   float3 diffuseColor = albedo - (albedo * metalness);
-   float3 specularColor = lerp(float3(0.04,0.04,0.04), albedo, metalness);
+   float4 diffuse = TORQUE_TEX2DLOD( diffuseLightingBuffer, float4(IN.uv0,0,0)); 
+   float4 specular = TORQUE_TEX2DLOD( specularLightingBuffer, float4(IN.uv0,0,0));
 
-   float3 light = (diffuseColor * diffuse.rgb) + (specularColor * specular.rgb);
+   float3 sceneColor = (surface.albedo * diffuse.rgb) + (surface.F * specular.rgb) * surface.ao;
    
-   return float4(light.rgb, 1.0);
+   return float4(sceneColor.rgb, 1.0);
 }

+ 3 - 6
Templates/Full/game/shaders/common/lighting/advanced/reflectionProbeP.hlsl

@@ -163,16 +163,15 @@ PS_OUTPUT main( ConvexConnectP IN )
     float3 ssPos = IN.ssPos.xyz / IN.ssPos.w; 
 
     float2 uvScene = getUVFromSSPos( ssPos, rtParams0 );
-
-    // Matinfo flags
-    float4 matInfo = TORQUE_TEX2D( matInfoBuffer, uvScene ); 
-
     // Sample/unpack the normal/z data
     float4 deferredSample = TORQUE_DEFERRED_UNCONDITION( deferredBuffer, uvScene );
     float3 normal = deferredSample.rgb;
     float depth = deferredSample.a;
     if (depth>0.9999)
           clip(-1);
+    
+    // Matinfo flags
+    float4 matInfo = TORQUE_TEX2D( matInfoBuffer, uvScene ); 
 
     // Need world-space normal.
     float3 wsNormal = mul(cameraToWorld, float4(normal, 0)).xyz;
@@ -206,7 +205,5 @@ PS_OUTPUT main( ConvexConnectP IN )
 	float3 surfToEye = normalize(wsPos - eyePosWorld);
 	Output.diffuse = float4(iblBoxDiffuse(wsNormal, wsPos, TORQUE_SAMPLERCUBE_MAKEARG(irradianceCubemap), probeWSPos, bbMin, bbMax), blendVal);
 	Output.spec = float4(iblBoxSpecular(wsNormal, wsPos, 1.0 - matInfo.b, surfToEye, TORQUE_SAMPLER2D_MAKEARG(BRDFTexture), TORQUE_SAMPLERCUBE_MAKEARG(cubeMap), probeWSPos, bbMin, bbMax), blendVal);
-	Output.diffuse.rgb *= matInfo.g;
-	Output.spec.rgb *= matInfo.g;
 	return Output;
 }

+ 25 - 106
Templates/Full/game/shaders/common/lighting/advanced/skylightP.hlsl

@@ -15,71 +15,16 @@ struct ConvexConnectP
 
 TORQUE_UNIFORM_SAMPLER2D(deferredBuffer, 0);
 TORQUE_UNIFORM_SAMPLER2D(matInfoBuffer, 1);
-TORQUE_UNIFORM_SAMPLERCUBE(cubeMap, 2);
-TORQUE_UNIFORM_SAMPLERCUBE(irradianceCubemap, 3);
-TORQUE_UNIFORM_SAMPLER2D(BRDFTexture, 4);
-
+TORQUE_UNIFORM_SAMPLER2D(colorBuffer, 2);
+TORQUE_UNIFORM_SAMPLERCUBE(cubeMap, 3);
+TORQUE_UNIFORM_SAMPLERCUBE(irradianceCubemap, 4);
+TORQUE_UNIFORM_SAMPLER2D(BRDFTexture, 5);
 
 uniform float4 rtParams0;
-
 uniform float4 vsFarPlane;
-
 uniform float4x4 cameraToWorld;
-
 uniform float3 eyePosWorld;
 
-//SHTerms
-/*uniform float4 SHTerms0;
-uniform float4 SHTerms1;
-uniform float4 SHTerms2;
-uniform float4 SHTerms3;
-uniform float4 SHTerms4;
-uniform float4 SHTerms5;
-uniform float4 SHTerms6;
-uniform float4 SHTerms7;
-uniform float4 SHTerms8;
-
-uniform float SHConsts0;
-uniform float SHConsts1;
-uniform float SHConsts2;
-uniform float SHConsts3;
-uniform float SHConsts4;
-
-float4 decodeSH(float3 normal)
-{
-   float x = normal.x;
-   float y = normal.y;
-   float z = normal.z;
-
-   float3 l00 = SHTerms0.rgb;
-
-   float3 l10 = SHTerms1.rgb;
-   float3 l11 = SHTerms2.rgb;
-   float3 l12 = SHTerms3.rgb;
-
-   float3 l20 = SHTerms4.rgb;
-   float3 l21 = SHTerms5.rgb;
-   float3 l22 = SHTerms6.rgb;
-   float3 l23 = SHTerms7.rgb;
-   float3 l24 = SHTerms8.rgb;
-
-   float3 result = (
-         l00 * SHConsts0 +
-
-         l12 * SHConsts1 * x +
-         l10 * SHConsts1 * y +
-         l11 * SHConsts1 * z +
-
-         l20 * SHConsts2 * x*y +
-         l21 * SHConsts2 * y*z +
-         l22 * SHConsts3 * (3.0*z*z - 1.0) +
-         l23 * SHConsts2 * x*z +
-         l24 * SHConsts4 * (x*x - y*y)
-      );
-
-    return float4(result,1);
-}*/
-
 float3 iblSpecular(float3 v, float3 n, float roughness)
 {
 	float3 R = reflect(v, n); 
@@ -87,61 +32,35 @@ float3 iblSpecular(float3 v, float3 n, float roughness)
 	float3 prefilteredColor = TORQUE_TEXCUBELOD(cubeMap, float4(R, roughness * MAX_REFLECTION_LOD)).rgb;
 	float2 envBRDF  = TORQUE_TEX2D(BRDFTexture, float2(max(dot(n, v), 0.0), roughness)).rg;
 	return prefilteredColor * (envBRDF.x + envBRDF.y);
-   //return prefilteredColor;
- }
-
-struct PS_OUTPUT
-{
-    float4 spec: TORQUE_TARGET0;
-    float4 diffuse: TORQUE_TARGET1;
-};
+}
 
-PS_OUTPUT main( ConvexConnectP IN )
+LightTargetOutput main( ConvexConnectP IN )
 { 
-    PS_OUTPUT Output = (PS_OUTPUT)0;
-
-    // Compute scene UV
-    float3 ssPos = IN.ssPos.xyz / IN.ssPos.w; 
-
-    //float4 hardCodedRTParams0 = float4(0,0.0277777780,1,0.972222209);
-    float2 uvScene = getUVFromSSPos( ssPos, rtParams0 );
-
-    // Matinfo flags
-    float4 matInfo = TORQUE_TEX2D( matInfoBuffer, uvScene ); 
-
-    // Sample/unpack the normal/z data
-    float4 deferredSample = TORQUE_DEFERRED_UNCONDITION( deferredBuffer, uvScene );
-    float3 normal = deferredSample.rgb;
-    float depth = deferredSample.a;
-    if (depth>0.9999)
-        return Output; 
-
-    // Need world-space normal.
-    float3 wsNormal = mul(cameraToWorld, float4(normal, 0)).xyz;
-
-    float3 vsEyeRay = getDistanceVectorToPlane( -vsFarPlane.w, IN.vsEyeDir.xyz, vsFarPlane );
-    float3 vsPos = vsEyeRay * depth;
-
-    float3 wsEyeRay = mul(cameraToWorld, float4(vsEyeRay, 0)).xyz;
-    // calculate world space position
-    float3 wsPos = float3(eyePosWorld + wsEyeRay * depth);
+   LightTargetOutput Output = (LightTargetOutput)0;
 
-    float3 reflectionVec = reflect(IN.wsEyeDir, float4(wsNormal,0)).xyz;
+   // Compute scene UV
+   float3 ssPos = IN.ssPos.xyz / IN.ssPos.w; 
+   float2 uvScene = getUVFromSSPos( ssPos, rtParams0 );
 
-    float roughness = 1 - matInfo.b;
+   //eye ray WS/LS
+   float3 vsEyeRay = getDistanceVectorToPlane( -vsFarPlane.w, IN.vsEyeDir.xyz, vsFarPlane );
+   float3 wsEyeRay = mul(cameraToWorld, float4(vsEyeRay, 0)).xyz;
 
-    float3 v = normalize(eyePosWorld - wsPos);
+   //create surface
+   Surface surface = CreateSurface( TORQUE_SAMPLER2D_MAKEARG(deferredBuffer), TORQUE_SAMPLER2D_MAKEARG(colorBuffer),TORQUE_SAMPLER2D_MAKEARG(matInfoBuffer),
+                                    uvScene, eyePosWorld, wsEyeRay, cameraToWorld);
 
-    float3 irradiance = TORQUE_TEXCUBE(irradianceCubemap, wsNormal).rgb;
+   //sky check
+   if (surface.depth>0.9999)
+      return Output;
 
-    float3 specular = iblSpecular(wsEyeRay, wsNormal, roughness);
+   float3 diffuse = TORQUE_TEXCUBELOD(irradianceCubemap, float4(surface.N,0)).rgb;
+   float3 specular = iblSpecular(wsEyeRay, surface.N, surface.roughness);
 
-	float blendVal = 0.0001;
+	float blendVal = 0.0001;// ?????
 
-    Output.diffuse = float4(irradiance.rgb, blendVal);
-    Output.spec = float4(specular.rgb, blendVal);
-	Output.diffuse.rgb *= matInfo.g;
-	Output.spec.rgb *= matInfo.g;
-    return Output;
+   Output.diffuse = float4(diffuse, blendVal);
+   Output.spec = float4(specular, blendVal);
+   return Output;
 
 }

+ 52 - 137
Templates/Full/game/shaders/common/lighting/advanced/vectorLightP.hlsl

@@ -63,6 +63,7 @@ uniform float2 fadeStartLength;
 uniform float2 atlasScale;
 
 uniform float4x4 eyeMat;
+uniform float4x4 cameraToWorld;
 
 // Static Shadows
 uniform float4x4 worldToLightProj;
@@ -81,21 +82,16 @@ uniform float4 dynamicFarPlaneScalePSSM;
 float4 AL_VectorLightShadowCast( TORQUE_SAMPLER2D(sourceShadowMap),
                                 float2 texCoord,
                                 float4x4 worldToLightProj,
-                                float4 worldPos,
+                                float3 worldPos,
                                 float4 scaleX,
                                 float4 scaleY,
                                 float4 offsetX,
                                 float4 offsetY,
                                 float4 farPlaneScalePSSM,
-                                float4 atlasXOffset,
-                                float4 atlasYOffset,
-                                float2 atlasScale,
-                                float shadowSoftness, 
-                                float dotNL ,
-                                float4 overDarkPSSM)
+                                float dotNL)
 {
       // Compute shadow map coordinate
-      float4 pxlPosLightProj = mul(worldToLightProj, worldPos);
+      float4 pxlPosLightProj = mul(worldToLightProj, float4(worldPos,1));
       float2 baseShadowCoord = pxlPosLightProj.xy / pxlPosLightProj.w;   
 
       // Distance to light, in shadowmap space
@@ -182,144 +178,63 @@ float4 AL_VectorLightShadowCast( TORQUE_SAMPLER2D(sourceShadowMap),
       float farPlaneScale = dot( farPlaneScalePSSM, finalMask );
       distToLight *= farPlaneScale;
 
-      return float4(debugColor,
-                    softShadow_filter(  TORQUE_SAMPLER2D_MAKEARG(sourceShadowMap),
-                                 texCoord,
-                                 shadowCoord,
-                                 farPlaneScale * shadowSoftness,
-                                 distToLight,
-                                 dotNL,
-                                 dot( finalMask, overDarkPSSM ) ) );
+      return float4(debugColor, softShadow_filter(  TORQUE_SAMPLER2D_MAKEARG(sourceShadowMap), texCoord, shadowCoord, farPlaneScale * shadowSoftness,
+                                distToLight, dotNL, dot( finalMask, overDarkPSSM ) ) );
 };
 
-struct PS_OUTPUT
-{
-    float4 spec: TORQUE_TARGET0;
-    float4 diffuse: TORQUE_TARGET1;
-};
 
-PS_OUTPUT main(FarFrustumQuadConnectP IN)
+LightTargetOutput main(FarFrustumQuadConnectP IN)
 {
-   PS_OUTPUT Output = (PS_OUTPUT)0;
-   // Matinfo flags
-   float4 matInfo = TORQUE_TEX2D(matInfoBuffer, IN.uv0);
-   bool emissive = getFlag( matInfo.r, 0 );
-   if (emissive)
-   {
-      return Output;
-   }
-   float4 colorSample = TORQUE_TEX2D(colorBuffer, IN.uv0);
-   float3 subsurface = float3(0.0, 0.0, 0.0);
-   if (getFlag(matInfo.r, 1))
-   {
-      subsurface = colorSample.rgb;
-      if (colorSample.r > colorSample.g)
-         subsurface = float3(0.772549, 0.337255, 0.262745);
-	  else
-         subsurface = float3(0.337255, 0.772549, 0.262745);
-	}
-   // Sample/unpack the normal/z data
-   float4 deferredSample = TORQUE_DEFERRED_UNCONDITION( deferredBuffer, IN.uv0 );
-   float3 normal = deferredSample.rgb;
-   float depth = deferredSample.a;
-
-   // Use eye ray to get ws pos
-   float4 worldPos = float4(eyePosWorld + IN.wsEyeRay * depth, 1.0f);
-   
-   // Get the light attenuation.
-   float dotNL = dot(-lightDirection, normal);
-
-#ifdef PSSM_DEBUG_RENDER
-   float3 debugColor = float3(0, 0, 0);
-#endif
-
-#ifdef NO_SHADOW
-
-   // Fully unshadowed.
-   float shadowed = 1.0;
-
-#ifdef PSSM_DEBUG_RENDER
-   debugColor = float3(1.0, 1.0, 1.0);
-#endif
-
-#else
-
-   float4 static_shadowed_colors = AL_VectorLightShadowCast(TORQUE_SAMPLER2D_MAKEARG(shadowMap),
-      IN.uv0.xy,
-      worldToLightProj,
-      worldPos,
-      scaleX, scaleY,
-      offsetX, offsetY,
-      farPlaneScalePSSM,
-      atlasXOffset, atlasYOffset,
-      atlasScale,
-      shadowSoftness,
-      dotNL,
-      overDarkPSSM);
-   float4 dynamic_shadowed_colors = AL_VectorLightShadowCast(TORQUE_SAMPLER2D_MAKEARG(dynamicShadowMap),
-      IN.uv0.xy,
-      dynamicWorldToLightProj,
-      worldPos,
-      dynamicScaleX, dynamicScaleY,
-      dynamicOffsetX, dynamicOffsetY,
-      dynamicFarPlaneScalePSSM,
-      atlasXOffset, atlasYOffset,
-      atlasScale,
-      shadowSoftness,
-      dotNL,
-      overDarkPSSM);
-
-   float static_shadowed = static_shadowed_colors.a;
-   float dynamic_shadowed = dynamic_shadowed_colors.a;
-
-#ifdef PSSM_DEBUG_RENDER
-   debugColor = static_shadowed_colors.rgb*0.5 + dynamic_shadowed_colors.rgb*0.5;
-#endif
-
-   // Fade out the shadow at the end of the range.
-   float4 zDist = (zNearFarInvNearFar.x + zNearFarInvNearFar.y * depth);
-   float fadeOutAmt = (zDist.x - fadeStartLength.x) * fadeStartLength.y;
-
-   static_shadowed = lerp(static_shadowed, 1.0, saturate(fadeOutAmt));
-   dynamic_shadowed = lerp(dynamic_shadowed, 1.0, saturate(fadeOutAmt));
-
-   // temp for debugging. uncomment one or the other.
-   //float shadowed = static_shadowed;
-   //float shadowed = dynamic_shadowed;
-   float shadowed = min(static_shadowed, dynamic_shadowed)*matInfo.g;
-
-#ifdef PSSM_DEBUG_RENDER
-   if (fadeOutAmt > 1.0)
-      debugColor = 1.0;
-#endif
-
-#endif // !NO_SHADOW
+   LightTargetOutput Output = (LightTargetOutput)0;
+
+   //create surface
+   Surface surface = CreateSurface( TORQUE_SAMPLER2D_MAKEARG(deferredBuffer), TORQUE_SAMPLER2D_MAKEARG(colorBuffer),TORQUE_SAMPLER2D_MAKEARG(matInfoBuffer),
+                                    IN.uv0, eyePosWorld, IN.wsEyeRay, cameraToWorld);
+   //create surface to light    
+   float3 wsLightDir = mul(cameraToWorld, float4(lightDirection,0)).xyz;                             
+   SurfaceToLight surfaceToLight = CreateSurfaceToLight(surface, -wsLightDir);
+
+   //light color might be changed by PSSM_DEBUG_RENDER
+   float3 lightingColor = lightColor.rgb;
+
+   #ifdef NO_SHADOW
+      float shadow = 1.0;
+   #else
+
+      // Fade out the shadow at the end of the range.
+      float4 zDist = (zNearFarInvNearFar.x + zNearFarInvNearFar.y * surface.depth);
+      float fadeOutAmt = ( zDist.x - fadeStartLength.x ) * fadeStartLength.y;
+
+      //there must be a better way of doing this, two shadowcast lookups = very yucky!
+      float4 static_shadowed_colors = AL_VectorLightShadowCast( TORQUE_SAMPLER2D_MAKEARG(shadowMap), IN.uv0.xy, worldToLightProj, surface.P, scaleX, scaleY, offsetX, offsetY,
+                                                             farPlaneScalePSSM, surfaceToLight.NdotL);
+
+      float4 dynamic_shadowed_colors = AL_VectorLightShadowCast( TORQUE_SAMPLER2D_MAKEARG(dynamicShadowMap), IN.uv0.xy, dynamicWorldToLightProj, surface.P, dynamicScaleX,
+                                                              dynamicScaleY, dynamicOffsetX, dynamicOffsetY, dynamicFarPlaneScalePSSM, surfaceToLight.NdotL);
+      float static_shadowed = static_shadowed_colors.a;
+      float dynamic_shadowed = dynamic_shadowed_colors.a;
+	  
+      #ifdef PSSM_DEBUG_RENDER
+	     lightingColor = static_shadowed_colors.rgb*0.5+dynamic_shadowed_colors.rgb*0.5;
+      #endif
 
-   float3 l = normalize(-lightDirection);
-   float3 v = normalize(eyePosWorld - worldPos.xyz);
+      static_shadowed = lerp( static_shadowed, 1.0, saturate( fadeOutAmt ) );
+      dynamic_shadowed = lerp( dynamic_shadowed, 1.0, saturate( fadeOutAmt ) );
 
-   float3 h = normalize(v + l);
-   float dotNLa = clamp(dot(normal, l), 0.0, 1.0);
-   float dotNVa = clamp(dot(normal, v), 0.0, 1.0);
-   float dotNHa = clamp(dot(normal, h), 0.0, 1.0);
-   float dotHVa = clamp(dot(normal, v), 0.0, 1.0);
-   float dotLHa = clamp(dot(l, h), 0.0, 1.0);
+      float shadow = min(static_shadowed, dynamic_shadowed);
 
-   float roughness = 1.0001-matInfo.b;
-   float metalness = matInfo.a;
+      #ifdef PSSM_DEBUG_RENDER
+         if ( fadeOutAmt > 1.0 )
+            lightingColor = 1.0;
+      #endif
 
-   //diffuse
-   //float dotNL = clamp(dot(normal,l), 0.0, 1.0);
-   float disDiff = Fr_DisneyDiffuse(dotNVa, dotNLa, dotLHa, roughness);
-   float3 diffuse = float3(disDiff, disDiff, disDiff) / M_PI_F;// alternative: (lightColor * dotNL) / Pi;
-   //specular
-   float3 specular = directSpecular(normal, v, l, roughness, 1.0) * lightColor.rgb;
-   
-   float finalShadowed = shadowed;
+   #endif //NO_SHADOW
 
-//output
-   Output.diffuse = float4(diffuse * (lightBrightness)*dotNLa*shadowed, 1.0);
-   Output.spec = float4(specular * (lightBrightness)*dotNLa*shadowed, 1.0);
+   //get directional light contribution   
+   LightResult result = GetDirectionalLight(surface, surfaceToLight, lightingColor.rgb, lightBrightness, shadow);
+   //output
+   Output.diffuse = float4(result.diffuse, 0);
+   Output.spec = float4(result.spec, 0);
 
    return Output;
 }

+ 37 - 40
Templates/Full/game/shaders/common/shaderModel.hlsl

@@ -24,48 +24,45 @@
 #define _TORQUE_SHADERMODEL_
 
 // Portability helpers for different shader models
-// Shader model 4.0+
-#if TORQUE_SM >= 40
-   #define TORQUE_POSITION SV_Position
-   #define TORQUE_DEPTH SV_Depth
-   #define TORQUE_VPOS SV_Position //note float4 compared to SM 3 where it is a float2
-   #define TORQUE_TARGET0 SV_Target0
-   #define TORQUE_TARGET1 SV_Target1
-   #define TORQUE_TARGET2 SV_Target2
-   #define TORQUE_TARGET3 SV_Target3
-   #define TORQUE_TARGET4 SV_Target4
-   #define TORQUE_TARGET5 SV_Target5
-   // Sampler uniforms
-   //1D is emulated to a 2D for now
-   #define TORQUE_UNIFORM_SAMPLER1D(tex,regist) uniform Texture2D texture_##tex : register(T##regist); uniform SamplerState tex : register(S##regist)
-   #define TORQUE_UNIFORM_SAMPLER2D(tex,regist) uniform Texture2D texture_##tex : register(T##regist); uniform SamplerState tex : register(S##regist)
-   #define TORQUE_UNIFORM_SAMPLER2DCMP(tex,regist) uniform Texture2D texture_##tex : register(T##regist); uniform SamplerComparisonState tex : register(S##regist)
-   #define TORQUE_UNIFORM_SAMPLER3D(tex,regist) uniform Texture3D texture_##tex : register(T##regist); uniform SamplerState tex : register(S##regist)
-   #define TORQUE_UNIFORM_SAMPLERCUBE(tex,regist) uniform TextureCube texture_##tex : register(T##regist); uniform SamplerState tex : register(S##regist)
-   // Sampling functions
-   #define TORQUE_TEX1D(tex,coords) texture_##tex.Sample(tex,coords)
-   #define TORQUE_TEX2D(tex,coords) texture_##tex.Sample(tex,coords)
-   #define TORQUE_TEX2DPROJ(tex,coords) texture_##tex.Sample(tex,coords.xy / coords.w)
-   #define TORQUE_TEX3D(tex,coords) texture_##tex.Sample(tex,coords)
-   #define TORQUE_TEXCUBE(tex,coords) texture_##tex.Sample(tex,coords)
-   // The mipmap LOD is specified in coord.w
-   #define TORQUE_TEX2DLOD(tex,coords) texture_##tex.SampleLevel(tex,coords.xy,coords.w)
-   #define TORQUE_TEXCUBELOD(tex,coords) texture_##tex.SampleLevel(tex,coords.xyz,coords.w)
-   // Tex2d comparison
-   #define TORQUE_TEX2DCMP(tex,coords,compare) texture_##tex.SampleCmpLevelZero(tex,coords,compare)
+#define TORQUE_POSITION SV_Position
+#define TORQUE_DEPTH SV_Depth
+#define TORQUE_VPOS SV_Position //note float4 compared to SM 3 where it is a float2
+#define TORQUE_TARGET0 SV_Target0
+#define TORQUE_TARGET1 SV_Target1
+#define TORQUE_TARGET2 SV_Target2
+#define TORQUE_TARGET3 SV_Target3
+#define TORQUE_TARGET4 SV_Target4
+#define TORQUE_TARGET5 SV_Target5
+// Sampler uniforms
+//1D is emulated to a 2D for now
+#define TORQUE_UNIFORM_SAMPLER1D(tex,regist) uniform Texture2D texture_##tex : register(T##regist); uniform SamplerState tex : register(S##regist)
+#define TORQUE_UNIFORM_SAMPLER2D(tex,regist) uniform Texture2D texture_##tex : register(T##regist); uniform SamplerState tex : register(S##regist)
+#define TORQUE_UNIFORM_SAMPLER2DCMP(tex,regist) uniform Texture2D texture_##tex : register(T##regist); uniform SamplerComparisonState tex : register(S##regist)
+#define TORQUE_UNIFORM_SAMPLER3D(tex,regist) uniform Texture3D texture_##tex : register(T##regist); uniform SamplerState tex : register(S##regist)
+#define TORQUE_UNIFORM_SAMPLERCUBE(tex,regist) uniform TextureCube texture_##tex : register(T##regist); uniform SamplerState tex : register(S##regist)
+// Sampling functions
+#define TORQUE_TEX1D(tex,coords) texture_##tex.Sample(tex,coords)
+#define TORQUE_TEX2D(tex,coords) texture_##tex.Sample(tex,coords)
+#define TORQUE_TEX2DPROJ(tex,coords) texture_##tex.Sample(tex,coords.xy / coords.w)
+#define TORQUE_TEX3D(tex,coords) texture_##tex.Sample(tex,coords)
+#define TORQUE_TEXCUBE(tex,coords) texture_##tex.Sample(tex,coords)
+// The mipmap LOD is specified in coord.w
+#define TORQUE_TEX2DLOD(tex,coords) texture_##tex.SampleLevel(tex,coords.xy,coords.w)
+#define TORQUE_TEXCUBELOD(tex,coords) texture_##tex.SampleLevel(tex,coords.xyz,coords.w)
+// Tex2d comparison
+#define TORQUE_TEX2DCMP(tex,coords,compare) texture_##tex.SampleCmpLevelZero(tex,coords,compare)
 
-   #define TORQUE_TEX2DGATHER(tex,coords,compare,offset) texture_##tex.GatherCmp(tex,coords,compare,offset)
+#define TORQUE_TEX2DGATHER(tex,coords,compare,offset) texture_##tex.GatherCmp(tex,coords,compare,offset)
 
-   //helper if you want to pass sampler/texture in a function
-   //2D
-   #define TORQUE_SAMPLER2D(tex) Texture2D texture_##tex, SamplerState tex
-   #define TORQUE_SAMPLER2D_MAKEARG(tex) texture_##tex, tex
-   // Sampler comparison state - use above MAKEARG with this
-   #define TORQUE_SAMPLER2DCMP(tex) Texture2D texture_##tex, SamplerComparisonState tex
-   //Cube
-   #define TORQUE_SAMPLERCUBE(tex) TextureCube texture_##tex, SamplerState tex
-   #define TORQUE_SAMPLERCUBE_MAKEARG(tex) texture_##tex, tex
-#endif
+//helper if you want to pass sampler/texture in a function
+//2D
+#define TORQUE_SAMPLER2D(tex) Texture2D texture_##tex, SamplerState tex
+#define TORQUE_SAMPLER2D_MAKEARG(tex) texture_##tex, tex
+// Sampler comparison state - use above MAKEARG with this
+#define TORQUE_SAMPLER2DCMP(tex) Texture2D texture_##tex, SamplerComparisonState tex
+//Cube
+#define TORQUE_SAMPLERCUBE(tex) TextureCube texture_##tex, SamplerState tex
+#define TORQUE_SAMPLERCUBE_MAKEARG(tex) texture_##tex, tex
 
 #endif // _TORQUE_SHADERMODEL_
 

+ 18 - 3
Templates/Full/game/shaders/common/shaderModelAutoGen.hlsl

@@ -24,11 +24,26 @@
 #define _TORQUE_SHADERMODEL_AUTOGEN_
 
 #include "shadergen:/autogenConditioners.h"
+#include "./shaderModel.hlsl"
 
 // Portability helpers for autogenConditioners
 
-#if TORQUE_SM >= 40
-   #define TORQUE_DEFERRED_UNCONDITION(tex, coords) deferredUncondition(tex, texture_##tex, coords)
-#endif
+//todo deprecate this function
+#define TORQUE_DEFERRED_UNCONDITION(tex, coords) deferredUncondition(tex, texture_##tex, coords)
+
+inline float4 UnpackDepthNormal(TORQUE_SAMPLER2D(tex), float2 screenUVVar)
+{
+   // Sampler g-buffer
+   float4 bufferSample = TORQUE_TEX2DLOD(tex,float4(screenUVVar,0,0));
+   // g-buffer unconditioner: float4(normal.X, normal.Y, depth Hi, depth Lo)
+   float2 _inpXY = bufferSample.xy;
+   float _xySQ = dot(_inpXY, _inpXY);
+   float4 _gbUnconditionedInput = float4( sqrt(half(1.0 - (_xySQ / 4.0))) * _inpXY, -1.0 + (_xySQ / 2.0), bufferSample.a).xzyw;
+   
+   // Decode depth
+   _gbUnconditionedInput.w = dot( bufferSample.zw, float2(1.0, 1.0/65535.0));
+
+   return _gbUnconditionedInput;
+}
 
 #endif //_TORQUE_SHADERMODEL_AUTOGEN_

+ 4 - 0
Templates/Full/game/shaders/common/torque.hlsl

@@ -344,4 +344,8 @@ float3 getCubeDir(int face, float2 uv)
 
 	return normalize(dir);
 }
+
+#define sqr(a)		((a)*(a))
+#define float4_splat(a) float4(a,a,a,a)
+#define float3_splat(a) float3(a,a,a)
 #endif // _TORQUE_HLSL_

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików