Browse Source

Squashed commit of the following:

commit a384431cd1ce230630d6a4522022de919cb55ac9
Author: dragonCASTjosh <[email protected]>
Date:   Thu Nov 10 00:16:26 2016 +0000

    Fixed typing and style errors

commit d4f8ca2eeed2b0196b46bd391e96a511594dc738
Author: dragonCASTjosh <[email protected]>
Date:   Thu Nov 10 00:14:02 2016 +0000

    Removed isAreaLight from attibutes

commit 62d50f3ba94d9c665358dcd7377730d968fde7be
Author: dragonCASTjosh <[email protected]>
Date:   Mon Nov 7 22:53:45 2016 +0000

    Added documentation on area lighting options

commit 53e5844bee5caccc2a37f0dcdac3b8d4a984dd62
Author: dragonCASTjosh <[email protected]>
Date:   Sat Nov 5 17:15:14 2016 +0000

    Fixd spacing

commit 5afa4ec59c1ecd2aa4892d4854e3b954af9cc73f
Author: dragonCASTjosh <[email protected]>
Date:   Sat Nov 5 06:00:19 2016 +0000

    Fixed materials under deferred and light position in the scene

commit 314bc5847a44979b89f46a0272fcf5cd0f04e866
Author: dragonCASTjosh <[email protected]>
Date:   Sat Nov 5 05:14:27 2016 +0000

    Fixed Deferred rendering

commit bde3560de71ab5a33c9cc3a4ee40029567cca5bf
Author: dragonCASTjosh <[email protected]>
Date:   Sat Nov 5 03:26:54 2016 +0000

    Area lighting, improved IBL and improved attenuation for OpenGL

commit 52be0fc67626a9c8901091445be52bdbe99657d1
Author: dragonCASTjosh <[email protected]>
Date:   Sat Nov 5 01:23:53 2016 +0000

    Intergrated Area ligthing with the editor, and improved texture quality

commit 5044bebe3d8799dee687ca676334f4493586d376
Author: dragonCASTjosh <[email protected]>
Date:   Mon Oct 24 09:25:15 2016 +0100

    Tube lighting HLSL

commit f3849a93d1812345b21918a7418d12c8d3e1e3dd
Author: dragonCASTjosh <[email protected]>
Date:   Mon Oct 24 09:01:10 2016 +0100

    Improve IBL

commit 210bfaebb40ed977eb46f0f6f91b3b6a49ec25a7
Author: joshua Nuttall <[email protected]>
Date:   Thu Sep 15 12:32:15 2016 +0100

    Made sphere lights closer to epics paper

commit c186870e9e79de9572b5302019598ac059af58cf
Author: joshua Nuttall <[email protected]>
Date:   Thu Sep 15 11:57:39 2016 +0100

    Added sphere light and beginning of tube lights
Lasse Öörni 9 years ago
parent
commit
b8d55583f7
44 changed files with 713 additions and 279 deletions
  1. 6 0
      Source/Urho3D/AngelScript/GraphicsAPI.cpp
  2. 6 0
      Source/Urho3D/Graphics/Batch.cpp
  3. 4 0
      Source/Urho3D/Graphics/GraphicsDefs.cpp
  4. 4 0
      Source/Urho3D/Graphics/GraphicsDefs.h
  5. 28 2
      Source/Urho3D/Graphics/Light.cpp
  6. 21 0
      Source/Urho3D/Graphics/Light.h
  7. 9 0
      Source/Urho3D/LuaScript/pkgs/Graphics/Light.pkg
  8. 2 0
      bin/Autoload/LargeData/Materials/PBR/Check.xml
  9. 2 0
      bin/Autoload/LargeData/Materials/PBR/DiamonPlate.xml
  10. 2 0
      bin/Autoload/LargeData/Materials/PBR/Dynamic.xml
  11. 19 0
      bin/Autoload/LargeData/Materials/PBR/Emissive.xml
  12. 2 0
      bin/Autoload/LargeData/Materials/PBR/EmissivePannel.xml
  13. 2 0
      bin/Autoload/LargeData/Materials/PBR/HoverBikeGlass.xml
  14. 2 0
      bin/Autoload/LargeData/Materials/PBR/HoverBikeHull.xml
  15. 2 0
      bin/Autoload/LargeData/Materials/PBR/Lead.xml
  16. 3 1
      bin/Autoload/LargeData/Materials/PBR/Leather.xml
  17. 2 0
      bin/Autoload/LargeData/Materials/PBR/Metallic0.xml
  18. 2 0
      bin/Autoload/LargeData/Materials/PBR/Metallic10.xml
  19. 2 0
      bin/Autoload/LargeData/Materials/PBR/Metallic3.xml
  20. 2 0
      bin/Autoload/LargeData/Materials/PBR/Metallic5.xml
  21. 2 0
      bin/Autoload/LargeData/Materials/PBR/Metallic7.xml
  22. 2 0
      bin/Autoload/LargeData/Materials/PBR/MetallicRough10.xml
  23. 2 0
      bin/Autoload/LargeData/Materials/PBR/MetallicRough7.xml
  24. 3 1
      bin/Autoload/LargeData/Materials/PBR/Mud.xml
  25. 3 1
      bin/Autoload/LargeData/Materials/PBR/Roughness0.xml
  26. 3 1
      bin/Autoload/LargeData/Materials/PBR/Roughness10.xml
  27. 3 1
      bin/Autoload/LargeData/Materials/PBR/Roughness3.xml
  28. 3 1
      bin/Autoload/LargeData/Materials/PBR/Roughness5.xml
  29. 3 1
      bin/Autoload/LargeData/Materials/PBR/Roughness7.xml
  30. 2 0
      bin/Autoload/LargeData/Materials/PBR/Sand.xml
  31. 2 0
      bin/Autoload/LargeData/Materials/PBR/Tile.xml
  32. 20 8
      bin/CoreData/Shaders/GLSL/IBL.glsl
  33. 23 10
      bin/CoreData/Shaders/GLSL/Lighting.glsl
  34. 96 5
      bin/CoreData/Shaders/GLSL/PBR.glsl
  35. 12 4
      bin/CoreData/Shaders/GLSL/PBRDeferred.glsl
  36. 11 2
      bin/CoreData/Shaders/GLSL/PBRLitSolid.glsl
  37. 14 4
      bin/CoreData/Shaders/GLSL/Uniforms.glsl
  38. 37 14
      bin/CoreData/Shaders/HLSL/IBL.hlsl
  39. 24 10
      bin/CoreData/Shaders/HLSL/Lighting.hlsl
  40. 101 8
      bin/CoreData/Shaders/HLSL/PBR.hlsl
  41. 10 2
      bin/CoreData/Shaders/HLSL/PBRDeferred.hlsl
  42. 10 3
      bin/CoreData/Shaders/HLSL/PBRLitSolid.hlsl
  43. 10 0
      bin/CoreData/Shaders/HLSL/Uniforms.hlsl
  44. 195 200
      bin/Data/Scenes/PBRExample.xml

+ 6 - 0
Source/Urho3D/AngelScript/GraphicsAPI.cpp

