Explorar o código

Added brightness attribute to Light. Added separate equality test with and without epsilon to Color, similar to Vector2/3/4.

Lasse Öörni %!s(int64=11) %!d(string=hai) anos
pai
achega
094006ef91

+ 1 - 1
Bin/Data/Scripts/NinjaSnowWar/LightFlash.as

@@ -10,7 +10,7 @@ class LightFlash : GameObject
     void FixedUpdate(float timeStep)
     {
         Light@ light = node.GetComponent("Light");
-        light.color = light.color * Max(1.0 - timeStep * 10.0, 0.0);
+        light.brightness = light.brightness * Max(1.0 - timeStep * 10.0, 0.0);
 
         // Call superclass to handle lifetime
         GameObject::FixedUpdate(timeStep);

+ 3 - 2
Source/Engine/Graphics/Batch.cpp

@@ -407,7 +407,7 @@ void Batch::Prepare(View* view, bool setModelTransform) const
                 if (vertexLight->GetLightType() != LIGHT_DIRECTIONAL && fadeEnd > 0.0f && fadeStart > 0.0f && fadeStart < fadeEnd)
                     fade = Min(1.0f - (vertexLight->GetDistance() - fadeStart) / (fadeEnd - fadeStart), 1.0f);
                 
-                Color color = vertexLight->GetColor() * fade;
+                Color color = vertexLight->GetEffectiveColor() * fade;
                 vertexLights[i * 3] = Vector4(color.r_, color.g_, color.b_, invRange);
                 
                 // Direction
@@ -490,7 +490,8 @@ void Batch::Prepare(View* view, bool setModelTransform) const
             fade = Min(1.0f - (light->GetDistance() - fadeStart) / (fadeEnd - fadeStart), 1.0f);
         
         // Negative lights will use subtract blending, so write absolute RGB values to the shader parameter
-        graphics->SetShaderParameter(PSP_LIGHTCOLOR, Color(light->GetColor().Abs(), light->GetSpecularIntensity()) * fade);
+        graphics->SetShaderParameter(PSP_LIGHTCOLOR, Color(light->GetEffectiveColor().Abs(),
+            light->GetEffectiveSpecularIntensity()) * fade);
         graphics->SetShaderParameter(PSP_LIGHTDIR, lightWorldRotation * Vector3::BACK);
         graphics->SetShaderParameter(PSP_LIGHTPOS, Vector4((isLightVolume ? (lightNode->GetWorldPosition() -
             cameraEffectivePos) : lightNode->GetWorldPosition()), atten));

+ 15 - 6
Source/Engine/Graphics/Light.cpp

@@ -43,6 +43,7 @@ static const LightType DEFAULT_LIGHTTYPE = LIGHT_POINT;
 static const float DEFAULT_RANGE = 10.0f;
 static const float DEFAULT_FOV = 30.0f;
 static const float DEFAULT_SPECULARINTENSITY = 1.0f;
+static const float DEFAULT_BRIGHTNESS = 1.0f;
 static const float DEFAULT_CONSTANTBIAS = 0.0001f;
 static const float DEFAULT_SLOPESCALEDBIAS = 0.5f;
 static const float DEFAULT_BIASAUTOADJUST = 1.0f;
@@ -92,6 +93,7 @@ Light::Light(Context* context) :
     shadowFocus_(FocusParameters(true, true, true, DEFAULT_SHADOWQUANTIZE, DEFAULT_SHADOWMINVIEW)),
     lightQueue_(0),
     specularIntensity_(DEFAULT_SPECULARINTENSITY),
+    brightness_(DEFAULT_BRIGHTNESS),
     range_(DEFAULT_RANGE),
     fov_(DEFAULT_FOV),
     aspectRatio_(1.0f),
@@ -116,6 +118,7 @@ void Light::RegisterObject(Context* context)
     ENUM_ACCESSOR_ATTRIBUTE(Light, "Light Type", GetLightType, SetLightType, LightType, typeNames, DEFAULT_LIGHTTYPE, AM_DEFAULT);
     REF_ACCESSOR_ATTRIBUTE(Light, VAR_COLOR, "Color", GetColor, SetColor, Color, Color::WHITE, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Specular Intensity", GetSpecularIntensity, SetSpecularIntensity, float, DEFAULT_SPECULARINTENSITY, AM_DEFAULT);
+    ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Brightness Multiplier", GetBrightness, SetBrightness, float, DEFAULT_BRIGHTNESS, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Range", GetRange, SetRange, float, DEFAULT_RANGE, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Spot FOV", GetFov, SetFov, float, DEFAULT_FOV, AM_DEFAULT);
     ACCESSOR_ATTRIBUTE(Light, VAR_FLOAT, "Spot Aspect Ratio", GetAspectRatio, SetAspectRatio, float, 1.0f, AM_DEFAULT);
@@ -273,6 +276,18 @@ void Light::SetColor(const Color& color)
     MarkNetworkUpdate();
 }
 
+void Light::SetSpecularIntensity(float intensity)
+{
+    specularIntensity_ = Max(intensity, 0.0f);
+    MarkNetworkUpdate();
+}
+
+void Light::SetBrightness(float brightness)
+{
+    brightness_ = brightness;
+    MarkNetworkUpdate();
+}
+
 void Light::SetRange(float range)
 {
     range_ = Max(range, 0.0f);
@@ -300,12 +315,6 @@ void Light::SetShadowNearFarRatio(float nearFarRatio)
     MarkNetworkUpdate();
 }
 
-void Light::SetSpecularIntensity(float intensity)
-{
-    specularIntensity_ = Max(intensity, 0.0f);
-    MarkNetworkUpdate();
-}
-
 void Light::SetFadeDistance(float distance)
 {
     fadeDistance_ = Max(distance, 0.0f);

+ 12 - 2
Source/Engine/Graphics/Light.h

@@ -179,6 +179,8 @@ public:
     void SetColor(const Color& color);
     /// Set specular intensity.
     void SetSpecularIntensity(float intensity);
+    /// Set light brightness multiplier.
+    void SetBrightness(float brightness);
     /// Set range.
     void SetRange(float range);
     /// Set spotlight field of view.
@@ -214,6 +216,12 @@ public:
     const Color& GetColor() const { return color_; }
     /// Return specular intensity.
     float GetSpecularIntensity() const { return specularIntensity_; }
+    /// Return brightness multiplier.
+    float GetBrightness() const { return brightness_; }
+    /// Return effective color, multiplied by brightness. Do not multiply the alpha so that can compare against the default black color to detect a light with no effect.
+    Color GetEffectiveColor() const { return Color(color_ * brightness_, 1.0f); }
+    /// Return effective specular intensity, multiplied by absolute value of brightness.
+    float GetEffectiveSpecularIntensity() const { return specularIntensity_ * Abs(brightness_); }
     /// Return range.
     float GetRange() const { return range_; }
     /// Return spotlight field of view.
@@ -243,7 +251,7 @@ public:
     /// Return spotlight frustum.
     Frustum GetFrustum() const;
     /// Return whether light has negative (darkening) color.
-    bool IsNegative() const { return color_.SumRGB() < 0.0f; }
+    bool IsNegative() const { return GetEffectiveColor().SumRGB() < 0.0f; }
     
     /// Set sort value based on intensity and view distance.
     void SetIntensitySortValue(float distance);
@@ -258,7 +266,7 @@ public:
     /// Return light queue. Called by View.
     LightBatchQueue* GetLightQueue() const { return lightQueue_; }
     /// Return a divisor value based on intensity for calculating the sort value.
-    float GetIntensityDivisor(float attenuation = 1.0f) const { return Max(color_.SumRGB(), 0.0f) * attenuation + M_EPSILON; }
+    float GetIntensityDivisor(float attenuation = 1.0f) const { return Max(GetEffectiveColor().SumRGB(), 0.0f) * attenuation + M_EPSILON; }
     
     /// Set ramp texture attribute.
     void SetRampTextureAttr(ResourceRef value);
@@ -294,6 +302,8 @@ private:
     LightBatchQueue* lightQueue_;
     /// Specular intensity.
     float specularIntensity_;
+    /// Brightness multiplier.
+    float brightness_;
     /// Range.
     float range_;
     /// Spotlight field of view.

+ 3 - 1
Source/Engine/Graphics/View.cpp

@@ -228,7 +228,9 @@ void CheckVisibilityWork(const WorkItem* item, unsigned threadIndex)
             else if (drawable->GetDrawableFlags() & DRAWABLE_LIGHT)
             {
                 Light* light = static_cast<Light*>(drawable);
-                result.lights_.Push(light);
+                // Skip lights with zero brightness or black color
+                if (!light->GetEffectiveColor().Equals(Color::BLACK))
+                    result.lights_.Push(light);
             }
         }
     }

