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", "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", "void set_temperature(float)", asMETHOD(Light, SetTemperature), asCALL_THISCALL);
     engine->RegisterObjectMethod("Light", "float get_temperature() const", asMETHOD(Light, GetTemperature), 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", "void set_usePhysicalValues(bool)", asMETHOD(Light, SetUsePhysicalValues), asCALL_THISCALL);
     engine->RegisterObjectMethod("Light", "bool get_usePhysicalValues() const", asMETHOD(Light, GetUsePhysicalValues), 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", "void set_specularIntensity(float)", asMETHOD(Light, SetSpecularIntensity), asCALL_THISCALL);
     engine->RegisterObjectMethod("Light", "float get_specularIntensity() const", asMETHOD(Light, GetSpecularIntensity), 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);
     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_AMBIENTCOLOR, zone_->GetAmbientColor());
         graphics->SetShaderParameter(PSP_FOGCOLOR, overrideFogColorToBlack ? Color::BLACK : zone_->GetFogColor());
         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 farClip = camera->GetFarClip();
         float fogStart = Min(zone_->GetFogStart(), farClip);
         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);
                         graphics->SetShaderParameter(VSP_LIGHTMATRICES, lightVecRot.Data(), 16);
 #else
 #else
                         graphics->SetShaderParameter(VSP_LIGHTMATRICES, lightVecRot.Data(), 12);
                         graphics->SetShaderParameter(VSP_LIGHTMATRICES, lightVecRot.Data(), 12);
+
 #endif
 #endif
                     }
                     }
                     break;
                     break;
@@ -373,6 +376,9 @@ void Batch::Prepare(View* view, Camera* camera, bool setModelTransform, bool all
                 light->GetEffectiveSpecularIntensity()) * fade);
                 light->GetEffectiveSpecularIntensity()) * fade);
             graphics->SetShaderParameter(PSP_LIGHTDIR, lightDir);
             graphics->SetShaderParameter(PSP_LIGHTDIR, lightDir);
             graphics->SetShaderParameter(PSP_LIGHTPOS, lightPos);
             graphics->SetShaderParameter(PSP_LIGHTPOS, lightPos);