@@ -1214,8 +1214,14 @@ static void RegisterLight(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Light", "const Color& get_color() const", asMETHOD(Light, GetColor), asCALL_THISCALL);
     engine->RegisterObjectMethod("Light", "void set_temperature(float)", asMETHOD(Light, SetTemperature), asCALL_THISCALL);
     engine->RegisterObjectMethod("Light", "float get_temperature() const", asMETHOD(Light, GetTemperature), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Light", "void set_radius(float)", asMETHOD(Light, SetRadius), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Light", "float get_radius() const", asMETHOD(Light, GetRadius), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Light", "void set_length(float)", asMETHOD(Light, SetLength), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Light", "float get_length() const", asMETHOD(Light, GetLength), asCALL_THISCALL);
     engine->RegisterObjectMethod("Light", "void set_usePhysicalValues(bool)", asMETHOD(Light, SetUsePhysicalValues), asCALL_THISCALL);
     engine->RegisterObjectMethod("Light", "bool get_usePhysicalValues() const", asMETHOD(Light, GetUsePhysicalValues), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Light", "void set_isAreaLight(bool)", asMETHOD(Light, SetIsAreaLight), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Light", "bool get_isAreaLight() const", asMETHOD(Light, GetIsAreaLight), asCALL_THISCALL);
     engine->RegisterObjectMethod("Light", "void set_specularIntensity(float)", asMETHOD(Light, SetSpecularIntensity), asCALL_THISCALL);
     engine->RegisterObjectMethod("Light", "float get_specularIntensity() const", asMETHOD(Light, GetSpecularIntensity), asCALL_THISCALL);
     engine->RegisterObjectMethod("Light", "void set_brightness(float)", asMETHOD(Light, SetBrightness), asCALL_THISCALL);

+ 6 - 0
Source/Urho3D/Graphics/Batch.cpp

@@ -283,6 +283,8 @@ void Batch::Prepare(View* view, Camera* camera, bool setModelTransform, bool all
 
         graphics->SetShaderParameter(PSP_AMBIENTCOLOR, zone_->GetAmbientColor());
         graphics->SetShaderParameter(PSP_FOGCOLOR, overrideFogColorToBlack ? Color::BLACK : zone_->GetFogColor());
+        graphics->SetShaderParameter(PSP_ZONEMIN, zone_->GetBoundingBox().min_);
+        graphics->SetShaderParameter(PSP_ZONEMAX, zone_->GetBoundingBox().max_);
 
         float farClip = camera->GetFarClip();
         float fogStart = Min(zone_->GetFogStart(), farClip);
@@ -354,6 +356,7 @@ void Batch::Prepare(View* view, Camera* camera, bool setModelTransform, bool all
                         graphics->SetShaderParameter(VSP_LIGHTMATRICES, lightVecRot.Data(), 16);
 #else
                         graphics->SetShaderParameter(VSP_LIGHTMATRICES, lightVecRot.Data(), 12);
+
 #endif
                     }
                     break;
@@ -373,6 +376,9 @@ void Batch::Prepare(View* view, Camera* camera, bool setModelTransform, bool all
                 light->GetEffectiveSpecularIntensity()) * fade);
             graphics->SetShaderParameter(PSP_LIGHTDIR, lightDir);
             graphics->SetShaderParameter(PSP_LIGHTPOS, lightPos);
+            //graphics->define
+            graphics->SetShaderParameter(PSP_LIGHTRAD, light->GetRadius());
+            graphics->SetShaderParameter(PSP_LIGHTLENGTH, light->GetLength());
 
             if (graphics->HasShaderParameter(PSP_LIGHTMATRICES))
             {

+ 4 - 0
Source/Urho3D/Graphics/GraphicsDefs.cpp

@@ -85,6 +85,10 @@ extern URHO3D_API const StringHash PSP_LIGHTMATRICES("LightMatricesPS");
 extern URHO3D_API const StringHash PSP_VSMSHADOWPARAMS("VSMShadowParams");
 extern URHO3D_API const StringHash PSP_ROUGHNESS("Roughness");
 extern URHO3D_API const StringHash PSP_METALLIC("Metallic");
+extern URHO3D_API const StringHash PSP_LIGHTRAD("LightRad");
+extern URHO3D_API const StringHash PSP_LIGHTLENGTH("LightLength");
+extern URHO3D_API const StringHash PSP_ZONEMIN("ZoneMin");
+extern URHO3D_API const StringHash PSP_ZONEMAX("ZoneMax");
 
 extern URHO3D_API const Vector3 DOT_SCALE(1 / 3.0f, 1 / 3.0f, 1 / 3.0f);
 

+ 4 - 0
Source/Urho3D/Graphics/GraphicsDefs.h

@@ -420,6 +420,10 @@ extern URHO3D_API const StringHash PSP_LIGHTMATRICES;
 extern URHO3D_API const StringHash PSP_VSMSHADOWPARAMS;
 extern URHO3D_API const StringHash PSP_ROUGHNESS;
 extern URHO3D_API const StringHash PSP_METALLIC;
+extern URHO3D_API const StringHash PSP_LIGHTRAD;
+extern URHO3D_API const StringHash PSP_LIGHTLENGTH;
+extern URHO3D_API const StringHash PSP_ZONEMIN;
+extern URHO3D_API const StringHash PSP_ZONEMAX;
 
 // Scale calculation from bounding box diagonal.
 extern URHO3D_API const Vector3 DOT_SCALE;

+ 28 - 2
Source/Urho3D/Graphics/Light.cpp

@@ -58,6 +58,8 @@ static const float DEFAULT_SHADOWNEARFARRATIO = 0.002f;
 static const float DEFAULT_SHADOWMAXEXTRUSION = 1000.0f;
 static const float DEFAULT_SHADOWSPLIT = 1000.0f;
 static const float DEFAULT_TEMPERATURE = 6590.0f;
+static const float DEFAULT_RADIUS = 0.0f;
+static const float DEFAULT_LENGTH = 0.0f;
 
 static const char* typeNames[] =
 {
@@ -94,7 +96,9 @@ Light::Light(Context* context) :
     shadowCascade_(CascadeParameters(DEFAULT_SHADOWSPLIT, 0.0f, 0.0f, 0.0f, DEFAULT_SHADOWFADESTART)),
     shadowFocus_(FocusParameters(true, true, true, DEFAULT_SHADOWQUANTIZE, DEFAULT_SHADOWMINVIEW)),
     lightQueue_(0),
-    temperature_(6590.0f),
+    temperature_(DEFAULT_TEMPERATURE),
+    lightRad_(DEFAULT_RADIUS),
+    lightLength_(DEFAULT_LENGTH),
     specularIntensity_(DEFAULT_SPECULARINTENSITY),
     brightness_(DEFAULT_BRIGHTNESS),
     range_(DEFAULT_RANGE),
@@ -107,7 +111,8 @@ Light::Light(Context* context) :
     shadowNearFarRatio_(DEFAULT_SHADOWNEARFARRATIO),
     shadowMaxExtrusion_(DEFAULT_SHADOWMAXEXTRUSION),
     perVertex_(false),
-    usePhysicalValues_(false)
+    usePhysicalValues_(false),
+    isAreaLight_(false)
 {
 }
 
@@ -127,6 +132,9 @@ void Light::RegisterObject(Context* context)
     URHO3D_ACCESSOR_ATTRIBUTE("Brightness Multiplier", GetBrightness, SetBrightness, float, DEFAULT_BRIGHTNESS, AM_DEFAULT);
     URHO3D_ACCESSOR_ATTRIBUTE("Temperature", GetTemperature, SetTemperature, float, DEFAULT_TEMPERATURE, AM_DEFAULT);
     URHO3D_ATTRIBUTE("Use Physical Values", bool, usePhysicalValues_, false, AM_DEFAULT);
+    //URHO3D_ATTRIBUTE("Is Area Light", bool, isAreaLight_, false, AM_DEFAULT);
+    URHO3D_ACCESSOR_ATTRIBUTE("Radius", GetRadius, SetRadius, float, DEFAULT_RADIUS, AM_DEFAULT);
+    URHO3D_ACCESSOR_ATTRIBUTE("Length", GetLength, SetLength, float, DEFAULT_LENGTH, AM_DEFAULT);
     URHO3D_ACCESSOR_ATTRIBUTE("Range", GetRange, SetRange, float, DEFAULT_RANGE, AM_DEFAULT);
     URHO3D_ACCESSOR_ATTRIBUTE("Spot FOV", GetFov, SetFov, float, DEFAULT_LIGHT_FOV, AM_DEFAULT);
     URHO3D_ACCESSOR_ATTRIBUTE("Spot Aspect Ratio", GetAspectRatio, SetAspectRatio, float, 1.0f, AM_DEFAULT);
@@ -304,12 +312,30 @@ void Light::SetTemperature(float temperature)
     MarkNetworkUpdate();
 }
 
+void Light::SetRadius(float radius)
+{
+    lightRad_ = radius;
+    MarkNetworkUpdate();
+}
+
+void Light::SetLength(float length)
+{
+    lightLength_ = length;
+    MarkNetworkUpdate();
+}
+
 void Light::SetUsePhysicalValues(bool enable)
 {
     usePhysicalValues_ = enable;
     MarkNetworkUpdate();
 }
 
+void Light::SetIsAreaLight(bool enable)
+{
+    isAreaLight_ = enable;
+    MarkNetworkUpdate();
+}
+
 void Light::SetSpecularIntensity(float intensity)
 {
     specularIntensity_ = Max(intensity, 0.0f);

+ 21 - 0
Source/Urho3D/Graphics/Light.h

@@ -180,8 +180,14 @@ public:
     void SetColor(const Color& color);
     /// Set temperature of the light in Kelvin. Modulates the light color when "use physical values" is enabled.
     void SetTemperature(float temperature);
+    /// Set radius of the light
+    void SetRadius(float radius);
+    /// Set length of the light
+    void SetLength(float length);
     /// Set use physical light values.
     void SetUsePhysicalValues(bool enable);
+    /// Set light to be an area light
+    void SetIsAreaLight(bool enable);
     /// Set specular intensity. Zero disables specular calculations.
     void SetSpecularIntensity(float intensity);
     /// Set light brightness multiplier. Both the color and specular intensity are multiplied with this. When "use physical values" is enabled, the value is specified in lumens.
@@ -227,9 +233,18 @@ public:
     /// Return the temperature of the light in Kelvin.
     float GetTemperature() const { return temperature_; }
 
+    /// Return the radius of the light
+    float GetRadius() const { return lightRad_; }
+
+    /// Return the length of the light
+    float GetLength() const { return lightLength_; }
+
     /// Return if light uses temperature and brightness in lumens.
     bool GetUsePhysicalValues() const { return usePhysicalValues_; }
 
+    /// Return if we are using area lighting
+    bool GetIsAreaLight() const { return isAreaLight_; }
+
     /// Return the color value of the temperature in Kelvin.
     Color GetColorFromTemperature() const;
 
@@ -339,6 +354,10 @@ private:
     Color color_;
     /// Light temperature.
     float temperature_;
+    /// Radius of the light source. If above 0 it will turn the light into an area light.
+    float lightRad_;
+    /// Length of the light source. If above 0 and radius is above 0 it will create a tube light.
+    float lightLength_;
     /// Shadow depth bias parameters.
     BiasParameters shadowBias_;
     /// Directional light cascaded shadow parameters.
@@ -379,6 +398,8 @@ private:
     bool perVertex_;
     /// Use physical light values flag.
     bool usePhysicalValues_;
+    /// Use Area lighting flag. Currently not used.
+    bool isAreaLight_;
 };
 
 inline bool CompareLights(Light* lhs, Light* rhs)

+ 9 - 0
Source/Urho3D/LuaScript/pkgs/Graphics/Light.pkg

@@ -47,7 +47,10 @@ class Light : public Drawable
     void SetPerVertex(bool enable);
     void SetColor(const Color& color);
     void SetTemperature(float temperature);
+    void SetRadius(float redius);
+    void SetLength(float length);
     void SetUsePhysicalValues(bool enable);
+    void SetIsAreaLight(bool enable);
     void SetSpecularIntensity(float intensity);
     void SetBrightness(float brightness);
     void SetRange(float range);
@@ -69,11 +72,14 @@ class Light : public Drawable
     bool GetPerVertex() const;
     const Color& GetColor() const;
     float GetTemperature() const;
+    float GetRadius() const;
+    float GetLength() const;
     float GetSpecularIntensity() const;
     float GetBrightness() const;
     Color GetEffectiveColor() const;
     Color GetColorFromTemperature() const;
     bool GetUsePhysicalValues() const;
+    bool GetIsAreaLight() const;
     float GetEffectiveSpecularIntensity() const;
     float GetRange() const;
     float GetFov() const;
@@ -97,7 +103,10 @@ class Light : public Drawable
     tolua_property__get_set bool perVertex;
     tolua_property__get_set Color& color;
     tolua_property__get_set float temperature;
+    tolua_property__get_set float radius;
+    tolua_property__get_set float length;
     tolua_property__get_set bool usePhysicalValues;
+    tolua_property__get_set bool isAreaLight;
     tolua_property__get_set float specularIntensity;
     tolua_property__get_set float brightness;
     tolua_property__get_set float range;

+ 2 - 0
bin/Autoload/LargeData/Materials/PBR/Check.xml

@@ -16,5 +16,7 @@
 	<shadowcull value="ccw" />
 	<fill value="solid" />
 	<depthbias constant="0" slopescaled="0" />
+	<alphatocoverage enable="false" />
 	<renderorder value="128" />
+	<occlusion enable="true" />
 </material>

+ 2 - 0
bin/Autoload/LargeData/Materials/PBR/DiamonPlate.xml

@@ -16,5 +16,7 @@
 	<shadowcull value="ccw" />
 	<fill value="solid" />
 	<depthbias constant="0" slopescaled="0" />
+	<alphatocoverage enable="false" />
 	<renderorder value="128" />
+	<occlusion enable="true" />
 </material>

+ 2 - 0
bin/Autoload/LargeData/Materials/PBR/Dynamic.xml

@@ -13,5 +13,7 @@
 	<shadowcull value="ccw" />
 	<fill value="solid" />
 	<depthbias constant="0" slopescaled="0" />
+	<alphatocoverage enable="false" />
 	<renderorder value="128" />
+	<occlusion enable="true" />
 </material>

+ 19 - 0
bin/Autoload/LargeData/Materials/PBR/Emissive.xml

@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<material>
+	<technique name="Techniques/PBR/PBRNoTexture.xml" quality="0" loddistance="0" />
+	<parameter name="UOffset" value="1 0 0 0" />
+	<parameter name="VOffset" value="0 1 0 0" />
+	<parameter name="MatDiffColor" value="1 1 1 1" />
+	<parameter name="MatEmissiveColor" value="1 1 1" />
+	<parameter name="MatEnvMapColor" value="1 1 1" />
+	<parameter name="MatSpecColor" value="1 1 1 1" />
+	<parameter name="Roughness" value="1" />
+	<parameter name="Metallic" value="0" />
+	<cull value="ccw" />
+	<shadowcull value="ccw" />
+	<fill value="solid" />
+	<depthbias constant="0" slopescaled="0" />
+	<alphatocoverage enable="false" />
+	<renderorder value="128" />
+	<occlusion enable="true" />
+</material>

+ 2 - 0
bin/Autoload/LargeData/Materials/PBR/EmissivePannel.xml

@@ -17,5 +17,7 @@
 	<shadowcull value="ccw" />
 	<fill value="solid" />
 	<depthbias constant="0" slopescaled="0" />
+	<alphatocoverage enable="false" />
 	<renderorder value="128" />
+	<occlusion enable="true" />
 </material>

+ 2 - 0
bin/Autoload/LargeData/Materials/PBR/HoverBikeGlass.xml

@@ -16,5 +16,7 @@
 	<shadowcull value="ccw" />
 	<fill value="solid" />
 	<depthbias constant="0" slopescaled="0" />
+	<alphatocoverage enable="false" />
 	<renderorder value="128" />
+	<occlusion enable="true" />
 </material>

+ 2 - 0
bin/Autoload/LargeData/Materials/PBR/HoverBikeHull.xml

@@ -16,5 +16,7 @@
 	<shadowcull value="ccw" />
 	<fill value="solid" />
 	<depthbias constant="0" slopescaled="0" />
+	<alphatocoverage enable="false" />
 	<renderorder value="128" />
+	<occlusion enable="true" />
 </material>

+ 2 - 0
bin/Autoload/LargeData/Materials/PBR/Lead.xml

@@ -16,5 +16,7 @@
 	<shadowcull value="ccw" />
 	<fill value="solid" />
 	<depthbias constant="0" slopescaled="0" />
+	<alphatocoverage enable="false" />
 	<renderorder value="128" />
+	<occlusion enable="true" />
 </material>

+ 3 - 1
bin/Autoload/LargeData/Materials/PBR/Leather.xml

@@ -10,11 +10,13 @@
 	<parameter name="MatEmissiveColor" value="0 0 0" />
 	<parameter name="MatEnvMapColor" value="1 1 1" />
 	<parameter name="MatSpecColor" value="1 1 1 1" />
-	<parameter name="Roughness" value="0" />
+	<parameter name="Roughness" value="-0.1" />
 	<parameter name="Metallic" value="0" />
 	<cull value="ccw" />
 	<shadowcull value="ccw" />
 	<fill value="solid" />
 	<depthbias constant="0" slopescaled="0" />
+	<alphatocoverage enable="false" />
 	<renderorder value="128" />
+	<occlusion enable="true" />
 </material>

+ 2 - 0
bin/Autoload/LargeData/Materials/PBR/Metallic0.xml

@@ -13,5 +13,7 @@
 	<shadowcull value="ccw" />
 	<fill value="solid" />
 	<depthbias constant="0" slopescaled="0" />
+	<alphatocoverage enable="false" />
 	<renderorder value="128" />
+	<occlusion enable="true" />
 </material>

+ 2 - 0
bin/Autoload/LargeData/Materials/PBR/Metallic10.xml

@@ -13,5 +13,7 @@
 	<shadowcull value="ccw" />
 	<fill value="solid" />
 	<depthbias constant="0" slopescaled="0" />
+	<alphatocoverage enable="false" />
 	<renderorder value="128" />
+	<occlusion enable="true" />
 </material>

+ 2 - 0
bin/Autoload/LargeData/Materials/PBR/Metallic3.xml

@@ -13,5 +13,7 @@
 	<shadowcull value="ccw" />
 	<fill value="solid" />
 	<depthbias constant="0" slopescaled="0" />
+	<alphatocoverage enable="false" />
 	<renderorder value="128" />
+	<occlusion enable="true" />
 </material>

+ 2 - 0
bin/Autoload/LargeData/Materials/PBR/Metallic5.xml

@@ -13,5 +13,7 @@
 	<shadowcull value="ccw" />
 	<fill value="solid" />
 	<depthbias constant="0" slopescaled="0" />
+	<alphatocoverage enable="false" />
 	<renderorder value="128" />
+	<occlusion enable="true" />
 </material>

+ 2 - 0
bin/Autoload/LargeData/Materials/PBR/Metallic7.xml

@@ -13,5 +13,7 @@
 	<shadowcull value="ccw" />
 	<fill value="solid" />
 	<depthbias constant="0" slopescaled="0" />
+	<alphatocoverage enable="false" />
 	<renderorder value="128" />
+	<occlusion enable="true" />
 </material>

+ 2 - 0
bin/Autoload/LargeData/Materials/PBR/MetallicRough10.xml

@@ -13,5 +13,7 @@
 	<shadowcull value="ccw" />
 	<fill value="solid" />
 	<depthbias constant="0" slopescaled="0" />
+	<alphatocoverage enable="false" />
 	<renderorder value="128" />
+	<occlusion enable="true" />
 </material>

+ 2 - 0
bin/Autoload/LargeData/Materials/PBR/MetallicRough7.xml

@@ -13,5 +13,7 @@
 	<shadowcull value="ccw" />
 	<fill value="solid" />
 	<depthbias constant="0" slopescaled="0" />
+	<alphatocoverage enable="false" />
 	<renderorder value="128" />
+	<occlusion enable="true" />
 </material>

+ 3 - 1
bin/Autoload/LargeData/Materials/PBR/Mud.xml

@@ -10,11 +10,13 @@
 	<parameter name="MatEmissiveColor" value="0 0 0" />
 	<parameter name="MatEnvMapColor" value="1 1 1" />
 	<parameter name="MatSpecColor" value="1 1 1 1" />
-	<parameter name="Roughness" value="0" />
+	<parameter name="Roughness" value="-0.12" />
 	<parameter name="Metallic" value="0" />
 	<cull value="ccw" />
 	<shadowcull value="ccw" />
 	<fill value="solid" />
 	<depthbias constant="0" slopescaled="0" />
+	<alphatocoverage enable="false" />
 	<renderorder value="128" />
+	<occlusion enable="true" />
 </material>

+ 3 - 1
bin/Autoload/LargeData/Materials/PBR/Roughness0.xml

@@ -3,7 +3,7 @@
 	<technique name="Techniques/PBR/PBRNoTexture.xml" quality="0" loddistance="0" />
 	<parameter name="UOffset" value="1 0 0 0" />
 	<parameter name="VOffset" value="0 1 0 0" />
-	<parameter name="MatDiffColor" value="0 0 0 1" />
+	<parameter name="MatDiffColor" value="0.034 0.101 0.589 1" />
 	<parameter name="MatEmissiveColor" value="0 0 0" />
 	<parameter name="MatEnvMapColor" value="1 1 1" />
 	<parameter name="MatSpecColor" value="1 1 1 1" />
@@ -13,5 +13,7 @@
 	<shadowcull value="ccw" />
 	<fill value="solid" />
 	<depthbias constant="0" slopescaled="0" />
+	<alphatocoverage enable="false" />
 	<renderorder value="128" />
+	<occlusion enable="true" />
 </material>

+ 3 - 1
bin/Autoload/LargeData/Materials/PBR/Roughness10.xml

@@ -3,7 +3,7 @@
 	<technique name="Techniques/PBR/PBRNoTexture.xml" quality="0" loddistance="0" />
 	<parameter name="UOffset" value="1 0 0 0" />
 	<parameter name="VOffset" value="0 1 0 0" />
-	<parameter name="MatDiffColor" value="0 0 0 1" />
+	<parameter name="MatDiffColor" value="0.034 0.101 0.589 1" />
 	<parameter name="MatEmissiveColor" value="0 0 0" />
 	<parameter name="MatEnvMapColor" value="1 1 1" />
 	<parameter name="MatSpecColor" value="1 1 1 1" />
@@ -13,5 +13,7 @@
 	<shadowcull value="ccw" />
 	<fill value="solid" />
 	<depthbias constant="0" slopescaled="0" />
+	<alphatocoverage enable="false" />
 	<renderorder value="128" />
+	<occlusion enable="true" />
 </material>

+ 3 - 1
bin/Autoload/LargeData/Materials/PBR/Roughness3.xml

@@ -3,7 +3,7 @@
 	<technique name="Techniques/PBR/PBRNoTexture.xml" quality="0" loddistance="0" />
 	<parameter name="UOffset" value="1 0 0 0" />
 	<parameter name="VOffset" value="0 1 0 0" />
-	<parameter name="MatDiffColor" value="0 0 0 1" />
+	<parameter name="MatDiffColor" value="0.034 0.101 0.589 1" />
 	<parameter name="MatEmissiveColor" value="0 0 0" />
 	<parameter name="MatEnvMapColor" value="1 1 1" />
 	<parameter name="MatSpecColor" value="1 1 1 1" />
@@ -13,5 +13,7 @@
 	<shadowcull value="ccw" />
 	<fill value="solid" />
 	<depthbias constant="0" slopescaled="0" />
+	<alphatocoverage enable="false" />
 	<renderorder value="128" />
+	<occlusion enable="true" />
 </material>

+ 3 - 1
bin/Autoload/LargeData/Materials/PBR/Roughness5.xml

@@ -3,7 +3,7 @@
 	<technique name="Techniques/PBR/PBRNoTexture.xml" quality="0" loddistance="0" />
 	<parameter name="UOffset" value="1 0 0 0" />
 	<parameter name="VOffset" value="0 1 0 0" />
-	<parameter name="MatDiffColor" value="0 0 0 1" />
+	<parameter name="MatDiffColor" value="0.034 0.101 0.589 1" />
 	<parameter name="MatEmissiveColor" value="0 0 0" />
 	<parameter name="MatEnvMapColor" value="1 1 1" />
 	<parameter name="MatSpecColor" value="1 1 1 1" />
@@ -13,5 +13,7 @@
 	<shadowcull value="ccw" />
 	<fill value="solid" />
 	<depthbias constant="0" slopescaled="0" />
+	<alphatocoverage enable="false" />
 	<renderorder value="128" />
+	<occlusion enable="true" />
 </material>

+ 3 - 1
bin/Autoload/LargeData/Materials/PBR/Roughness7.xml

@@ -3,7 +3,7 @@
 	<technique name="Techniques/PBR/PBRNoTexture.xml" quality="0" loddistance="0" />
 	<parameter name="UOffset" value="1 0 0 0" />
 	<parameter name="VOffset" value="0 1 0 0" />
-	<parameter name="MatDiffColor" value="0 0 0 1" />
+	<parameter name="MatDiffColor" value="0.034 0.101 0.589 1" />
 	<parameter name="MatEmissiveColor" value="0 0 0" />
 	<parameter name="MatEnvMapColor" value="1 1 1" />
 	<parameter name="MatSpecColor" value="1 1 1 1" />
@@ -13,5 +13,7 @@
 	<shadowcull value="ccw" />
 	<fill value="solid" />
 	<depthbias constant="0" slopescaled="0" />
+	<alphatocoverage enable="false" />
 	<renderorder value="128" />
+	<occlusion enable="true" />
 </material>

+ 2 - 0
bin/Autoload/LargeData/Materials/PBR/Sand.xml

@@ -16,5 +16,7 @@
 	<shadowcull value="ccw" />
 	<fill value="solid" />
 	<depthbias constant="0" slopescaled="0" />
+	<alphatocoverage enable="false" />
 	<renderorder value="128" />
+	<occlusion enable="true" />
 </material>

+ 2 - 0
bin/Autoload/LargeData/Materials/PBR/Tile.xml

@@ -16,5 +16,7 @@
 	<shadowcull value="ccw" />
 	<fill value="solid" />
 	<depthbias constant="0" slopescaled="0" />
+	<alphatocoverage enable="false" />
 	<renderorder value="128" />
+	<occlusion enable="true" />
 </material>

+ 20 - 8
bin/CoreData/Shaders/GLSL/IBL.glsl

@@ -236,10 +236,10 @@
         return mix(normal, reflection, lerpFactor);
     }
 
-    float GetMipFromRougness(float roughness)
+    float GetMipFromRoughness(float roughness)
     {
-        float smoothness = 1.0 - roughness;
-        return (1.0 - smoothness * smoothness) * 10.0;
+        float Level = 3 - 1.15 * log2( roughness );
+        return 9.0 - 1 - Level;
     }
 
 
@@ -253,6 +253,18 @@
         return SpecularColor * AB.x + AB.y;
     }
 