+ 7 - 0
Source/Engine/LuaScript/pkgs/Graphics/Light.pkg

@@ -34,6 +34,7 @@ class Light : public Drawable
     void SetPerVertex(bool enable);
     void SetColor(const Color& color);
     void SetSpecularIntensity(float intensity);
+    void SetBrightness(float brightness);
     void SetRange(float range);
     void SetFov(float fov);
     void SetAspectRatio(float aspectRatio);
@@ -52,6 +53,9 @@ class Light : public Drawable
     bool GetPerVertex() const;
     const Color& GetColor() const;
     float GetSpecularIntensity() const;
+    float GetBrightness() const;
+    Color GetEffectiveColor() const;
+    float GetEffectiveSpecularIntensity() const;
     float GetRange() const;
     float GetFov() const;
     float GetAspectRatio() const;
@@ -72,6 +76,7 @@ class Light : public Drawable
     tolua_property__get_set bool perVertex;
     tolua_property__get_set Color& color;
     tolua_property__get_set float specularIntensity;
+    tolua_property__get_set float brightness;
     tolua_property__get_set float range;
     tolua_property__get_set float fov;
     tolua_property__get_set float aspectRatio;
@@ -87,4 +92,6 @@ class Light : public Drawable
     tolua_property__get_set Texture* shapeTexture;
     tolua_readonly tolua_property__get_set Frustum frustum;
     tolua_readonly tolua_property__is_set bool negative;