+            //graphics->define
+            graphics->SetShaderParameter(PSP_LIGHTRAD, light->GetRadius());
+            graphics->SetShaderParameter(PSP_LIGHTLENGTH, light->GetLength());
 
 
             if (graphics->HasShaderParameter(PSP_LIGHTMATRICES))
             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_VSMSHADOWPARAMS("VSMShadowParams");
 extern URHO3D_API const StringHash PSP_ROUGHNESS("Roughness");
 extern URHO3D_API const StringHash PSP_ROUGHNESS("Roughness");
 extern URHO3D_API const StringHash PSP_METALLIC("Metallic");
 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);
 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_VSMSHADOWPARAMS;
 extern URHO3D_API const StringHash PSP_ROUGHNESS;
 extern URHO3D_API const StringHash PSP_ROUGHNESS;
 extern URHO3D_API const StringHash PSP_METALLIC;
 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.
 // Scale calculation from bounding box diagonal.
 extern URHO3D_API const Vector3 DOT_SCALE;
 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_SHADOWMAXEXTRUSION = 1000.0f;
 static const float DEFAULT_SHADOWSPLIT = 1000.0f;
 static const float DEFAULT_SHADOWSPLIT = 1000.0f;
 static const float DEFAULT_TEMPERATURE = 6590.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[] =
 static const char* typeNames[] =
 {
 {
@@ -94,7 +96,9 @@ Light::Light(Context* context) :
     shadowCascade_(CascadeParameters(DEFAULT_SHADOWSPLIT, 0.0f, 0.0f, 0.0f, DEFAULT_SHADOWFADESTART)),
     shadowCascade_(CascadeParameters(DEFAULT_SHADOWSPLIT, 0.0f, 0.0f, 0.0f, DEFAULT_SHADOWFADESTART)),
     shadowFocus_(FocusParameters(true, true, true, DEFAULT_SHADOWQUANTIZE, DEFAULT_SHADOWMINVIEW)),
     shadowFocus_(FocusParameters(true, true, true, DEFAULT_SHADOWQUANTIZE, DEFAULT_SHADOWMINVIEW)),
     lightQueue_(0),
     lightQueue_(0),
-    temperature_(6590.0f),
+    temperature_(DEFAULT_TEMPERATURE),
+    lightRad_(DEFAULT_RADIUS),
+    lightLength_(DEFAULT_LENGTH),
     specularIntensity_(DEFAULT_SPECULARINTENSITY),
     specularIntensity_(DEFAULT_SPECULARINTENSITY),
     brightness_(DEFAULT_BRIGHTNESS),
     brightness_(DEFAULT_BRIGHTNESS),
     range_(DEFAULT_RANGE),
     range_(DEFAULT_RANGE),
@@ -107,7 +111,8 @@ Light::Light(Context* context) :
     shadowNearFarRatio_(DEFAULT_SHADOWNEARFARRATIO),
     shadowNearFarRatio_(DEFAULT_SHADOWNEARFARRATIO),
     shadowMaxExtrusion_(DEFAULT_SHADOWMAXEXTRUSION),
     shadowMaxExtrusion_(DEFAULT_SHADOWMAXEXTRUSION),
     perVertex_(false),
     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("Brightness Multiplier", GetBrightness, SetBrightness, float, DEFAULT_BRIGHTNESS, AM_DEFAULT);
     URHO3D_ACCESSOR_ATTRIBUTE("Temperature", GetTemperature, SetTemperature, float, DEFAULT_TEMPERATURE, 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("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("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 FOV", GetFov, SetFov, float, DEFAULT_LIGHT_FOV, AM_DEFAULT);
     URHO3D_ACCESSOR_ATTRIBUTE("Spot Aspect Ratio", GetAspectRatio, SetAspectRatio, float, 1.0f, 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();
     MarkNetworkUpdate();
 }
 }
 
 
+void Light::SetRadius(float radius)
+{
+    lightRad_ = radius;
+    MarkNetworkUpdate();
+}
+
+void Light::SetLength(float length)
+{
+    lightLength_ = length;
+    MarkNetworkUpdate();
+}
+
 void Light::SetUsePhysicalValues(bool enable)
 void Light::SetUsePhysicalValues(bool enable)
 {
 {
     usePhysicalValues_ = enable;
     usePhysicalValues_ = enable;
     MarkNetworkUpdate();
     MarkNetworkUpdate();
 }
 }
 
 
+void Light::SetIsAreaLight(bool enable)
+{
+    isAreaLight_ = enable;
+    MarkNetworkUpdate();
+}
+
 void Light::SetSpecularIntensity(float intensity)
 void Light::SetSpecularIntensity(float intensity)
 {
 {
     specularIntensity_ = Max(intensity, 0.0f);
     specularIntensity_ = Max(intensity, 0.0f);

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

@@ -180,8 +180,14 @@ public:
     void SetColor(const Color& color);
     void SetColor(const Color& color);
     /// Set temperature of the light in Kelvin. Modulates the light color when "use physical values" is enabled.
     /// Set temperature of the light in Kelvin. Modulates the light color when "use physical values" is enabled.
     void SetTemperature(float temperature);
     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.
     /// Set use physical light values.
     void SetUsePhysicalValues(bool enable);
     void SetUsePhysicalValues(bool enable);
+    /// Set light to be an area light
+    void SetIsAreaLight(bool enable);
     /// Set specular intensity. Zero disables specular calculations.
     /// Set specular intensity. Zero disables specular calculations.
     void SetSpecularIntensity(float intensity);
     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.
     /// 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.
     /// Return the temperature of the light in Kelvin.
     float GetTemperature() const { return temperature_; }
     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.
     /// Return if light uses temperature and brightness in lumens.
     bool GetUsePhysicalValues() const { return usePhysicalValues_; }
     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.
     /// Return the color value of the temperature in Kelvin.
     Color GetColorFromTemperature() const;
     Color GetColorFromTemperature() const;
 
 
@@ -339,6 +354,10 @@ private:
     Color color_;
     Color color_;
     /// Light temperature.
     /// Light temperature.
     float 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.
     /// Shadow depth bias parameters.
     BiasParameters shadowBias_;
     BiasParameters shadowBias_;
     /// Directional light cascaded shadow parameters.
     /// Directional light cascaded shadow parameters.
@@ -379,6 +398,8 @@ private:
     bool perVertex_;
     bool perVertex_;
     /// Use physical light values flag.
     /// Use physical light values flag.
     bool usePhysicalValues_;
     bool usePhysicalValues_;
+    /// Use Area lighting flag. Currently not used.
+    bool isAreaLight_;
 };
 };
 
 
 inline bool CompareLights(Light* lhs, Light* rhs)
 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 SetPerVertex(bool enable);
     void SetColor(const Color& color);
     void SetColor(const Color& color);
     void SetTemperature(float temperature);
     void SetTemperature(float temperature);
+    void SetRadius(float redius);
+    void SetLength(float length);
     void SetUsePhysicalValues(bool enable);
     void SetUsePhysicalValues(bool enable);
+    void SetIsAreaLight(bool enable);
     void SetSpecularIntensity(float intensity);
     void SetSpecularIntensity(float intensity);
     void SetBrightness(float brightness);
     void SetBrightness(float brightness);
     void SetRange(float range);
     void SetRange(float range);
@@ -69,11 +72,14 @@ class Light : public Drawable
     bool GetPerVertex() const;
     bool GetPerVertex() const;
     const Color& GetColor() const;
     const Color& GetColor() const;
     float GetTemperature() const;
     float GetTemperature() const;
+    float GetRadius() const;
+    float GetLength() const;
     float GetSpecularIntensity() const;
     float GetSpecularIntensity() const;
     float GetBrightness() const;
     float GetBrightness() const;
     Color GetEffectiveColor() const;
     Color GetEffectiveColor() const;
     Color GetColorFromTemperature() const;
     Color GetColorFromTemperature() const;
     bool GetUsePhysicalValues() const;
     bool GetUsePhysicalValues() const;
+    bool GetIsAreaLight() const;
     float GetEffectiveSpecularIntensity() const;
     float GetEffectiveSpecularIntensity() const;
     float GetRange() const;
     float GetRange() const;
     float GetFov() const;
     float GetFov() const;
@@ -97,7 +103,10 @@ class Light : public Drawable
     tolua_property__get_set bool perVertex;
     tolua_property__get_set bool perVertex;
     tolua_property__get_set Color& color;
     tolua_property__get_set Color& color;
     tolua_property__get_set float temperature;
     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 usePhysicalValues;
+    tolua_property__get_set bool isAreaLight;
     tolua_property__get_set float specularIntensity;
     tolua_property__get_set float specularIntensity;
     tolua_property__get_set float brightness;
     tolua_property__get_set float brightness;
     tolua_property__get_set float range;
     tolua_property__get_set float range;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@@ -236,10 +236,10 @@
         return mix(normal, reflection, lerpFactor);
         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;
         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
     /// Calculate IBL contributation
     ///     reflectVec: reflection vector for cube sampling
     ///     reflectVec: reflection vector for cube sampling
     ///     wsNormal: surface normal in word space
     ///     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/
         // PMREM Mipmapmode https://seblagarde.wordpress.com/2012/06/10/amd-cubemapgen-for-physically-based-rendering/
         //float GlossScale = 16.0;
         //float GlossScale = 16.0;
         //float GlossBias = 5.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,
         // 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
         // so for now, sample without explicit LOD, and from the environment sampler, where the zone texture will be put
         // on mobile hardware
         // on mobile hardware
         #ifndef GL_ES
         #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
         #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
         #endif
 
 
         // Fake the HDR texture
         // 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)
 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)
 float GetDiffuseVolumetric(vec3 worldPos)

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

@@ -1,6 +1,81 @@
 #include "BRDF.glsl"
 #include "BRDF.glsl"
 #ifdef COMPILEPS
 #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
 	//Return the PBR BRDF value
 	// lightDir  = the vector to the light
 	// lightDir  = the vector to the light
 	// lightVev  = normalised lightDir
 	// lightVev  = normalised lightDir
@@ -9,7 +84,7 @@
 	// roughness = roughness of the pixel
 	// roughness = roughness of the pixel
 	// diffColor = the rgb color of the pixel
 	// diffColor = the rgb color of the pixel
 	// specColor = the rgb specular 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);
         vec3 Hn = normalize(toCamera + lightDir);
         float vdh = clamp((dot(toCamera, Hn)), M_EPSILON, 1.0);
         float vdh = clamp((dot(toCamera, Hn)), M_EPSILON, 1.0);
@@ -21,11 +96,27 @@
         vec3 specularFactor = vec3(0.0, 0.0, 0.0);
         vec3 specularFactor = vec3(0.0, 0.0, 0.0);
 
 
         #ifdef SPECULAR
         #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
         #endif
 
 
         return diffuseFactor + specularFactor;
         return diffuseFactor + specularFactor;

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

@@ -86,7 +86,16 @@ void PS()
     vec4 projWorldPos = vec4(worldPos, 1.0);
     vec4 projWorldPos = vec4(worldPos, 1.0);
 
 
     vec3 lightDir;
     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;
     float shadow = 1;
     #ifdef SHADOW
     #ifdef SHADOW
@@ -109,9 +118,8 @@ void PS()
     float ndl = clamp(abs(dot(normal, lightVec)), M_EPSILON, 1.0);
     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 lightDir;
         vec3 finalColor;
         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;
         float shadow = 1.0;
         #ifdef SHADOW
         #ifdef SHADOW
             shadow = GetShadow(vShadowPos, vWorldPos.w);
             shadow = GetShadow(vShadowPos, vWorldPos.w);
@@ -189,7 +198,7 @@ void PS()
         vec3 lightVec = normalize(lightDir);
         vec3 lightVec = normalize(lightDir);
         float ndl = clamp((dot(normal, lightVec)), M_EPSILON, 1.0);
         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;
         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
 #ifdef PBR
     uniform float cRoughness;
     uniform float cRoughness;
     uniform float cMetallic;
     uniform float cMetallic;
+    uniform float cLightRad;
+    uniform float cLightLength;
 #endif
 #endif
+uniform vec3 cZoneMin;
+uniform vec3 cZoneMax;
 uniform float cNearClipPS;
 uniform float cNearClipPS;
 uniform float cFarClipPS;
 uniform float cFarClipPS;
 uniform vec4 cShadowCubeAdjust;
 uniform vec4 cShadowCubeAdjust;
@@ -174,6 +178,8 @@ uniform ZonePS
     vec4 cAmbientColor;
     vec4 cAmbientColor;
     vec4 cFogParams;
     vec4 cFogParams;
     vec3 cFogColor;
     vec3 cFogColor;
+    vec3 cZoneMin;
+    vec3 cZoneMax;
 };
 };
 
 
 uniform LightPS
 uniform LightPS