+    vec3 FixCubeLookup(vec3 v) 
+    {
+        float M = max(max(abs(v.x), abs(v.y)), abs(v.z));
+        float scale = (1024 - 1) / 1024;
+
+        if (abs(v.x) != M) v.x += scale;
+        if (abs(v.y) != M) v.y += scale;
+        if (abs(v.z) != M) v.z += scale; 
+
+        return v;
+    }
+
     /// Calculate IBL contributation
     ///     reflectVec: reflection vector for cube sampling
     ///     wsNormal: surface normal in word space
@@ -267,17 +279,17 @@
         // PMREM Mipmapmode https://seblagarde.wordpress.com/2012/06/10/amd-cubemapgen-for-physically-based-rendering/
         //float GlossScale = 16.0;
         //float GlossBias = 5.0;
-        float mipSelect = roughness * 9.0; //exp2(GlossScale * roughness * roughness + GlossBias) - exp2(GlossBias);
+        float mipSelect = GetMipFromRoughness(roughness); //exp2(GlossScale * roughness * roughness + GlossBias) - exp2(GlossBias);
 
         // OpenGL ES does not support textureLod without extensions and does not have the sZoneCubeMap sampler,
         // so for now, sample without explicit LOD, and from the environment sampler, where the zone texture will be put
         // on mobile hardware
         #ifndef GL_ES
