Explorar el Código

Light radius now depends on intensity (physically correct way)
- Also added a separate mode where user can manually adjust radius (physically incorrect attenuation)

BearishSun hace 10 años
padre
commit
0b88b5cbf6

+ 30 - 66
BansheeEngine/Include/BsCLight.h

@@ -9,7 +9,7 @@ namespace BansheeEngine
 	/**
 	 * @copydoc	LightInternal
 	 *
-	 * Wraps Light as a Component
+	 * Wraps Light as a Component.
 	 */
     class BS_EXPORT CLight : public Component
     {
@@ -20,94 +20,64 @@ namespace BansheeEngine
 
 		virtual ~CLight();
 
-	    /**
-		 * @copydoc	LightInternal::getPosition
-	     */
+	    /** @copydoc LightInternal::getPosition */
 		Vector3 getPosition() const { return mInternal->getPosition(); }
 
-	    /**
-		 * @copydoc	LightInternal::setPosition
-	     */
+	    /** @copydoc LightInternal::setPosition */
 		void setPosition(const Vector3& position) { mInternal->setPosition(position); }
 
-	    /**
-		 * @copydoc	LightInternal::getRotation
-	     */
+	    /** @copydoc LightInternal::getRotation */
 		Quaternion getRotation() const { return mInternal->getRotation(); }
 
-	    /**
-		 * @copydoc	LightInternal::setRotation
-	     */
+	    /** @copydoc LightInternal::setRotation */
 		void setRotation(const Quaternion& rotation) { mInternal->setRotation(rotation); }
 
-	    /**
-		 * @copydoc	LightInternal::getType
-	     */
+	    /** @copydoc LightInternal::getType */
 		LightType getType() const { return mInternal->getType(); }
 
-	    /**
-		 * @copydoc	LightInternal::setType
-	     */
+	    /** @copydoc LightInternal::setType */
 		void setType(LightType type) { mInternal->setType(type); }
 
-	    /**
-		 * @copydoc	LightInternal::getCastsShadow
-	     */
+	    /** @copydoc LightInternal::getCastsShadow */
 		bool getCastsShadow() const { return mInternal->getCastsShadow(); }
 
-	    /**
-		 * @copydoc	LightInternal::setCastsShadow
-	     */
+	    /** @copydoc LightInternal::setCastsShadow  */
 		void setCastsShadow(bool castsShadow) { mInternal->setCastsShadow(castsShadow); }
 
-	    /**
-		 * @copydoc	LightInternal::getColor
-	     */
+	    /** @copydoc LightInternal::getColor */
 		Color getColor() const { return mInternal->getColor(); }
 
-	    /**
-		 * @copydoc	LightInternal::setColor
-	     */
+	    /** @copydoc LightInternal::setColor */
 		void setColor(const Color& color) { mInternal->setColor(color); }
 
-	    /**
-		 * @copydoc	LightInternal::getRange
-	     */
+	    /** @copydoc LightInternal::getRange */
 		float getRange() const { return mInternal->getRange(); }
 
-	    /**
-		 * @copydoc	LightInternal::setRange
-	     */
+	    /** @copydoc LightInternal::setRange */
 		void setRange(float range) { mInternal->setRange(range);; }
 
-	    /**
-		 * @copydoc	LightInternal::getIntensity
-	     */
+	    /** @copydoc LightInternal::getIntensity */
 		float getIntensity() const { return mInternal->getIntensity(); }
 
-	    /**
-		 * @copydoc	LightInternal::setIntensity
-	     */
+	    /** @copydoc LightInternal::setIntensity */
 		void setIntensity(float intensity) { mInternal->setIntensity(intensity); }
 
-	    /**
-		 * @copydoc	LightInternal::getSpotAngle
-	     */
+	    /** @copydoc LightInternal::getSpotAngle */
 		Degree getSpotAngle() const { return mInternal->getSpotAngle(); }
 
-	    /**
-		 * @copydoc	LightInternal::setSpotAngle
-	     */
+	    /** @copydoc LightInternal::setSpotAngle */
 		void setSpotAngle(const Degree& spotAngle) { mInternal->setSpotAngle(spotAngle); }
 
-	    /**
-		 * @copydoc	LightInternal::getBounds
-	     */
+		/** @copydoc LightInternal::getPhysicallyBasedAttenuation  */
+		bool getPhysicallyBasedAttenuation() const { return mInternal->getPhysicallyBasedAttenuation(); }
+
+		/**  @copydoc LightInternal::setPhysicallyBasedAttenuation  */
+		void setPhysicallyBasedAttenuation(bool enabled) { mInternal->setPhysicallyBasedAttenuation(enabled); }
+
+	    /** @copydoc LightInternal::getBounds  */
 		Sphere getBounds() const;
 
-	    /**
-		 * @brief	Returns the light that this component wraps.
-	     */
+	    /**	Returns the light that this component wraps. */
 		SPtr<Light> _getLight() const { return mInternal; }
 
     protected:
@@ -128,20 +98,14 @@ namespace BansheeEngine
 	protected:
 		friend class SceneObject;
 
-	    /**
-		 * @copydoc	Component::onInitialized
-	     */
+	    /** @copydoc Component::onInitialized */
 		void onInitialized() override;
 
-	    /**
-		 * @copydoc	Component::onDestroyed
-	     */
+	    /** @copydoc Component::onDestroyed */
 		void onDestroyed() override;
 
-		/**
-		 * @copydoc	Component::update
-		 */
-		virtual void update() override { }
+		/** @copydoc Component::update */
+		void update() override { }
 
 		/************************************************************************/
 		/* 								RTTI		                     		*/
@@ -149,7 +113,7 @@ namespace BansheeEngine
 	public:
 		friend class CLightRTTI;
 		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const override;
+		RTTITypeBase* getRTTI() const override;
 
 	protected:
 		CLight() {} // Serialization only

+ 22 - 3
BansheeEngine/Include/BsLight.h

@@ -71,11 +71,26 @@ namespace BansheeEngine
 		float getRange() const { return mRange; }
 
 		/**
-		 * Returns the maximum range of the light. Light will not affect any geometry past that point.
+		 * Sets the maximum range of the light. Light will not affect any geometry past that point. Value is ignored if
+		 * physically based attenuation is active.
 		 *
 		 * @note	Normally you want to set this at a point where light intensity is too low due to attenuation.
 		 */
-		void setRange(float range) { mRange = range; _markCoreDirty(); updateBounds(); }
+		void setRange(float range);
+
+		/** 
+		 * Checks is physically based attenuation active. If true the range and attenuation of the light are controlled
+		 * by inverse square of distance. If false then the user is allowed to set the range and attenuation is adjusted
+		 * accordingly. 
+		 */
+		bool getPhysicallyBasedAttenuation() const { return mPhysCorrectAtten; }
+
+		/** 
+		 * Activates or deactivates physically based attenuation. If true the range and attenuation of the light are 
+		 * controlled by inverse square of distance. If false then the user is allowed to set the range and attenuation is 
+		 * adjusted accordingly. 
+		 */
+		void setPhysicallyBasedAttenuation(bool enabled);
 
 		/**
 		 * Gets the power of the light source. This is luminous flux for point & spot lights, and radiance for directional 
@@ -87,7 +102,7 @@ namespace BansheeEngine
 		 * Sets the power of the light source. This will be luminous flux for point & spot lights, and radiance for 
 		 * directional lights.
 		 */
-		void setIntensity(float intensity) { mIntensity = intensity; _markCoreDirty(); }
+		void setIntensity(float intensity);
 
 		/**	Gets the total angle covered by a spot light. */
 		Degree getSpotAngle() const { return mSpotAngle; }
@@ -133,6 +148,9 @@ namespace BansheeEngine
 		/** Updates the internal bounds for the light. Call this whenever a property affecting the bounds changes. */
 		void updateBounds();
 
+		/** Calculates maximum light range based on light intensity. */
+		void updatePhysicallyCorrectRange();
+
 		Vector3 mPosition; /**< World space position. */
 		Quaternion mRotation; /**< World space rotation. */
 
@@ -145,6 +163,7 @@ namespace BansheeEngine
 		Degree mSpotFalloffAngle; /**< Spot light angle at which falloff starts. Must be smaller than total angle. */
 		bool mIsActive; /**< Whether the light should be rendered or not. */
 		Sphere mBounds; /**< Sphere that bounds the light area of influence. */
+		bool mPhysCorrectAtten; /**< Determines is physically based attentuation active. */
 	};
 
 	/**

+ 4 - 0
BansheeEngine/Include/BsLightRTTI.h

@@ -35,6 +35,9 @@ namespace BansheeEngine
 
 		Degree& getSpotFalloffAngle(Light* obj) { return obj->mSpotFalloffAngle; }
 		void setSpotFalloffAngle(Light* obj, Degree& spotAngle) { obj->mSpotFalloffAngle = spotAngle; }
+
+		bool& getPhysCorrectAtten(Light* obj) { return obj->mPhysCorrectAtten; }
+		void setPhysCorrectAtten(Light* obj, bool& value) { obj->mPhysCorrectAtten = value; }
 	public:
 		LightRTTI()
 		{
@@ -47,6 +50,7 @@ namespace BansheeEngine
 			addPlainField("mIntensity", 6, &LightRTTI::getIntensity, &LightRTTI::setIntensity);
 			addPlainField("mSpotAngle", 7, &LightRTTI::getSpotAngle, &LightRTTI::setSpotAngle);
 			addPlainField("mSpotFalloffAngle", 8, &LightRTTI::getSpotFalloffAngle, &LightRTTI::setSpotFalloffAngle);
+			addPlainField("mPhysCorrectAtten", 9, &LightRTTI::getPhysCorrectAtten, &LightRTTI::setPhysCorrectAtten);
 		}
 
 		virtual void onDeserializationEnded(IReflectable* obj) override

+ 50 - 7
BansheeEngine/Source/BsLight.cpp

@@ -25,7 +25,7 @@ namespace BansheeEngine
 				UINT32 numVertices = 0;
 				UINT32 numIndices = 0;
 
-				ShapeMeshes3D::getNumElementsSphere(1, numVertices, numIndices);
+				ShapeMeshes3D::getNumElementsSphere(3, numVertices, numIndices);
 				MeshDataPtr meshData = bs_shared_ptr_new<MeshData>(numVertices, numIndices, vertexDesc);
 
 				UINT32* indexData = meshData->getIndices32();
@@ -33,7 +33,7 @@ namespace BansheeEngine
 
 				Sphere localSphere(Vector3::ZERO, 1.0f);
 				ShapeMeshes3D::solidSphere(localSphere, positionData, nullptr, 0,
-					vertexDesc->getVertexStride(), indexData, 0, 1);
+					vertexDesc->getVertexStride(), indexData, 0, 3);
 
 				sPointLightMesh = MeshCore::create(meshData);
 			}
@@ -116,17 +116,48 @@ namespace BansheeEngine
 
 	LightBase::LightBase()
 		:mType(LightType::Point), mCastsShadows(false), mRange(10.0f),
-		mIntensity(5.0f), mSpotAngle(45), mSpotFalloffAngle(35.0f), mColor(Color::White), mIsActive(true)
+		mIntensity(5.0f), mSpotAngle(45), mSpotFalloffAngle(35.0f), mColor(Color::White), 
+		mIsActive(true), mPhysCorrectAtten(true)
 	{
-		mBounds = Sphere(mPosition, mRange);
+		updatePhysicallyCorrectRange();
 	}
 
 	LightBase::LightBase(LightType type, Color color,
 		float intensity, float range, bool castsShadows, Degree spotAngle, Degree spotFalloffAngle)
 		:mType(type), mCastsShadows(castsShadows), mRange(range), mSpotFalloffAngle(spotFalloffAngle),
-		mIntensity(intensity), mSpotAngle(spotAngle), mColor(color), mIsActive(true)
+		mIntensity(intensity), mSpotAngle(spotAngle), mColor(color), mIsActive(true), mPhysCorrectAtten(true)
 	{
-		mBounds = Sphere(mPosition, mRange);
+		updatePhysicallyCorrectRange();
+	}
+
+	void LightBase::setPhysicallyBasedAttenuation(bool enabled)
+	{
+		mPhysCorrectAtten = enabled; 
+
+		if(enabled)
+			updatePhysicallyCorrectRange();
+
+		_markCoreDirty();
+	}
+
+	void LightBase::setRange(float range)
+	{
+		if (mPhysCorrectAtten)
+			return;
+
+		mRange = range; 
+		_markCoreDirty(); 
+		updateBounds();
+	}
+
+	void LightBase::setIntensity(float intensity)
+	{
+		mIntensity = intensity; 
+
+		if (mPhysCorrectAtten)
+			updatePhysicallyCorrectRange();
+
+		_markCoreDirty(); 
 	}
 
 	float LightBase::getRadiance() const
@@ -147,6 +178,15 @@ namespace BansheeEngine
 		return mIntensity;
 	}
 
+	void LightBase::updatePhysicallyCorrectRange()
+	{
+		// When lower than this attenuation light influence is assumed to be zero
+		const float minAttenuation = 0.05f;
+		mRange = sqrt(mIntensity / minAttenuation - 1.0f);
+
+		updateBounds();
+	}
+
 	void LightBase::updateBounds()
 	{
 		switch (mType)
@@ -219,6 +259,7 @@ namespace BansheeEngine
 		dataPtr = rttiReadElem(mIntensity, dataPtr);
 		dataPtr = rttiReadElem(mSpotAngle, dataPtr);
 		dataPtr = rttiReadElem(mSpotFalloffAngle, dataPtr);
+		dataPtr = rttiReadElem(mPhysCorrectAtten, dataPtr);
 		dataPtr = rttiReadElem(mIsActive, dataPtr);
 		dataPtr = rttiReadElem(dirtyFlags, dataPtr);
 		dataPtr = rttiReadElem(mBounds, dataPtr);
@@ -333,8 +374,9 @@ namespace BansheeEngine
 		size += rttiGetElemSize(mRange);
 		size += rttiGetElemSize(mIntensity);
 		size += rttiGetElemSize(mSpotAngle);
-		size += rttiGetElemSize(mIsActive);
 		size += rttiGetElemSize(mSpotFalloffAngle);
+		size += rttiGetElemSize(mPhysCorrectAtten);
+		size += rttiGetElemSize(mIsActive);
 		size += rttiGetElemSize(getCoreDirtyFlags());
 		size += rttiGetElemSize(mBounds);
 
@@ -350,6 +392,7 @@ namespace BansheeEngine
 		dataPtr = rttiWriteElem(mIntensity, dataPtr);
 		dataPtr = rttiWriteElem(mSpotAngle, dataPtr);
 		dataPtr = rttiWriteElem(mSpotFalloffAngle, dataPtr);
+		dataPtr = rttiWriteElem(mPhysCorrectAtten, dataPtr);
 		dataPtr = rttiWriteElem(mIsActive, dataPtr);
 		dataPtr = rttiWriteElem(getCoreDirtyFlags(), dataPtr);
 		dataPtr = rttiWriteElem(mBounds, dataPtr);

+ 24 - 11
MBansheeEditor/Inspectors/LightInspector.cs

@@ -15,6 +15,7 @@ namespace BansheeEditor
         private GUIFloatField intensityField = new GUIFloatField(new LocEdString("Intensity"));
         private GUISliderField spotAngleField = new GUISliderField(1, 180, new LocEdString("Spot angle"));
         private GUISliderField spotFalloffAngleField = new GUISliderField(1, 180, new LocEdString("Spot falloff angle"));
+        private GUIToggleField physBasedAttenField = new GUIToggleField(new LocEdString("Physically based attenuation"));
         private GUIToggleField castShadowField = new GUIToggleField(new LocEdString("Cast shadow"));
 
         private InspectableState modifyState;
@@ -30,7 +31,7 @@ namespace BansheeEditor
                 {
                     light.Type = (LightType)x;
 
-                    ToggleTypeSpecificFields((LightType) x);
+                    ToggleTypeSpecificFields((LightType) x, light.PhysicallyBasedAttenuation);
                 };
 
                 colorField.OnChanged += x =>
@@ -60,16 +61,25 @@ namespace BansheeEditor
                     MarkAsModified();
                     ConfirmModify();
                 };
-                
+
+                physBasedAttenField.OnChanged += x =>
+                {
+                    light.PhysicallyBasedAttenuation = x;
+                    ToggleTypeSpecificFields(light.Type, x);
+                    MarkAsModified();
+                    ConfirmModify();
+                };
+
                 Layout.AddElement(lightTypeField);
                 Layout.AddElement(colorField);
                 Layout.AddElement(intensityField);
                 Layout.AddElement(rangeField);
                 Layout.AddElement(spotAngleField);
                 Layout.AddElement(spotFalloffAngleField);
+                Layout.AddElement(physBasedAttenField);
                 Layout.AddElement(castShadowField);
 
-                ToggleTypeSpecificFields(light.Type);
+                ToggleTypeSpecificFields(light.Type, light.PhysicallyBasedAttenuation);
             }
         }
 
@@ -81,17 +91,16 @@ namespace BansheeEditor
                 return InspectableState.NotModified;
 
             LightType lightType = light.Type;
-            if (lightTypeField.Value != (ulong)lightType)
-            {
-                lightTypeField.Value = (ulong)lightType;
-                ToggleTypeSpecificFields(lightType);
-            }
+            if (lightTypeField.Value != (ulong)lightType || physBasedAttenField.Value != light.PhysicallyBasedAttenuation)
+                ToggleTypeSpecificFields(lightType, light.PhysicallyBasedAttenuation);
 
+            lightTypeField.Value = (ulong)lightType;
             colorField.Value = light.Color;
             intensityField.Value = light.Intensity;
             rangeField.Value = light.Range;
             spotAngleField.Value = light.SpotAngle.Degrees;
             spotFalloffAngleField.Value = light.SpotFalloffAngle.Degrees;
+            physBasedAttenField.Value = light.PhysicallyBasedAttenuation;
             castShadowField.Value = light.CastsShadow;
 
             InspectableState oldState = modifyState;
@@ -105,25 +114,29 @@ namespace BansheeEditor
         /// Enables or disables different GUI elements depending on the light type.
         /// </summary>
         /// <param name="type">Light type to show GUI elements for.</param>
-        private void ToggleTypeSpecificFields(LightType type)
+        /// <param name="physBasedAttenuation">Determines is physically based attenuation enabled.</param>
+        private void ToggleTypeSpecificFields(LightType type, bool physBasedAttenuation)
         {
             if (type == LightType.Directional)
             {
                 rangeField.Active = false;
                 spotAngleField.Active = false;
                 spotFalloffAngleField.Active = false;
+                physBasedAttenField.Active = false;
             }
             else if (type == LightType.Point)
             {
-                rangeField.Active = true;
+                rangeField.Active = !physBasedAttenuation;
                 spotAngleField.Active = false;
                 spotFalloffAngleField.Active = false;
+                physBasedAttenField.Active = true;
             }
             else
             {
-                rangeField.Active = true;
+                rangeField.Active = !physBasedAttenuation;
                 spotAngleField.Active = true;
                 spotFalloffAngleField.Active = true;
+                physBasedAttenField.Active = true;
             }
         }
 

+ 15 - 1
MBansheeEngine/Light.cs

@@ -38,7 +38,8 @@
         }
 
         /// <summary>
-        /// Maximum range of the light. Light will not affect any geometry past that point.
+        /// Maximum range of the light. Light will not affect any geometry past that point. Range is automatically 
+        /// calculated from intensity if <see cref="PhysicallyBasedAttenuation"/> is turned on.
         /// </summary>
         public float Range
         {
@@ -74,6 +75,17 @@
             set { _nativeLight.SpotFalloffAngle = value; serializableData.spotFalloffAngle = value; }
         }
 
+        /// <summary>
+        /// Determines is the light attenuation handled in a physically correct way, or should the user have more artistic
+        /// control over it. If true the range and attenuation of the light are controlled by inverse square of distance. 
+        /// If false then the user is allowed to set the range and attenuation is adjusted accordingly. 
+        /// </summary>
+        public bool PhysicallyBasedAttenuation
+        {
+            get { return _nativeLight.PhysicallyBasedAttenuation; }
+            set { _nativeLight.PhysicallyBasedAttenuation = value; serializableData.physicallyBasedAttenuation = value; }
+        }
+
         /// <summary>
         /// Determines does this light cast a shadow when rendered.
         /// </summary>
@@ -106,6 +118,7 @@
             _nativeLight.Intensity = serializableData.intensity;
             _nativeLight.Type = serializableData.type;
             _nativeLight.CastsShadow = serializableData.castShadows;
+            _nativeLight.PhysicallyBasedAttenuation = serializableData.physicallyBasedAttenuation;
         }
 
         private void OnUpdate()
@@ -142,6 +155,7 @@
             public float intensity = 5.0f;
             public LightType type = LightType.Point;
             public bool castShadows = false;
+            public bool physicallyBasedAttenuation = true;
         }
     }
 }

+ 10 - 0
MBansheeEngine/NativeLight.cs

@@ -64,6 +64,12 @@ namespace BansheeEngine
             set { Internal_SetCastsShadow(mCachedPtr, value); }
         }
 
+        internal bool PhysicallyBasedAttenuation
+        {
+            get { return Internal_GetPhysicallyBasedAttenuation(mCachedPtr); }
+            set { Internal_SetPhysicallyBasedAttenuation(mCachedPtr, value); }
+        }
+
         internal Sphere Bounds
         {
             get
@@ -118,6 +124,10 @@ namespace BansheeEngine
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_SetCastsShadow(IntPtr instance, bool value);
         [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_GetPhysicallyBasedAttenuation(IntPtr instance);
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetPhysicallyBasedAttenuation(IntPtr instance, bool value);
+        [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern float Internal_GetSpotAngle(IntPtr instance);
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_SetSpotAngle(IntPtr instance, float value);

+ 1 - 1
RenderBeast/Include/BsLightRendering.h

@@ -9,7 +9,7 @@ namespace BansheeEngine
 	BS_PARAM_BLOCK_BEGIN(PerLightParamBuffer)
 		BS_PARAM_BLOCK_ENTRY(Vector4, gLightPositionAndType)
 		BS_PARAM_BLOCK_ENTRY(Vector4, gLightColorAndIntensity)
-		BS_PARAM_BLOCK_ENTRY(Vector3, gLightSpotAngles)
+		BS_PARAM_BLOCK_ENTRY(Vector4, gLightSpotAnglesAndSqrdInvRadius)
 		BS_PARAM_BLOCK_ENTRY(Vector3, gLightDirection)
 		BS_PARAM_BLOCK_ENTRY(Vector4, gLightGeometry)
 		BS_PARAM_BLOCK_ENTRY(Matrix4, gMatConeTransform)

+ 6 - 5
RenderBeast/Source/BsLightRendering.cpp

@@ -41,12 +41,13 @@ namespace BansheeEngine
 		Radian spotAngle = Math::clamp(light->getSpotAngle() * 0.5f, Degree(1), Degree(90));
 		Radian spotFalloffAngle = Math::clamp(light->getSpotFalloffAngle() * 0.5f, Degree(1), (Degree)spotAngle);
 
-		Vector3 spotAngles;
-		spotAngles.x = spotAngle.valueRadians();
-		spotAngles.y = Math::cos(spotAngles.x);
-		spotAngles.z = 1.0f / (Math::cos(spotFalloffAngle) - spotAngles.y);
+		Vector4 spotAnglesAndInvSqrdRadius;
+		spotAnglesAndInvSqrdRadius.x = spotAngle.valueRadians();
+		spotAnglesAndInvSqrdRadius.y = Math::cos(spotAnglesAndInvSqrdRadius.x);
+		spotAnglesAndInvSqrdRadius.z = 1.0f / (Math::cos(spotFalloffAngle) - spotAnglesAndInvSqrdRadius.y);
+		spotAnglesAndInvSqrdRadius.w = 1.0f / (light->getBounds().getRadius() * light->getBounds().getRadius());
 
-		mBuffer.gLightSpotAngles.set(spotAngles);
+		mBuffer.gLightSpotAnglesAndSqrdInvRadius.set(spotAnglesAndInvSqrdRadius);
 
 		mBuffer.gLightDirection.set(-light->getRotation().zAxis());
 

+ 3 - 0
SBansheeEngine/Include/BsScriptLight.h

@@ -49,6 +49,9 @@ namespace BansheeEngine
 		static bool internal_getCastsShadow(ScriptLight* thisPtr);
 		static void internal_setCastsShadow(ScriptLight* thisPtr, bool castsShadow);
 
+		static bool internal_getPhysicallyBasedAttenuation(ScriptLight* thisPtr);
+		static void internal_setPhysicallyBasedAttenuation(ScriptLight* thisPtr, bool value);
+
 		static void internal_getColor(ScriptLight* thisPtr, Color* color);
 		static void internal_setColor(ScriptLight* thisPtr, Color color);
 

+ 14 - 0
SBansheeEngine/Source/BsScriptLight.cpp

@@ -23,6 +23,10 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_SetType", &ScriptLight::internal_setType);
 		metaData.scriptClass->addInternalCall("Internal_GetCastsShadow", &ScriptLight::internal_getCastsShadow);
 		metaData.scriptClass->addInternalCall("Internal_SetCastsShadow", &ScriptLight::internal_setCastsShadow);
+		metaData.scriptClass->addInternalCall("Internal_GetPhysicallyBasedAttenuation", 
+			&ScriptLight::internal_getPhysicallyBasedAttenuation);
+		metaData.scriptClass->addInternalCall("Internal_SetPhysicallyBasedAttenuation", 
+			&ScriptLight::internal_setPhysicallyBasedAttenuation);
 		metaData.scriptClass->addInternalCall("Internal_GetColor", &ScriptLight::internal_getColor);
 		metaData.scriptClass->addInternalCall("Internal_SetColor", &ScriptLight::internal_setColor);
 		metaData.scriptClass->addInternalCall("Internal_GetRange", &ScriptLight::internal_getRange);
@@ -67,6 +71,16 @@ namespace BansheeEngine
 		thisPtr->getInternal()->setCastsShadow(castsShadow);
 	}
 
+	bool ScriptLight::internal_getPhysicallyBasedAttenuation(ScriptLight* thisPtr)
+	{
+		return thisPtr->getInternal()->getPhysicallyBasedAttenuation();
+	}
+
+	void ScriptLight::internal_setPhysicallyBasedAttenuation(ScriptLight* thisPtr, bool value)
+	{
+		thisPtr->getInternal()->setPhysicallyBasedAttenuation(value);
+	}
+
 	void ScriptLight::internal_getColor(ScriptLight* thisPtr, Color* color)
 	{
 		*color = thisPtr->getInternal()->getColor();