@@ -191,6 +197,10 @@ uniform LightPS
 #ifdef VSM_SHADOW
 #ifdef VSM_SHADOW
     vec2 cVSMShadowParams;
     vec2 cVSMShadowParams;
 #endif
 #endif
+#ifdef PBR
+    float cLightRad;
+    float cLightLength;
+#endif
 };
 };
 
 
 #ifndef CUSTOM_MATERIAL_CBUFFER
 #ifndef CUSTOM_MATERIAL_CBUFFER
@@ -200,10 +210,10 @@ uniform MaterialPS
     vec3 cMatEmissiveColor;
     vec3 cMatEmissiveColor;
     vec3 cMatEnvMapColor;
     vec3 cMatEnvMapColor;
     vec4 cMatSpecColor;
     vec4 cMatSpecColor;
-    #ifdef PBR
-        float cRoughness;
-        float cMetallic;
-    #endif
+#ifdef PBR
+    float cRoughness;
+    float cMetallic;
+#endif
 };
 };
 #endif
 #endif
 
 

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

@@ -227,23 +227,35 @@
         return lerp(normal, reflection, lerpFactor);
         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 c0 = float4(-1, -0.0275, -0.572, 0.022 );
         const float4 c1 = float4(1, 0.0425, 1.0, -0.04 );
         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;
         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
     /// Calculate IBL contributation
     ///     reflectVec: reflection vector for cube sampling
     ///     reflectVec: reflection vector for cube sampling
     ///     wsNormal: surface normal in word space
     ///     wsNormal: surface normal in word space