+    tolua_readonly tolua_property__get_set Color effectiveColor;
+    tolua_readonly tolua_property__get_set float effectiveSpecularIntensity;
 };

+ 2 - 1
Source/Engine/LuaScript/pkgs/Math/Color.pkg

@@ -41,7 +41,8 @@ class Color
     void Invert(bool invertAlpha = false);
     Color Lerp(const Color& rhs, float t) const;
     Color Abs() const;
-    
+    bool Equals(const Color& rhs) const;
+
     String ToString() const;
     
     float r_ @ r;

+ 2 - 6
Source/Engine/Math/Color.cpp

@@ -235,14 +235,10 @@ float Color::Hue(float min, float max) const
         return 0.0f;
 
     // Calculate and return hue
-    if (Equals(g_, max))
-    {
+    if (Urho3D::Equals(g_, max))
         return (b_ + 2.0f*chroma - r_) / (6.0f * chroma);
-    }
-    else if (Equals(b_, max))
-    {
+    else if (Urho3D::Equals(b_, max))
         return (4.0f * chroma - g_ + r_) / (6.0f * chroma);
-    }
     else
     {
         float r = (g_ - b_) / (6.0f * chroma);

+ 6 - 5
Source/Engine/Math/Color.h

@@ -90,10 +90,10 @@ public:
     {
     }
 
-    /// Test for equality with another color.
-    bool operator == (const Color& rhs) const { return Equals(r_, rhs.r_) && Equals(g_, rhs.g_) && Equals(b_, rhs.b_) && Equals(a_, rhs.a_); }
-    /// Test for inequality with another color.
-    bool operator != (const Color& rhs) const { return !Equals(r_, rhs.r_) || !Equals(g_, rhs.g_) || !Equals(b_, rhs.b_) || !Equals(a_, rhs.a_); }
+    /// Test for equality with another color without epsilon.
+    bool operator == (const Color& rhs) const { return r_ == rhs.r_ && g_ == rhs.g_ && b_ == rhs.b_ && a_ == rhs.a_; }
+    /// Test for inequality with another color without epsilon.
+    bool operator != (const Color& rhs) const { return r_ != rhs.r_ || g_ != rhs.g_ || b_ != rhs.b_ || a_ != rhs.a_; }
     /// Multiply with a scalar.
     Color operator * (float rhs) const { return Color(r_ * rhs, g_ * rhs, b_ * rhs, a_ * rhs); }
     /// Add a color.
@@ -129,7 +129,6 @@ public:
     Vector3 ToVector3() const { return Vector3(r_, g_, b_); }
     /// Return RGBA as a four-dimensional vector.
     Vector4 ToVector4() const { return Vector4(r_, g_, b_, a_); }
-    /// Return RGB values as a Vector3.
 
     /// Return sum of RGB components.
     float SumRGB() const { return r_ + g_ + b_; }
@@ -168,6 +167,8 @@ public:
     Color Lerp(const Color& rhs, float t) const;
     /// Return color with absolute components.
     Color Abs() const { return Color(Urho3D::Abs(r_), Urho3D::Abs(g_), Urho3D::Abs(b_), Urho3D::Abs(a_)); }
+    /// Test for equality with another color with epsilon.
+    bool Equals(const Color& rhs) const { return Urho3D::Equals(r_, rhs.r_) && Urho3D::Equals(g_, rhs.g_) && Urho3D::Equals(b_, rhs.b_) && Urho3D::Equals(a_, rhs.a_); }
     
     /// Return as string.
     String ToString() const;

+ 4 - 0
Source/Engine/Script/GraphicsAPI.cpp

@@ -778,6 +778,8 @@ static void RegisterLight(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Light", "const Color& get_color() const", asMETHOD(Light, GetColor), asCALL_THISCALL);
     engine->RegisterObjectMethod("Light", "void set_specularIntensity(float)", asMETHOD(Light, SetSpecularIntensity), asCALL_THISCALL);
     engine->RegisterObjectMethod("Light", "float get_specularIntensity() const", asMETHOD(Light, GetSpecularIntensity), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Light", "void set_brightness(float)", asMETHOD(Light, SetBrightness), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Light", "float get_brightness() const", asMETHOD(Light, GetBrightness), asCALL_THISCALL);
     engine->RegisterObjectMethod("Light", "void set_range(float)", asMETHOD(Light, SetRange), asCALL_THISCALL);
     engine->RegisterObjectMethod("Light", "float get_range() const", asMETHOD(Light, GetRange), asCALL_THISCALL);
     engine->RegisterObjectMethod("Light", "void set_fov(float)", asMETHOD(Light, SetFov), asCALL_THISCALL);
@@ -806,6 +808,8 @@ static void RegisterLight(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Light", "Texture@+ get_shapeTexture() const", asMETHOD(Light, GetShapeTexture), asCALL_THISCALL);
     engine->RegisterObjectMethod("Light", "Frustum get_frustum() const", asMETHOD(Light, GetFrustum), asCALL_THISCALL);
     engine->RegisterObjectMethod("Light", "bool get_negative() const", asMETHOD(Light, IsNegative), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Light", "Color get_effectiveColor() const", asMETHOD(Light, GetEffectiveColor), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Light", "float get_effectiveSpecularIntensity() const", asMETHOD(Light, GetEffectiveSpecularIntensity), asCALL_THISCALL);
 }
 
 static void RegisterZone(asIScriptEngine* engine)

+ 1 - 0
Source/Engine/Script/MathAPI.cpp

@@ -1145,6 +1145,7 @@ static void RegisterColor(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Color", "void Invert(bool)", asMETHOD(Color, Invert), asCALL_THISCALL);
     engine->RegisterObjectMethod("Color", "Color Lerp(const Color&in, float) const", asMETHOD(Color, Lerp), asCALL_THISCALL);
     engine->RegisterObjectMethod("Color", "Color Abs() const", asMETHOD(Color, Abs), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Color", "bool Equals() const", asMETHOD(Color, Equals), asCALL_THISCALL);
     engine->RegisterObjectMethod("Color", "String ToString() const", asMETHOD(Color, ToString), asCALL_THISCALL);
 
     engine->RegisterObjectProperty("Color", "float r", offsetof(Color, r_));