-            vec3 cube = textureLod(sZoneCubeMap, reflectVec, mipSelect).rgb;
-            vec3 cubeD = textureLod(sZoneCubeMap, wsNormal, 9.0).rgb;
+            vec3 cube = textureLod(sZoneCubeMap, FixCubeLookup(reflectVec), mipSelect).rgb;
+            vec3 cubeD = textureLod(sZoneCubeMap, FixCubeLookup(wsNormal), 9.0).rgb;
         #else
-            vec3 cube = textureCube(sEnvCubeMap, reflectVec).rgb;
-            vec3 cubeD = textureCube(sEnvCubeMap, wsNormal).rgb;
+            vec3 cube = textureCube(sEnvCubeMap, FixCubeLookup(reflectVec)).rgb;
+            vec3 cubeD = textureCube(sEnvCubeMap, FixCubeLookup(wsNormal)).rgb;
         #endif
 
         // Fake the HDR texture

+ 23 - 10
bin/CoreData/Shaders/GLSL/Lighting.glsl

@@ -127,17 +127,30 @@ float GetDiffuse(vec3 normal, vec3 worldPos, out vec3 lightDir)
 
 float GetAtten(vec3 normal, vec3 worldPos, out vec3 lightDir)
 {
-     #ifdef DIRLIGHT
-        lightDir = cLightDirPS;
-        return clamp(dot(normal, lightDir), 0.0, 1.0);
-    #else
-        vec3 lightVec = (cLightPosPS.xyz - worldPos) * cLightPosPS.w;
-        float lightDist = length(lightVec);
-        float falloff = pow(clamp(1.0 - pow(lightDist / 1.0, 4.0), 0.0, 1.0), 2.0) / (pow(lightDist, 2.0) + 1.0);
+    lightDir = cLightDirPS;
+    return clamp(dot(normal, lightDir), 0.0, 1.0);
+    
+}
+
+float GetAttenPoint(vec3 normal, vec3 worldPos, out vec3 lightDir)
+{
+    vec3 lightVec = (cLightPosPS.xyz - worldPos) * cLightPosPS.w;
+    float lightDist = length(lightVec);
+    float falloff = pow(clamp(1.0 - pow(lightDist / 1.0, 4.0), 0.0, 1.0), 2.0) * 3.14159265358979323846 / (4 * 3.14159265358979323846)*(pow(lightDist, 2.0) + 1.0);
+    lightDir = lightVec / lightDist;
+    return clamp(dot(normal, lightDir), 0.0, 1.0) * falloff;
+
+}
+
+float GetAttenSpot(vec3 normal, vec3 worldPos, out vec3 lightDir)
+{
+    vec3 lightVec = (cLightPosPS.xyz - worldPos) * cLightPosPS.w;
+    float lightDist = length(lightVec);
+    float falloff = pow(clamp(1.0 - pow(lightDist / 1.0, 4.0), 0.0, 1.0), 2.0) / (pow(lightDist, 2.0) + 1.0);
+
+    lightDir = lightVec / lightDist;
+    return clamp(dot(normal, lightDir), 0.0, 1.0) * falloff;
 
-        lightDir = lightVec / vec3(lightDist, lightDist, lightDist);
-        return clamp(dot(normal, lightDir), 0.0, 1.0) * falloff;
-    #endif
 }
 
 float GetDiffuseVolumetric(vec3 worldPos)

