summaryrefslogtreecommitdiff
path: root/Runtime/Camera/Light.h
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2019-08-14 22:50:43 +0800
committerchai <chaifix@163.com>2019-08-14 22:50:43 +0800
commit15740faf9fe9fe4be08965098bbf2947e096aeeb (patch)
treea730ec236656cc8cab5b13f088adfaed6bb218fb /Runtime/Camera/Light.h
+Unity Runtime codeHEADmaster
Diffstat (limited to 'Runtime/Camera/Light.h')
-rw-r--r--Runtime/Camera/Light.h254
1 files changed, 254 insertions, 0 deletions
diff --git a/Runtime/Camera/Light.h b/Runtime/Camera/Light.h
new file mode 100644
index 0000000..c14a59c
--- /dev/null
+++ b/Runtime/Camera/Light.h
@@ -0,0 +1,254 @@
+#ifndef LIGHT_H
+#define LIGHT_H
+
+#include "Lighting.h"
+#include "Flare.h"
+#include "ShadowSettings.h"
+#include "Runtime/GameCode/Behaviour.h"
+#include "Runtime/Math/Color.h"
+#include "Runtime/Math/Vector3.h"
+#include "Runtime/Geometry/AABB.h"
+#include "Runtime/GfxDevice/GfxDeviceObjects.h"
+#include "Runtime/GfxDevice/GfxDeviceConfigure.h"
+#include "Runtime/Utilities/LinkedList.h"
+#if UNITY_EDITOR
+#include "Editor/Src/LightmapVisualization.h"
+#endif
+#include "Runtime/Math/Rect.h"
+
+class Texture;
+class GfxDevice;
+
+class Light : public Behaviour, public ListElement
+{
+public:
+
+ REGISTER_DERIVED_CLASS (Light, Behaviour)
+ DECLARE_OBJECT_SERIALIZE (Light)
+
+ Light (MemLabelId label, ObjectCreationMode mode);
+ // ~Light(); declared-by-macro
+
+ static void InitializeClass ();
+ static void CleanupClass ();
+
+ // Tag class as sealed, this makes QueryComponent faster.
+ static bool IsSealedClass () { return true; }
+
+ virtual void Reset ();
+
+ // System interaction
+ virtual void AddToManager ();
+ virtual void RemoveFromManager ();
+ virtual void CheckConsistency ();
+ virtual void AwakeFromLoad(AwakeFromLoadMode mode);
+
+ void TransformChanged ();
+
+
+ LightType GetType() const { return static_cast<LightType>( m_Type ); }
+ void SetType (LightType type);
+
+
+ /// How to render this light.
+ enum RenderMode
+ {
+ kRenderAuto, ///< Automatic
+ kRenderImportant, ///< This light is important
+ kRenderNotImportant, ///< This light is not very important
+ kRenderModeCount // keep this last!
+ };
+ /// Get the render mode hint for this light
+ int GetRenderMode() const { return m_RenderMode; }
+ void SetRenderMode (int mode) { m_RenderMode = mode; SetDirty(); m_GfxLightValid = false; }
+
+ enum Lightmapping
+ {
+ kLightmappingRealtimeOnly = 0, // light is not baked, realtime only
+ kLightmappingAuto = 1, // light is baked in the dual lightmap style
+ kLightmappingBakedOnly = 2 // light is fully baked, not rendering in realtime at all
+ };
+
+ void SetLightmapping (int mode) { m_Lightmapping = mode; SetDirty(); m_GfxLightValid = false; }
+ inline Lightmapping GetLightmappingForRender() const;
+ Lightmapping GetLightmappingForBake() const;
+
+ void SetActuallyLightmapped (bool v);
+ bool GetActuallyLightmapped() const { return m_ActuallyLightmapped; }
+
+ /// Get the full range of the light.
+ float GetRange() const { return m_Range; }
+ void SetRange (float range) { m_Range = std::max(0.0F, range); SetDirty (); m_GfxLightValid = false; Precalc (); }
+
+ /// Get the spot angle in degrees.
+ float GetSpotAngle() const { return m_SpotAngle; }
+ void SetSpotAngle (float angle) { m_SpotAngle = angle; CheckConsistency(); SetDirty (); m_GfxLightValid = false; Precalc (); }
+
+ float GetCookieSize() const { return m_CookieSize; }
+ void SetCookieSize (float size) { m_CookieSize = size; CheckConsistency(); SetDirty (); m_GfxLightValid = false; Precalc (); }
+
+ // range * this value = end side length
+ float GetCotanHalfSpotAngle () const { return m_CotanHalfSpotAngle; }
+ // range * this value = diagonal side length
+ float GetInvCosHalfSpotAngle () const { return m_InvCosHalfSpotAngle; }
+
+ /// Get/set the cookie used for the light
+ void SetCookie (Texture *tex);
+ Texture *GetCookie () const { return m_Cookie; }
+
+ /// Get/set the lens flare used
+ void SetFlare (Flare *flare);
+ Flare *GetFlare () { return m_Flare; }
+
+ const ColorRGBAf& GetColor () const { return m_Color; }
+ void SetColor (const ColorRGBAf& c);
+ ColorRGBAf GetConvertedFinalColor() const { return m_ConvertedFinalColor; }
+
+ float GetIntensity() const { return m_Intensity; }
+ void SetIntensity( float i );
+
+ float GetShadowStrength() const { return m_Shadows.m_Strength; }
+ void SetShadowStrength( float f ) { m_Shadows.m_Strength = f; SetDirty(); }
+ ShadowType GetShadows() const { return static_cast<ShadowType>(m_Shadows.m_Type); }
+ void SetShadows( int v );
+ int GetShadowResolution() const { return m_Shadows.m_Resolution; }
+ void SetShadowResolution( int v ) { m_Shadows.m_Resolution = v; SetDirty(); }
+ float GetShadowBias() const { return m_Shadows.m_Bias; }
+ void SetShadowBias( float v ) { m_Shadows.m_Bias = v; SetDirty(); }
+ float GetShadowSoftness() const { return m_Shadows.m_Softness; }
+ void SetShadowSoftness (float v) { m_Shadows.m_Softness = v; SetDirty(); }
+ float GetShadowSoftnessFade() const { return m_Shadows.m_SoftnessFade; }
+ void SetShadowSoftnessFade (float v) { m_Shadows.m_SoftnessFade = v; SetDirty(); }
+
+ int GetFinalShadowResolution() const;
+
+ #if UNITY_EDITOR
+ int GetShadowSamples() const { return m_ShadowSamples; }
+ void SetShadowSamples (int samples) { m_ShadowSamples = samples; }
+ float GetShadowRadius() const { return m_ShadowRadius; }
+ void SetShadowRadius (float radius) { m_ShadowRadius = radius; }
+ float GetShadowAngle() const { return m_ShadowAngle; }
+ void SetShadowAngle (float angle) { m_ShadowAngle = angle; }
+ float GetIndirectIntensity() const { return m_IndirectIntensity; }
+ void SetIndirectIntensity (float intensity) { m_IndirectIntensity = intensity; }
+ Vector2f GetAreaSize() const { return m_AreaSize; }
+ void SetAreaSize(const Vector2f& areaSize) { m_AreaSize = areaSize; }
+ #endif
+
+ /// Calculate the quadratic attenuation factor for a light with a specified range
+ /// @param range the range of the light
+ /// @return the quadratic attenuation factor
+ static float CalcQuadFac (float range);
+
+ // Attenuation function: inverse quadratic. distSqr is over 0..1 range
+ static float AttenuateNormalized(float distSqr);
+
+ // Get the result of attenuation for a squared distance from the light
+ float AttenuateApprox (float sqrDist) const;
+
+ // Set up this light as GfxDevice fixed function per-vertex light.
+ // IMPORTANT: Assumes the modelview matrix has been set up to be the world2camera matrix.
+ void SetupVertexLight (int lightNo, float visibilityFade);
+
+ void SetLightKeyword();
+ void SetPropsToShaderLab (float blend) const;
+
+
+ // Set up the halo for the light.
+ void SetupHalo ();
+ // Set up the flare for the light.
+ void SetupFlare ();
+
+ void SetCullingMask (int mask) { m_CullingMask.m_Bits = mask; SetDirty(); }
+ int GetCullingMask () const { return m_CullingMask.m_Bits; }
+
+ // Precalc all non-changing shaderlab values.
+ void Precalc ();
+
+ const Vector3f& GetWorldPosition() const { return m_WorldPosition; }
+ const Matrix4x4f& GetWorldToLocalMatrix() const { return m_World2Local; }
+
+ enum AttenuationMode
+ {
+ kSpotCookie, // 2D cookie projected in spot light's cone
+ kPointFalloff, // Attenuation for a point light
+ kDirectionalCookie, // Cookie projected from a directional light
+ kUnused // The attenuation texture is not used
+ };
+ void GetMatrix (const Matrix4x4f* __restrict object2light, Matrix4x4f* __restrict outMatrix) const;
+
+ bool IsValidToRender() const;
+
+private:
+ void UpdateSpotAngleValues ()
+ {
+ float halfSpotRad = Deg2Rad(m_SpotAngle * 0.5f);
+ float cs = cosf(halfSpotRad);
+ float ss = sinf(halfSpotRad);
+ m_CotanHalfSpotAngle = cs / ss;
+ m_InvCosHalfSpotAngle = 1.0f / cs;
+ }
+
+ void ComputeGfxLight (GfxVertexLight& gfxLight) const;
+
+private:
+ Matrix4x4f m_World2Local;
+ Vector3f m_WorldPosition;
+ ShadowSettings m_Shadows; ///< Shadow settings.
+
+ ColorRGBAf m_Color;
+ ColorRGBAf m_ConvertedFinalColor;
+
+ PPtr<Flare> m_Flare; ///< Does the light have a flare?
+ PPtr<Texture> m_Cookie; ///< Custom cookie (optional).
+ BitField m_CullingMask; ///< The mask used for selectively lighting objects in the scene.
+ float m_Intensity; ///< Light intensity range {0.0, 8.0}
+ float m_Range; ///< Light range
+ float m_SpotAngle; ///< Angle of the spotlight cone.
+ float m_CookieSize; ///< Cookie size for directional lights.
+ float m_CotanHalfSpotAngle; // cotangent of half of the spot angle
+ float m_InvCosHalfSpotAngle; // 1/cos of half of the spot angle
+ int m_RenderMode; ///< enum { Auto, Important, Not Important } Rendering mode for the light.
+ int m_Lightmapping; ///< enum { RealtimeOnly, Auto, BakedOnly } Is light baked into lightmaps?
+ int m_Type; ///< enum { Spot, Directional, Point, Area (baked only) } Light type
+ bool m_DrawHalo; ///< Does the light have a halo?
+ bool m_ActuallyLightmapped; // Is it actually lightmapped already?
+ #if UNITY_EDITOR
+ int m_ShadowSamples; // number of samples for lightmapper shadow calculations
+ float m_ShadowRadius; // radius of the light source for lightmapper shadow calculations (point and spot lights)
+ float m_ShadowAngle; // angle of the cone for lightmapper shadow rays (directional lights)
+ float m_IndirectIntensity; // aka bounce intensity - a multiplier for the indirect light
+ Vector2f m_AreaSize; // size of area light's rectangle
+ #endif
+
+ PPtr<Texture> m_AttenuationTexture;
+ AttenuationMode m_AttenuationMode;
+ LightKeywordMode m_KeywordMode; // The current keyword used by the light
+
+ int m_HaloHandle, m_FlareHandle;
+
+ GfxVertexLight m_CachedGfxLight;
+ bool m_GfxLightValid;
+};
+
+void SetupVertexLights(const std::vector<Light*>& lights);
+void SetLightScissorRect (const Rectf& lightRect, const Rectf& viewPort, bool intoRT, GfxDevice& device);
+void ClearScissorRect (bool oldScissor, const int oldRect[4], GfxDevice& device);
+
+
+// Inline this; called a lot in light culling.
+inline Light::Lightmapping Light::GetLightmappingForRender() const
+{
+ if (m_Type == kLightArea)
+ return kLightmappingBakedOnly;
+
+ // all lights behave as realtime only if no lightmaps have been baked yet or if lightmaps are disabled
+ return m_ActuallyLightmapped
+ #if UNITY_EDITOR
+ && GetLightmapVisualization().GetUseLightmapsForRendering()
+ #endif
+ ? static_cast<Lightmapping>(m_Lightmapping) : kLightmappingRealtimeOnly;
+}
+
+
+#endif