| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443 |
- // Copyright (c) 2008-2023 the Urho3D project
- // License: MIT
- /// \file
- #pragma once
- #include "../Graphics/Drawable.h"
- #include "../GraphicsAPI/Texture.h"
- #include "../Math/Color.h"
- #include "../Math/Frustum.h"
- namespace Urho3D
- {
- class Camera;
- struct LightBatchQueue;
- /// %Light types.
- enum LightType
- {
- LIGHT_DIRECTIONAL = 0,
- LIGHT_SPOT,
- LIGHT_POINT
- };
- inline constexpr float SHADOW_MIN_QUANTIZE = 0.1f;
- inline constexpr float SHADOW_MIN_VIEW = 1.0f;
- inline constexpr i32 MAX_LIGHT_SPLITS = 6;
- #ifdef DESKTOP_GRAPHICS
- inline constexpr i32 MAX_CASCADE_SPLITS = 4;
- #else
- inline constexpr i32 MAX_CASCADE_SPLITS = 1;
- #endif
- /// Depth bias parameters. Used both by lights (for shadow mapping) and materials.
- struct URHO3D_API BiasParameters
- {
- /// Construct undefined.
- BiasParameters() = default;
- /// Construct with initial values.
- BiasParameters(float constantBias, float slopeScaledBias, float normalOffset = 0.0f) :
- constantBias_(constantBias),
- slopeScaledBias_(slopeScaledBias),
- normalOffset_(normalOffset)
- {
- }
- /// Validate parameters.
- void Validate();
- /// Constant bias.
- float constantBias_;
- /// Slope scaled bias.
- float slopeScaledBias_;
- /// Normal offset multiplier.
- float normalOffset_;
- };
- /// Cascaded shadow map parameters.
- /// @pod
- struct URHO3D_API CascadeParameters
- {
- /// Construct undefined.
- CascadeParameters() = default;
- /// Construct with initial values.
- CascadeParameters(float split1, float split2, float split3, float split4, float fadeStart, float biasAutoAdjust = 1.0f) :
- fadeStart_(fadeStart),
- biasAutoAdjust_(biasAutoAdjust)
- {
- splits_[0] = split1;
- splits_[1] = split2;
- splits_[2] = split3;
- splits_[3] = split4;
- }
- /// Validate parameters.
- void Validate();
- /// Return shadow maximum range.
- float GetShadowRange() const
- {
- float ret = 0.0f;
- for (unsigned i = 0; i < MAX_CASCADE_SPLITS; ++i)
- ret = Max(ret, splits_[i]);
- return ret;
- }
- /// Far clip values of the splits.
- Vector4 splits_;
- /// The point relative to the total shadow range where shadow fade begins (0.0 - 1.0).
- float fadeStart_{};
- /// Automatic depth bias adjustment strength.
- float biasAutoAdjust_{};
- };
- /// Shadow map focusing parameters.
- /// @pod
- struct URHO3D_API FocusParameters
- {
- /// Construct undefined.
- FocusParameters() = default;
- /// Construct with initial values.
- FocusParameters(bool focus, bool nonUniform, bool autoSize, float quantize, float minView) :
- focus_(focus),
- nonUniform_(nonUniform),
- autoSize_(autoSize),
- quantize_(quantize),
- minView_(minView)
- {
- }
- /// Validate parameters.
- void Validate();
- /// Focus flag.
- bool focus_;
- /// Non-uniform focusing flag.
- bool nonUniform_;
- /// Auto-size (reduce resolution when far away) flag.
- bool autoSize_;
- /// Focus quantization.
- float quantize_;
- /// Minimum view size.
- float minView_;
- };
- /// %Light component.
- class URHO3D_API Light : public Drawable
- {
- URHO3D_OBJECT(Light, Drawable);
- public:
- /// Construct.
- explicit Light(Context* context);
- /// Destruct.
- ~Light() override;
- /// Register object factory. Drawable must be registered first.
- /// @nobind
- static void RegisterObject(Context* context);
- /// Process octree raycast. May be called from a worker thread.
- void ProcessRayQuery(const RayOctreeQuery& query, Vector<RayQueryResult>& results) override;
- /// Calculate distance and prepare batches for rendering. May be called from worker thread(s), possibly re-entrantly.
- void UpdateBatches(const FrameInfo& frame) override;
- /// Visualize the component as debug geometry.
- void DrawDebugGeometry(DebugRenderer* debug, bool depthTest) override;
- /// Set light type.
- /// @property
- void SetLightType(LightType type);
- /// Set vertex lighting mode.
- /// @property
- void SetPerVertex(bool enable);
- /// Set color.
- /// @property
- void SetColor(const Color& color);
- /// Set temperature of the light in Kelvin. Modulates the light color when "use physical values" is enabled.
- /// @property
- void SetTemperature(float temperature);
- /// Set area light radius. Greater than zero activates area light mode. Works only with PBR shaders.
- /// @property
- void SetRadius(float radius);
- /// Set tube area light length. Works only with PBR shaders.
- /// @property
- void SetLength(float length);
- /// Set use physical light values.
- /// @property
- void SetUsePhysicalValues(bool enable);
- /// Set specular intensity. Zero disables specular calculations.
- /// @property
- 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.
- /// @property
- void SetBrightness(float brightness);
- /// Set range.
- /// @property
- void SetRange(float range);
- /// Set spotlight field of view.
- /// @property
- void SetFov(float fov);
- /// Set spotlight aspect ratio.
- /// @property
- void SetAspectRatio(float aspectRatio);
- /// Set fade out start distance.
- /// @property
- void SetFadeDistance(float distance);
- /// Set shadow fade out start distance. Only has effect if shadow distance is also non-zero.
- /// @property
- void SetShadowFadeDistance(float distance);
- /// Set shadow depth bias parameters.
- /// @property
- void SetShadowBias(const BiasParameters& parameters);
- /// Set directional light cascaded shadow parameters.
- /// @property
- void SetShadowCascade(const CascadeParameters& parameters);
- /// Set shadow map focusing parameters.
- /// @property
- void SetShadowFocus(const FocusParameters& parameters);
- /// Set light intensity in shadow between 0.0 - 1.0. 0.0 (the default) gives fully dark shadows.
- /// @property
- void SetShadowIntensity(float intensity);
- /// Set shadow resolution between 0.25 - 1.0. Determines the shadow map to use.
- /// @property
- void SetShadowResolution(float resolution);
- /// Set shadow camera near/far clip distance ratio for spot and point lights. Does not affect directional lights, since they are orthographic and have near clip 0.
- /// @property
- void SetShadowNearFarRatio(float nearFarRatio);
- /// Set maximum shadow extrusion for directional lights. The actual extrusion will be the smaller of this and camera far clip. Default 1000.
- /// @property
- void SetShadowMaxExtrusion(float extrusion);
- /// Set range attenuation texture.
- /// @property
- void SetRampTexture(Texture* texture);
- /// Set spotlight attenuation texture.
- /// @property
- void SetShapeTexture(Texture* texture);
- /// Return light type.
- /// @property
- LightType GetLightType() const { return lightType_; }
- /// Return vertex lighting mode.
- /// @property
- bool GetPerVertex() const { return perVertex_; }
- /// Return color.
- /// @property
- const Color& GetColor() const { return color_; }
- /// Return the temperature of the light in Kelvin.
- /// @property
- float GetTemperature() const { return temperature_; }
- /// Return area light mode radius. Works only with PBR shaders.
- /// @property
- float GetRadius() const { return lightRad_; }
- /// Return area tube light length. Works only with PBR shaders.
- /// @property
- float GetLength() const { return lightLength_; }
- /// Return if light uses temperature and brightness in lumens.
- /// @property
- bool GetUsePhysicalValues() const { return usePhysicalValues_; }
- /// Return the color value of the temperature in Kelvin.
- /// @property
- Color GetColorFromTemperature() const;
- /// Return specular intensity.
- /// @property
- float GetSpecularIntensity() const { return specularIntensity_; }
- /// Return brightness multiplier. Specified in lumens when "use physical values" is enabled.
- /// @property
- float GetBrightness() const { return brightness_; }
- /// Return effective color, multiplied by brightness and affected by temperature when "use physical values" is enabled. Alpha is always 1 so that can compare against the default black color to detect a light with no effect.
- /// @property
- Color GetEffectiveColor() const;
- /// Return effective specular intensity, multiplied by absolute value of brightness.
- /// @property
- float GetEffectiveSpecularIntensity() const { return specularIntensity_ * Abs(brightness_); }
- /// Return range.
- /// @property
- float GetRange() const { return range_; }
- /// Return spotlight field of view.
- /// @property
- float GetFov() const { return fov_; }
- /// Return spotlight aspect ratio.
- /// @property
- float GetAspectRatio() const { return aspectRatio_; }
- /// Return fade start distance.
- /// @property
- float GetFadeDistance() const { return fadeDistance_; }
- /// Return shadow fade start distance.
- /// @property
- float GetShadowFadeDistance() const { return shadowFadeDistance_; }
- /// Return shadow depth bias parameters.
- /// @property
- const BiasParameters& GetShadowBias() const { return shadowBias_; }
- /// Return directional light cascaded shadow parameters.
- /// @property
- const CascadeParameters& GetShadowCascade() const { return shadowCascade_; }
- /// Return shadow map focus parameters.
- /// @property
- const FocusParameters& GetShadowFocus() const { return shadowFocus_; }
- /// Return light intensity in shadow.
- /// @property
- float GetShadowIntensity() const { return shadowIntensity_; }
- /// Return shadow resolution.
- /// @property
- float GetShadowResolution() const { return shadowResolution_; }
- /// Return shadow camera near/far clip distance ratio.
- /// @property
- float GetShadowNearFarRatio() const { return shadowNearFarRatio_; }
- /// Return maximum shadow extrusion distance for directional lights.
- /// @property
- float GetShadowMaxExtrusion() const { return shadowMaxExtrusion_; }
- /// Return range attenuation texture.
- /// @property
- Texture* GetRampTexture() const { return rampTexture_; }
- /// Return spotlight attenuation texture.
- /// @property
- Texture* GetShapeTexture() const { return shapeTexture_; }
- /// Return spotlight frustum.
- /// @property
- Frustum GetFrustum() const;
- /// Return spotlight frustum in the specified view space.
- Frustum GetViewSpaceFrustum(const Matrix3x4& view) const;
- /// Return number of shadow map cascade splits for a directional light, considering also graphics API limitations.
- /// @property
- i32 GetNumShadowSplits() const;
- /// Return whether light has negative (darkening) color.
- /// @property
- bool IsNegative() const { return GetEffectiveColor().SumRGB() < 0.0f; }
- /// Set sort value based on intensity and view distance.
- void SetIntensitySortValue(float distance);
- /// Set sort value based on overall intensity over a bounding box.
- void SetIntensitySortValue(const BoundingBox& box);
- /// Set light queue used for this light. Called by View.
- void SetLightQueue(LightBatchQueue* queue);
- /// Return light volume model transform.
- const Matrix3x4& GetVolumeTransform(Camera* camera);
- /// 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(GetEffectiveColor().SumRGB(), 0.0f) * attenuation + M_EPSILON;
- }
- /// Set ramp texture attribute.
- void SetRampTextureAttr(const ResourceRef& value);
- /// Set shape texture attribute.
- void SetShapeTextureAttr(const ResourceRef& value);
- /// Return ramp texture attribute.
- ResourceRef GetRampTextureAttr() const;
- /// Return shape texture attribute.
- ResourceRef GetShapeTextureAttr() const;
- /// Return a transform for deferred fullscreen quad (directional light) rendering.
- static Matrix3x4 GetFullscreenQuadTransform(Camera* camera);
- protected:
- /// Recalculate the world-space bounding box.
- void OnWorldBoundingBoxUpdate() override;
- private:
- /// Validate shadow focus.
- void ValidateShadowFocus() { shadowFocus_.Validate(); }
- /// Validate shadow cascade.
- void ValidateShadowCascade() { shadowCascade_.Validate(); }
- /// Validate shadow bias.
- void ValidateShadowBias() { shadowBias_.Validate(); }
- /// Light type.
- LightType lightType_;
- /// Color.
- Color color_;
- /// Light temperature.
- float temperature_;
- /// Radius of the light source. If above 0 it will turn the light into an area light. Works only with PBR shaders.
- float lightRad_;
- /// Length of the light source. If above 0 and radius is above 0 it will create a tube light. Works only with PBR shaders.
- float lightLength_;
- /// Shadow depth bias parameters.
- BiasParameters shadowBias_;
- /// Directional light cascaded shadow parameters.
- CascadeParameters shadowCascade_;
- /// Shadow map focus parameters.
- FocusParameters shadowFocus_;
- /// Custom world transform for the light volume.
- Matrix3x4 volumeTransform_;
- /// Range attenuation texture.
- SharedPtr<Texture> rampTexture_;
- /// Spotlight attenuation texture.
- SharedPtr<Texture> shapeTexture_;
- /// Light queue.
- LightBatchQueue* lightQueue_;
- /// Specular intensity.
- float specularIntensity_;
- /// Brightness multiplier.
- float brightness_;
- /// Range.
- float range_;
- /// Spotlight field of view.
- float fov_;
- /// Spotlight aspect ratio.
- float aspectRatio_;
- /// Fade start distance.
- float fadeDistance_;
- /// Shadow fade start distance.
- float shadowFadeDistance_;
- /// Light intensity in shadow.
- float shadowIntensity_;
- /// Shadow resolution.
- float shadowResolution_;
- /// Shadow camera near/far clip distance ratio.
- float shadowNearFarRatio_;
- /// Directional shadow max. extrusion distance.
- float shadowMaxExtrusion_;
- /// Per-vertex lighting flag.
- bool perVertex_;
- /// Use physical light values flag.
- bool usePhysicalValues_;
- };
- inline bool CompareLights(Light* lhs, Light* rhs)
- {
- // When sorting lights, give priority to per-vertex lights, so that vertex lit base pass can be evaluated first
- if (lhs->GetPerVertex() != rhs->GetPerVertex())
- return lhs->GetPerVertex();
- else
- return lhs->GetSortValue() < rhs->GetSortValue();
- }
- }
|