+ 96 - 5
bin/CoreData/Shaders/GLSL/PBR.glsl

@@ -1,6 +1,81 @@
 #include "BRDF.glsl"
 #ifdef COMPILEPS
 
+    vec3 SphereLight(vec3 worldPos, vec3 lightVec, vec3 normal, vec3 toCamera, float roughness, vec3 specColor, out float ndl)
+    {
+        vec3 pos   = (cLightPosPS.xyz - worldPos);
+        float radius = cLightRad;
+
+        vec3 reflectVec   = reflect(-toCamera, normal);
+        vec3 centreToRay  = dot(pos, reflectVec) * reflectVec - pos;
+        vec3 closestPoint = pos + centreToRay * clamp(radius / length(centreToRay), 0.0, 1.0);
+
+        vec3 l = normalize(closestPoint);
+        vec3 h = normalize(toCamera + l);
+
+        ndl       = clamp(dot(normal, l), 0.0, 1.0);
+        float hdn = clamp(dot(h, normal), 0.0, 1.0);
+        float hdv = dot(h, toCamera);
+        float ndv = clamp(dot(normal, toCamera), 0.0, 1.0);
+
+        float distL      = length(pos);
+        float alpha      = roughness * roughness;
+        float alphaPrime = clamp(radius / (distL * 2.0) + alpha, 0.0, 1.0);
+
+        vec3 fresnelTerm = Fresnel(specColor, hdv) ;
+        float distTerm     = Distribution(hdn, alphaPrime);
+        float visTerm      = Visibility(ndl, ndv, roughness);
+
+        return distTerm * visTerm * fresnelTerm ;
+    }
+
+    vec3 TubeLight(vec3 worldPos, vec3 lightVec, vec3 normal, vec3 toCamera, float roughness, vec3 specColor, out float ndl)
+    {
+        float radius      = cLightRad;
+        float len         = cLightLength; 
+        vec3 pos         = (cLightPosPS.xyz - worldPos);
+        vec3 reflectVec  = reflect(-toCamera, normal);
+        
+        vec3 L01 = cLightDirPS * len;
+        vec3 L0 = pos - 0.5 * L01;
+        vec3 L1 = pos + 0.5 * L01;
+        vec3 ld = L1 - L0;
+
+        float distL0    = length( L0 );
+        float distL1    = length( L1 );
+
+        float NoL0      = dot( L0, normal ) / ( 2.0 * distL0 );
+        float NoL1      = dot( L1, normal ) / ( 2.0 * distL1 );
+        ndl             = ( 2.0 * clamp( NoL0 + NoL1, 0.0, 1.0 ) ) 
+                        / ( distL0 * distL1 + dot( L0, L1 ) + 2.0 );
+    
+        float a = len * len;
+        float b = dot( reflectVec, L01 );
+        float t = clamp( dot( L0, b * reflectVec - L01 ) / (a - b*b), 0.0, 1.0 );
+        
+        vec3 closestPoint   = L0 + ld * clamp(t, 0.0, 1.0);
+        vec3 centreToRay    = dot( closestPoint, reflectVec ) * reflectVec - closestPoint;
+        closestPoint          = closestPoint + centreToRay * clamp(radius / length(centreToRay), 0.0, 1.0);
+
+        vec3 l = normalize(closestPoint);
+        vec3 h = normalize(toCamera + l);
+
+        ndl       =  clamp(dot(normal, lightVec), 0.0, 1.0);
+        float hdn = clamp(dot(h, normal), 0.0, 1.0);
+        float hdv = dot(h, toCamera);
+        float ndv = clamp(dot(normal, toCamera), 0.0 ,1.0);
+
+        float distL      = length(closestPoint);
+        float alpha      = roughness * roughness;
+        float alphaPrime = clamp(radius / (distL * 2.0) + alpha, 0.0, 1.0);
+
+        vec3 fresnelTerm = Fresnel(specColor, hdv) ;
+        float distTerm     = Distribution(hdn, alphaPrime);
+        float visTerm      = Visibility(ndl, ndv, roughness);
+
+        return distTerm * visTerm * fresnelTerm ;
+    }
+
 	//Return the PBR BRDF value
 	// lightDir  = the vector to the light
 	// lightVev  = normalised lightDir