@@ -251,17 +263,28 @@
     ///     roughness: surface roughness
     ///     roughness: surface roughness
     ///     ambientOcclusion: ambient occlusion
     ///     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)
     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);
         reflectVec = GetSpecularDominantDir(wsNormal, reflectVec, roughness);
         const float ndv = saturate(dot(-toCamera, wsNormal));
         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
         // Fake the HDR texture
         float brightness = clamp(cAmbientColor.a, 0.0, 1.0);
         float brightness = clamp(cAmbientColor.a, 0.0, 1.0);
         float darknessCutoff = clamp((cAmbientColor.a - 1.0) * 0.1, 0.0, 0.25);
         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)
 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)
 float GetDiffuseVolumetric(float3 worldPos)
 {
 {
     #ifdef DIRLIGHT
     #ifdef DIRLIGHT

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

@@ -1,32 +1,125 @@
 #include "BRDF.hlsl"
 #include "BRDF.hlsl"
 #ifdef COMPILEPS
 #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
 	//Return the PBR BRDF value
 	// lightDir  = the vector to the light
 	// lightDir  = the vector to the light
-	// lightVev  = normalised lightDir
+	// lightVec  = normalised lightDir
 	// toCamera  = vector to the camera
 	// toCamera  = vector to the camera
 	// normal    = surface normal of the pixel
 	// normal    = surface normal of the pixel
 	// roughness = roughness of the pixel
 	// roughness = roughness of the pixel
 	// diffColor = the rgb color of the pixel
 	// diffColor = the rgb color of the pixel
 	// specColor = the rgb specular 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 float3 Hn = normalize(toCamera + lightDir);
         const float vdh = clamp((dot(toCamera, Hn)), M_EPSILON, 1.0);
         const float vdh = clamp((dot(toCamera, Hn)), M_EPSILON, 1.0);
         const float ndh = clamp((dot(normal, 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 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;
         float3 specularFactor = 0;
 
 
         #ifdef SPECULAR
         #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
         #endif
 
 
         return diffuseFactor + specularFactor;
         return diffuseFactor + specularFactor;

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

@@ -93,7 +93,15 @@ void PS(
     const float4 projWorldPos = float4(worldPos, 1.0);
     const float4 projWorldPos = float4(worldPos, 1.0);
 
 
     float3 lightDir;
     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;
     float shadow = 1;
     #ifdef SHADOW
     #ifdef SHADOW
@@ -113,7 +121,7 @@ void PS(
     const float3 lightVec = normalize(lightDir);
     const float3 lightVec = normalize(lightDir);
     const float ndl = clamp(abs(dot(normal, lightVec)), M_EPSILON, 1.0);
     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.a = 1;
     oColor.rgb  = BRDF * lightColor * shadow * atten / M_PI;
     oColor.rgb  = BRDF * lightColor * shadow * atten / M_PI;

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

@@ -1,9 +1,9 @@
 #include "Uniforms.hlsl"
 #include "Uniforms.hlsl"
 #include "Samplers.hlsl"
 #include "Samplers.hlsl"
+#include "Constants.hlsl"
 #include "Transform.hlsl"
 #include "Transform.hlsl"
 #include "ScreenPos.hlsl"
 #include "ScreenPos.hlsl"
 #include "Lighting.hlsl"
 #include "Lighting.hlsl"
-#include "Constants.hlsl"
 #include "Fog.hlsl"
 #include "Fog.hlsl"
 #include "PBR.hlsl"
 #include "PBR.hlsl"
 #include "IBL.hlsl"
 #include "IBL.hlsl"
@@ -252,8 +252,15 @@ void PS(
         float3 lightDir;
         float3 lightDir;
         float3 lightColor;
         float3 lightColor;
         float3 finalColor;
         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;
         float shadow = 1.0;
 
 
@@ -275,7 +282,7 @@ void PS(
         const float ndl = clamp((dot(normal, lightVec)), M_EPSILON, 1.0);
         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;
         finalColor.rgb = BRDF * lightColor * (atten * shadow) / M_PI;
 
 
         #ifdef AMBIENT
         #ifdef AMBIENT

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

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