@@ -9,7 +84,7 @@
 	// roughness = roughness of the pixel
 	// diffColor = the rgb color of the pixel
 	// specColor = the rgb specular color of the pixel
-	vec3 GetBRDF(vec3 lightDir, vec3 lightVec, vec3 toCamera, vec3 normal, float roughness, vec3 diffColor, vec3 specColor)
+	vec3 GetBRDF(vec3 worldPos, vec3 lightDir, vec3 lightVec, vec3 toCamera, vec3 normal, float roughness, vec3 diffColor, vec3 specColor)
 	{
         vec3 Hn = normalize(toCamera + lightDir);
         float vdh = clamp((dot(toCamera, Hn)), M_EPSILON, 1.0);
@@ -21,11 +96,27 @@
         vec3 specularFactor = vec3(0.0, 0.0, 0.0);
 
         #ifdef SPECULAR
-            vec3 fresnelTerm = Fresnel(specColor, vdh) ;
-            float distTerm = Distribution(ndh, roughness);
-            float visTerm = Visibility(ndl, ndv, roughness);
+            if(cLightRad > 0.0)
+            {
+                if(cLightLength > 0.0)
+                {
+                    specularFactor = TubeLight(worldPos, lightVec, normal, toCamera, roughness, specColor, ndl);
+                    specularFactor *= ndl;
+                }
+                else
+                {
+                    specularFactor = SphereLight(worldPos, lightVec, normal, toCamera, roughness, specColor, ndl);
+                    specularFactor *= ndl;
+                }
+            }
+            else
+            {
+                vec3 fresnelTerm = Fresnel(specColor, vdh) ;
+                float distTerm = Distribution(ndh, roughness);
+                float visTerm = Visibility(ndl, ndv, roughness);
 
-            specularFactor = fresnelTerm * distTerm * visTerm  / M_PI;
+                specularFactor = fresnelTerm * distTerm * visTerm  / M_PI;
+            }
         #endif
 
         return diffuseFactor + specularFactor;

+ 12 - 4
bin/CoreData/Shaders/GLSL/PBRDeferred.glsl

@@ -86,7 +86,16 @@ void PS()
     vec4 projWorldPos = vec4(worldPos, 1.0);
 
     vec3 lightDir;
-    float atten = GetAtten(normal, worldPos, lightDir);
+
+    float atten = 1;
+
+    #if defined(DIRLIGHT)
+        atten = GetAtten(normal, worldPos, lightDir);
+    #elif defined(SPOTLIGHT)
+        atten = GetAttenSpot(normal, worldPos, lightDir);
+    #else
+        atten = GetAttenPoint(normal, worldPos, lightDir);
+    #endif
 
     float shadow = 1;
     #ifdef SHADOW
@@ -109,9 +118,8 @@ void PS()
     float ndl = clamp(abs(dot(normal, lightVec)), M_EPSILON, 1.0);
 
 
-    vec3 BRDF = GetBRDF(lightDir, lightVec, toCamera, normal, roughness, albedoInput.rgb, specColor);
+    vec3 BRDF = GetBRDF(worldPos, lightDir, lightVec, toCamera, normal, roughness, albedoInput.rgb, specColor);
 
-    gl_FragColor.a = 1.0;
-    gl_FragColor.rgb = BRDF * lightColor * (atten * shadow) / M_PI;
+    finalColor.rgb = BRDF * lightColor * (atten * shadow) / M_PI;
 
 }

+ 11 - 2
bin/CoreData/Shaders/GLSL/PBRLitSolid.glsl

@@ -172,7 +172,16 @@ void PS()
         vec3 lightDir;
         vec3 finalColor;
 
-        float atten = GetAtten(normal, vWorldPos.xyz, lightDir);
+        float atten = 1;
+
+        #if defined(DIRLIGHT)
+            atten = GetAtten(normal, vWorldPos.xyz, lightDir);
+        #elif defined(SPOTLIGHT)
+            atten = GetAttenSpot(normal, vWorldPos.xyz, lightDir);
+        #else
+            atten = GetAttenPoint(normal, vWorldPos.xyz, lightDir);
+        #endif
+
         float shadow = 1.0;
         #ifdef SHADOW
             shadow = GetShadow(vShadowPos, vWorldPos.w);
@@ -189,7 +198,7 @@ void PS()
         vec3 lightVec = normalize(lightDir);
         float ndl = clamp((dot(normal, lightVec)), M_EPSILON, 1.0);
 
-        vec3 BRDF = GetBRDF(lightDir, lightVec, toCamera, normal, roughness, diffColor.rgb, specColor);
+        vec3 BRDF = GetBRDF(vWorldPos.xyz, lightDir, lightVec, toCamera, normal, roughness, diffColor.rgb, specColor);
 
         finalColor.rgb = BRDF * lightColor * (atten * shadow) / M_PI;
 

+ 14 - 4
bin/CoreData/Shaders/GLSL/Uniforms.glsl

@@ -71,7 +71,11 @@ uniform vec4 cMatSpecColor;
 #ifdef PBR
     uniform float cRoughness;
     uniform float cMetallic;
+    uniform float cLightRad;
+    uniform float cLightLength;
 #endif
+uniform vec3 cZoneMin;
+uniform vec3 cZoneMax;
 uniform float cNearClipPS;
 uniform float cFarClipPS;
 uniform vec4 cShadowCubeAdjust;
@@ -174,6 +178,8 @@ uniform ZonePS
     vec4 cAmbientColor;
     vec4 cFogParams;
     vec3 cFogColor;
+    vec3 cZoneMin;
+    vec3 cZoneMax;
 };
 
 uniform LightPS
@@ -191,6 +197,10 @@ uniform LightPS
 #ifdef VSM_SHADOW
     vec2 cVSMShadowParams;
 #endif
+#ifdef PBR
+    float cLightRad;
+    float cLightLength;
+#endif
 };
 
 #ifndef CUSTOM_MATERIAL_CBUFFER
@@ -200,10 +210,10 @@ uniform MaterialPS
     vec3 cMatEmissiveColor;
     vec3 cMatEnvMapColor;
     vec4 cMatSpecColor;
-    #ifdef PBR
-        float cRoughness;
-        float cMetallic;
-    #endif
+#ifdef PBR
+    float cRoughness;
+    float cMetallic;
+#endif
 };
 #endif
 

+ 37 - 14
bin/CoreData/Shaders/HLSL/IBL.hlsl

@@ -227,23 +227,35 @@
         return lerp(normal, reflection, lerpFactor);
     }
 
-    float GetMipFromRougness(float roughness)
+    float GetMipFromRoughness(float roughness)
     {
-        const float smoothness = 1.0 - roughness;
-        return (1.0 - smoothness * smoothness) * 10.0;
+        float Level = 3 - 1.15 * log2( roughness );
+        return 9.0 - 1 - Level;
     }
 
 
-    float3 EnvBRDFApprox (float3 SpecularColor, float Roughness, float NoV)
+    float3 EnvBRDFApprox (float3 specColor, float roughness, float ndv)
     {
         const float4 c0 = float4(-1, -0.0275, -0.572, 0.022 );
         const float4 c1 = float4(1, 0.0425, 1.0, -0.04 );
-        float4 r = Roughness * c0 + c1;
-        float a004 = min( r.x * r.x, exp2( -9.28 * NoV ) ) * r.x + r.y;
+        float4 r = roughness * c0 + c1;
+        float a004 = min( r.x * r.x, exp2( -9.28 * ndv ) ) * r.x + r.y;
         float2 AB = float2( -1.04, 1.04 ) * a004 + r.zw;
-        return SpecularColor * AB.x + AB.y;
+        return specColor * AB.x + AB.y;
     }
 
+    float3 FixCubeLookup(float3 v) 
+    {
+        float M = max(max(abs(v.x), abs(v.y)), abs(v.z));
+        float scale = (1024 - 1) / 1024;
+
+        if (abs(v.x) != M) v.x += scale;
+        if (abs(v.y) != M) v.y += scale;
+        if (abs(v.z) != M) v.z += scale; 
+
+        return v;
+    }
+    
     /// Calculate IBL contributation
     ///     reflectVec: reflection vector for cube sampling
     ///     wsNormal: surface normal in word space
@@ -251,17 +263,28 @@
     ///     roughness: surface roughness
     ///     ambientOcclusion: ambient occlusion
     float3 ImageBasedLighting(in float3 reflectVec, in float3 tangent, in float3 bitangent, in float3 wsNormal, in float3 toCamera, in float3 diffColor, in float3 specColor, in float roughness, inout float3 reflectionCubeColor)
-    {
+    { 
         reflectVec = GetSpecularDominantDir(wsNormal, reflectVec, roughness);
         const float ndv = saturate(dot(-toCamera, wsNormal));
 
-        // PMREM Mipmapmode https://seblagarde.wordpress.com/2012/06/10/amd-cubemapgen-for-physically-based-rendering/
-        //const float GlossScale = 16.0;
-        //const float GlossBias = 5.0;
-        const float mipSelect = roughness * 9.0;// exp2(GlossScale * roughness + GlossBias) - exp2(GlossBias);
+        /// Test: Parallax correction, currently not working
+
+        // float3 intersectMax = (cZoneMax - toCamera) / reflectVec;
+        // float3 intersectMin = (cZoneMin - toCamera) / reflectVec;
+        
+        // float3 furthestPlane = max(intersectMax, intersectMin);
+        
+        // float planeDistance = min(min(furthestPlane.x, furthestPlane.y), furthestPlane.z);
+
+        // // Get the intersection position
+        // float3 intersectionPos = toCamera + reflectVec * planeDistance;
+        // // Get corrected reflection
+        // reflectVec = intersectionPos - ((cZoneMin + cZoneMax )/ 2);
 
-        float3 cube = SampleCubeLOD(ZoneCubeMap, float4(reflectVec, mipSelect)).rgb;
-        float3 cubeD = SampleCubeLOD(ZoneCubeMap, float4(wsNormal, 9.0)).rgb;
+        const float mipSelect = GetMipFromRoughness(roughness);
+        float3 cube = SampleCubeLOD(ZoneCubeMap, float4(FixCubeLookup(reflectVec), mipSelect)).rgb;
+        float3 cubeD = SampleCubeLOD(ZoneCubeMap, float4(FixCubeLookup(wsNormal), 9.0)).rgb;
+        
         // Fake the HDR texture
         float brightness = clamp(cAmbientColor.a, 0.0, 1.0);
         float darknessCutoff = clamp((cAmbientColor.a - 1.0) * 0.1, 0.0, 0.25);

+ 24 - 10
bin/CoreData/Shaders/HLSL/Lighting.hlsl

@@ -138,19 +138,33 @@ float GetDiffuse(float3 normal, float3 worldPos, out float3 lightDir)
 
 float GetAtten(float3 normal, float3 worldPos, out float3 lightDir)
 {
-     #ifdef DIRLIGHT
-        lightDir = cLightDirPS;
-        return saturate(dot(normal, lightDir));
-    #else
-        float3 lightVec = (cLightPosPS.xyz - worldPos) * cLightPosPS.w;
-        float lightDist = length(lightVec);
-        float falloff = pow(saturate(1.0 - pow(lightDist / 1.0, 4.0)), 2.0) / (pow(lightDist, 2.0) + 1.0);
+    lightDir = cLightDirPS;
+    return saturate(dot(normal, lightDir));
+    
+}
+
+float GetAttenPoint(float3 normal, float3 worldPos, out float3 lightDir)
+{
+    float3 lightVec = (cLightPosPS.xyz - worldPos) * cLightPosPS.w;
+    float lightDist = length(lightVec);
+    float falloff = pow(saturate(1.0 - pow(lightDist / 1.0, 4.0)), 2.0) * 3.14159265358979323846 / (4 * 3.14159265358979323846)*(pow(lightDist, 2.0) + 1.0);
+    lightDir = lightVec / lightDist;
+    return saturate(dot(normal, lightDir)) * falloff;
+
+}
+
+float GetAttenSpot(float3 normal, float3 worldPos, out float3 lightDir)
+{
+    float3 lightVec = (cLightPosPS.xyz - worldPos) * cLightPosPS.w;
+    float lightDist = length(lightVec);
+    float falloff = pow(saturate(1.0 - pow(lightDist / 1.0, 4.0)), 2.0) / (pow(lightDist, 2.0) + 1.0);
+
+    lightDir = lightVec / lightDist;
+    return saturate(dot(normal, lightDir)) * falloff;
 
-        lightDir = lightVec / lightDist;
-        return saturate(dot(normal, lightDir)) * falloff;
-    #endif
 }
 
+
 float GetDiffuseVolumetric(float3 worldPos)
 {
     #ifdef DIRLIGHT

+ 101 - 8
bin/CoreData/Shaders/HLSL/PBR.hlsl

@@ -1,32 +1,125 @@
 #include "BRDF.hlsl"
 #ifdef COMPILEPS
 
+    
+
+    float3 SphereLight(float3 worldPos, float3 lightVec, float3 normal, float3 toCamera, float roughness, float3 specColor, out float ndl)
+    {
+        float3 pos   = (cLightPosPS.xyz - worldPos);
+        float radius = cLightRad;
+
+        float3 reflectVec   = reflect(-toCamera, normal);
+        float3 centreToRay  = dot(pos, reflectVec) * reflectVec - pos;
+        float3 closestPoint = pos + centreToRay * saturate(radius / length(centreToRay));
+
+        float3 l = normalize(closestPoint);
+        float3 h = normalize(toCamera + l);
+
+        ndl       = saturate(dot(normal, l));
+        float hdn = saturate(dot(h, normal));
+        float hdv = dot(h, toCamera);
+        float ndv = saturate(dot(normal, toCamera));
+
+        float distL      = length(pos);
+        float alpha      = roughness * roughness;
+        float alphaPrime = saturate(radius / (distL * 2.0) + alpha);
+
+        const float3 fresnelTerm = Fresnel(specColor, hdv) ;
+        const float distTerm     = Distribution(hdn, alphaPrime);
+        const float visTerm      = Visibility(ndl, ndv, roughness);
+
+        return distTerm * visTerm * fresnelTerm ;
+    }
+
+    float3 TubeLight(float3 worldPos, float3 lightVec, float3 normal, float3 toCamera, float roughness, float3 specColor, out float ndl)
+    {
+         float radius      = cLightRad;
+         float len         = cLightLength; 
+        float3 pos         = (cLightPosPS.xyz - worldPos);
+        float3 reflectVec  = reflect(-toCamera, normal);
+        
+        float3 L01 = cLightDirPS * len;
+        float3 L0 = pos - 0.5 * L01;
+        float3 L1 = pos + 0.5 * L01;
+        float3 ld = L1 - L0;
+
+        float distL0    = length( L0 );
+        float distL1    = length( L1 );
+
+        float NoL0      = dot( L0, normal ) / ( 2.0 * distL0 );
+        float NoL1      = dot( L1, normal ) / ( 2.0 * distL1 );
+        ndl             = ( 2.0 * clamp( NoL0 + NoL1, 0.0, 1.0 ) ) 
+                        / ( distL0 * distL1 + dot( L0, L1 ) + 2.0 );
+    
+        float a = len * len;
+        float b = dot( reflectVec, L01 );
+        float t = saturate( dot( L0, b * reflectVec - L01 ) / (a - b*b) );
+        
+        float3 closestPoint   = L0 + ld * saturate( t);
+        float3 centreToRay    = dot( closestPoint, reflectVec ) * reflectVec - closestPoint;
+        closestPoint          = closestPoint + centreToRay * saturate(radius / length(centreToRay));
+
+        float3 l = normalize(closestPoint);
+        float3 h = normalize(toCamera + l);
+
+        ndl       =  saturate(dot(normal, lightVec));
+        float hdn = saturate(dot(h, normal));
+        float hdv = dot(h, toCamera);
+        float ndv = saturate(dot(normal, toCamera));
+
+        float distL      = length(closestPoint);
+        float alpha      = roughness * roughness;
+        float alphaPrime = saturate(radius / (distL * 2.0) + alpha);
+
+        const float3 fresnelTerm = Fresnel(specColor, hdv) ;
+        const float distTerm     = Distribution(hdn, alphaPrime);
+        const float visTerm      = Visibility(ndl, ndv, roughness);
+
+        return distTerm * visTerm * fresnelTerm ;
+    }
+
 	//Return the PBR BRDF value
 	// lightDir  = the vector to the light
-	// lightVev  = normalised lightDir
+	// lightVec  = normalised lightDir
 	// toCamera  = vector to the camera
 	// normal    = surface normal of the pixel
 	// roughness = roughness of the pixel
 	// diffColor = the rgb color of the pixel
 	// specColor = the rgb specular color of the pixel
-	float3 GetBRDF(float3 lightDir, float3 lightVec, float3 toCamera, float3 normal, float roughness, float3 diffColor, float3 specColor)
+	float3 GetBRDF(float3 worldPos, float3 lightDir, float3 lightVec, float3 toCamera, float3 normal, float roughness, float3 diffColor, float3 specColor)
 	{
 
         const float3 Hn = normalize(toCamera + lightDir);
         const float vdh = clamp((dot(toCamera, Hn)), M_EPSILON, 1.0);
         const float ndh = clamp((dot(normal, Hn)), M_EPSILON, 1.0);
-        const float ndl = clamp((dot(normal, lightVec)), M_EPSILON, 1.0);
+        float ndl = clamp((dot(normal, lightVec)), M_EPSILON, 1.0);
         const float ndv = clamp((dot(normal, toCamera)), M_EPSILON, 1.0);
 
-        const float3 diffuseFactor = Diffuse(diffColor, roughness, ndv, ndl, vdh);
+        const float3 diffuseFactor = Diffuse(diffColor, roughness, ndv, ndl, vdh)  * ndl;
         float3 specularFactor = 0;
 
         #ifdef SPECULAR
-            const float3 fresnelTerm = Fresnel(specColor, vdh) ;
-            const float distTerm = Distribution(ndh, roughness);
-            const float visTerm = Visibility(ndl, ndv, roughness);
+            if(cLightRad > 0.0)
+            {
+                if(cLightLength > 0.0)
+                {
+                    specularFactor = TubeLight(worldPos, lightVec, normal, toCamera, roughness, specColor, ndl);
+                    specularFactor *= ndl;
+                }
+                else
+                {
+                    specularFactor = SphereLight(worldPos, lightVec, normal, toCamera, roughness, specColor, ndl);
+                    specularFactor *= ndl;
+                }
+            }
+            else
+            {
+                const float3 fresnelTerm = Fresnel(specColor, vdh) ;
+                const float distTerm = Distribution(ndh, roughness);
+                const float visTerm = Visibility(ndl, ndv, roughness);
+                specularFactor = distTerm * visTerm * fresnelTerm * ndl/ M_PI;
+            }
 
-            specularFactor = distTerm * visTerm * fresnelTerm / M_PI;
         #endif
 
         return diffuseFactor + specularFactor;

+ 10 - 2
bin/CoreData/Shaders/HLSL/PBRDeferred.hlsl

@@ -93,7 +93,15 @@ void PS(
     const float4 projWorldPos = float4(worldPos, 1.0);
 
     float3 lightDir;
-    float atten = GetAtten(normal, worldPos, lightDir);
+     float atten = 1;
+
+        #if defined(DIRLIGHT)
+            atten = GetAtten(normal, worldPos, lightDir);
+        #elif defined(SPOTLIGHT)
+            atten = GetAttenSpot(normal, worldPos, lightDir);
+        #else
+            atten = GetAttenPoint(normal, worldPos, lightDir);
+        #endif
 
     float shadow = 1;
     #ifdef SHADOW
@@ -113,7 +121,7 @@ void PS(
     const float3 lightVec = normalize(lightDir);
     const float ndl = clamp(abs(dot(normal, lightVec)), M_EPSILON, 1.0);
 
-    float3 BRDF = GetBRDF(lightDir, lightVec, toCamera, normal, roughness, albedoInput.rgb, specColor);
+    float3 BRDF = GetBRDF(worldPos, lightDir, lightVec, toCamera, normal, roughness, albedoInput.rgb, specColor);
 
     oColor.a = 1;
     oColor.rgb  = BRDF * lightColor * shadow * atten / M_PI;

+ 10 - 3
bin/CoreData/Shaders/HLSL/PBRLitSolid.hlsl

@@ -1,9 +1,9 @@
 #include "Uniforms.hlsl"
 #include "Samplers.hlsl"
+#include "Constants.hlsl"
 #include "Transform.hlsl"
 #include "ScreenPos.hlsl"
 #include "Lighting.hlsl"
-#include "Constants.hlsl"
 #include "Fog.hlsl"
 #include "PBR.hlsl"
 #include "IBL.hlsl"
@@ -252,8 +252,15 @@ void PS(
         float3 lightDir;
         float3 lightColor;
         float3 finalColor;
+        float atten = 1;
 
-        float atten = GetAtten(normal, iWorldPos.xyz, lightDir);
+        #if defined(DIRLIGHT)
+            atten = GetAtten(normal, iWorldPos.xyz, lightDir);
+        #elif defined(SPOTLIGHT)
+            atten = GetAttenSpot(normal, iWorldPos.xyz, lightDir);
+        #else
+            atten = GetAttenPoint(normal, iWorldPos.xyz, lightDir);
+        #endif
 
         float shadow = 1.0;
 
@@ -275,7 +282,7 @@ void PS(
         const float ndl = clamp((dot(normal, lightVec)), M_EPSILON, 1.0);
 
 
-        float3 BRDF = GetBRDF(lightDir, lightVec, toCamera, normal, roughness, diffColor.rgb, specColor);
+        float3 BRDF = GetBRDF(iWorldPos.xyz, lightDir, lightVec, toCamera, normal, roughness, diffColor.rgb, specColor);
         finalColor.rgb = BRDF * lightColor * (atten * shadow) / M_PI;
 
         #ifdef AMBIENT

+ 10 - 0
bin/CoreData/Shaders/HLSL/Uniforms.hlsl

@@ -60,7 +60,11 @@ uniform float4 cMatSpecColor;
 #ifdef PBR
     uniform float cRoughness;
     uniform float cMetallic;
+    uniform float cLightRad;
+    uniform float cLightLength;
 #endif
+uniform float3 cZoneMin;
+uniform float3 cZoneMax;
 uniform float cNearClipPS;
 uniform float cFarClipPS;
 uniform float4 cShadowCubeAdjust;
@@ -163,6 +167,8 @@ cbuffer ZonePS : register(b2)
     float4 cAmbientColor;
     float4 cFogParams;
     float3 cFogColor;
+    float3 cZoneMin;
+    float3 cZoneMax;
 }
 
 cbuffer LightPS : register(b3)
@@ -178,6 +184,10 @@ cbuffer LightPS : register(b3)
     float4 cShadowSplits;
     float2 cVSMShadowParams;
     float4x4 cLightMatricesPS[4];
+    #ifdef PBR
+        float cLightRad;
+        float cLightLength;
+    #endif
 }
 
 #ifndef CUSTOM_MATERIAL_CBUFFER

File diff suppressed because it is too large
+ 195 - 200
bin/Data/Scenes/PBRExample.xml


Some files were not shown because too many files changed in this diff