summaryrefslogtreecommitdiff
path: root/Runtime/Camera/Camera.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/Camera.h
+Unity Runtime codeHEADmaster
Diffstat (limited to 'Runtime/Camera/Camera.h')
-rw-r--r--Runtime/Camera/Camera.h503
1 files changed, 503 insertions, 0 deletions
diff --git a/Runtime/Camera/Camera.h b/Runtime/Camera/Camera.h
new file mode 100644
index 0000000..184aa8e
--- /dev/null
+++ b/Runtime/Camera/Camera.h
@@ -0,0 +1,503 @@
+#ifndef CAMERA_H
+#define CAMERA_H
+
+#include "Runtime/GameCode/Behaviour.h"
+#include <vector>
+#include "Runtime/Math/Rect.h"
+#include "Runtime/Math/Color.h"
+#include "Runtime/Geometry/Ray.h"
+#include "Runtime/Graphics/RenderTexture.h" //@TODO remove
+#include "Runtime/Camera/RenderLoops/RenderLoop.h" //@TODO remove
+#include "Runtime/Shaders/Shader.h"
+#include "Runtime/Modules/ExportModules.h"
+
+struct ImageFilter;
+class Cubemap;
+class Plane;
+class IntermediateRenderers;
+class Shader;
+struct RenderLoop;
+struct ShadowCullData;
+struct CullResults;
+struct CullingParameters;
+struct ShaderReplaceData;
+struct SceneCullingParameters;
+struct CameraCullingParameters;
+class Vector2f;
+
+struct DrawGridParameters;
+
+namespace Unity {class Material;}
+namespace Umbra { class DebugRenderer; }
+
+struct CameraRenderOldState
+{
+ void Reset()
+ {
+ subshaderIndex = 0;
+ currentPass = 0;
+ memset (&viewport, 0, sizeof(viewport));
+ memset (&matWorld, 0, sizeof(matWorld));
+ memset (&matView, 0, sizeof(matView));
+ matProj = Matrix4x4f::identity;
+ }
+ PPtr<Material> material;
+ PPtr<Shader> shader;
+ int subshaderIndex;
+ int currentPass;
+
+ int viewport[4];
+ PPtr<Camera> camera;
+ PPtr<RenderTexture> activeRT;
+
+ float matWorld[16];
+ float matView[16];
+ Matrix4x4f matProj;
+};
+
+struct CameraTemporarySettings
+{
+ int renderingPath;
+ float fieldOfView;
+ float aspect;
+ bool implicitAspect;
+};
+
+// The Camera
+class EXPORT_COREMODULE Camera : public Behaviour {
+public:
+ enum SortMode {
+ kSortDefault = 0,
+ kSortPerspective = 1,
+ kSortOrthographic = 2,
+ };
+
+ enum { kNumLayers = 32 };
+
+public:
+ Camera (MemLabelId label, ObjectCreationMode mode);
+ // ~Camera (); declared-by-macro
+ REGISTER_DERIVED_CLASS (Camera, Behaviour)
+ DECLARE_OBJECT_SERIALIZE (Camera)
+
+ // Tag class as sealed, this makes QueryComponent faster.
+ static bool IsSealedClass () { return true; }
+
+ virtual void Reset ();
+ virtual void AwakeFromLoad (AwakeFromLoadMode awakeMode);
+
+ virtual void CheckConsistency ();
+
+ enum RenderFlag {
+ kRenderFlagStandalone = (1<<0),
+ kRenderFlagSetRenderTarget = (1<<1),
+ kRenderFlagPrepareImageFilters = (1<<2),
+ kRenderFlagDontRestoreRenderState = (1<<3),
+ kRenderFlagSetRenderTargetFinal = (1<<4),
+ kRenderFlagExplicitShaderReplace = (1<<5),
+ };
+
+
+ // Set up the viewport, render target, load modelview & projection matrices
+ void SetupRender (int renderFlags = 0); // bitmask of kRenderFlagXXX
+
+ // Cull with default culling parameters
+ void Cull (CullResults& results);
+ void StandaloneCull (Shader* replacementShader, const std::string& replacementTag, CullResults& results);
+
+ // Cull With custom parameters
+ void CustomCull (const CameraCullingParameters& params, CullResults& cullResults);
+
+
+ static void PrepareSceneCullingParameters (const CameraCullingParameters& parameters, RenderingPath renderPath, CullResults& results);
+ void CalculateFrustumPlanes(Plane* frustum, const Matrix4x4f& overrideWorldToClip, float overrideFarPlane, float& outBaseFarDistance, bool implicitNearFar) const;
+ void CalculateCullingParameters(CullingParameters& cullingParameters) const;
+ void CalculateCustomCullingParameters(CullingParameters& cullingParameters, const Plane* planes, int planeCount) const;
+
+
+ // Clear the camera for how its set up - use skybox if neccessary
+ void Clear ();
+ void ClearNoSkybox (bool noDepth);
+ void RenderSkybox ();
+
+ // Set up the camera transform & render
+ void Render (CullResults& cullResults, int renderFlags); // bitmask of kRenderFlagXXX; kRenderFlagPrepareImageFilters always implied
+
+ // Out-of-order cull / rendering.
+ void StandaloneRender (UInt32 renderFlags, Shader* replacementShader, const std::string& replacementTag);
+ void StandaloneSetup ();
+ bool StandaloneRenderToCubemap (RenderTexture* rt, int faceMask);
+ bool StandaloneRenderToCubemap (Cubemap* cubemap, int faceMask);
+
+ void SetFov (float deg);
+ float GetFov () const { return m_FieldOfView; }
+ void SetNear (float n);
+ float GetNear () const { return m_NearClip; }
+ void SetFar (float f);
+ float GetFar () const { return m_FarClip; }
+
+ // Projection's near and far plane (can differ from GetNear/Far() for custom projection matrix)
+ float GetProjectionNear () const;
+ float GetProjectionFar () const;
+
+ void SetHDR (bool enable) { m_HDR = enable; SetDirty(); }
+ bool GetUsingHDR () const { return m_UsingHDR; } // Cached when setting up the render
+ // A recompute is needed if Camera.hdr is called from script before rendering (case 483603)
+ bool CalculateUsingHDR () const;
+
+ void SetRenderingPath (int rp) { m_RenderingPath = rp; SetDirty(); }
+ RenderingPath GetRenderingPath () const { return static_cast<RenderingPath>(m_RenderingPath); }
+
+ void SetOrthographicSize (float f);
+ float GetOrthographicSize () const { return m_OrthographicSize; }
+
+ bool GetOrthographic() const { return m_Orthographic; }
+ void SetOrthographic (bool v);
+
+ void GetTemporarySettings (CameraTemporarySettings& settings) const;
+ void SetTemporarySettings (const CameraTemporarySettings& settings);
+
+ float GetAspect() const { return m_Aspect; }
+ void SetAspect (float aspect);
+ void ResetAspect ();
+
+
+ bool IsValidToRender() const;
+
+ void SetNormalizedViewportRect (const Rectf& normalizedRect);
+ Rectf GetNormalizedViewportRect () const { return m_NormalizedViewPortRect; }
+
+ // The screen view port rect of the camera.
+ // If the cameras normalized viewport rect is set to be the fullscreen, then this will always go from
+ // 0, 0 to width, height.
+ Rectf GetScreenViewportRect () const { return GetCameraRect(true); }
+ // Similar to GetScreenViewportRect, except this can have non-zero origin even for fullscreen cameras.
+ // This only ever happens in editor's game view when using forced aspect ratio or size.
+ Rectf GetPhysicalViewportRect() const { return GetCameraRect(false); }
+
+ void SetScreenViewportRect (const Rectf& pixelRect);
+
+ // Get the final in-rendertarget render rectangle.
+ // This takes into account any render texture setup we may have.
+ Rectf GetRenderRectangle() const;
+
+
+ /// The Camera render order is determined by sorting all cameras by depth.
+ /// Small depth camera are rendered first, big depth cameras last.
+ float GetDepth () const { return m_Depth; }
+ void SetDepth (float depth);
+
+ /// Set the background color of the camera.
+ void SetBackgroundColor (const ColorRGBAf& color);
+ ColorRGBAf GetBackgroundColor () const { return m_BackGroundColor; }
+
+ // The clearing mode used for the camera.
+ enum ClearMode {
+ kSkybox = 1,
+ kSolidColor = 2,
+ kDepthOnly = 3,
+ kDontClear = 4
+ // Watch out for check consistency when changing this!
+ };
+
+ void SetClearFlags (int flags);
+ ClearMode GetClearFlags () const { return static_cast<ClearMode>(m_ClearFlags); }
+
+ void SetCullingMask (UInt32 cullingMask);
+ UInt32 GetCullingMask () const { return m_CullingMask.m_Bits; }
+
+ void SetEventMask (UInt32 cullingMask);
+ UInt32 GetEventMask () const { return m_EventMask.m_Bits; }
+
+ Vector3f GetPosition () const;
+
+ void SetUseOcclusionCulling (bool occlusionCull) { m_OcclusionCulling = occlusionCull; }
+ bool GetUseOcclusionCulling () const { return m_OcclusionCulling; }
+
+ /// A screen space point is defined in pixels.
+ /// The left-bottom of the screen is (0,0). The right-top is (screenWidth,screenHeight)
+ /// The z position is between 0...1. 0 is on the near plane. 1 is on the far plane
+
+ /// A viewport space point is normalized and relative to the camera
+ /// The left-bottom of the camera is (0,0). The top-right is (1,1)
+ /// The z position is between 0...1. 0 is on the near plane. 1 is on the far plane
+
+ /// Projects a World space point into screen space.
+ /// on return: canProject is true if the point could be projected to the screen (The point is inside the frustum)
+ Vector3f WorldToScreenPoint (const Vector3f& worldSpacePoint, bool* canProject = NULL) const;
+ /// Unprojects a screen space point into world space
+ Vector3f ScreenToWorldPoint (const Vector3f& screenSpacePoint) const;
+
+ /// Projects a world space point into viewport space
+ Vector3f WorldToViewportPoint (const Vector3f &worldSpace) const;
+ /// Unprojects a view port space into world space
+ Vector3f ViewportToWorldPoint (const Vector3f &viewPort) const;
+
+ /// Unprojects a view port space into camera space
+ Vector3f ViewportToCameraPoint (const Vector3f &viewPort) const;
+
+ // Converts a screen point into a world space ray
+ Ray ScreenPointToRay (const Vector2f& screenPos) const;
+ // Converts a viewport point into a world space ray
+ Ray ViewportPointToRay (const Vector2f& viewportPos) const;
+
+ // Converts a point between screen space and viewport space
+ Vector3f ScreenToViewportPoint (const Vector3f& screenPos) const;
+ Vector3f ViewportToScreenPoint (const Vector3f& viewPortPos) const;
+
+ // Calculates the distance between the left and right
+ // edges of the frustum pyramid at the far plane
+ float CalculateFarPlaneWorldSpaceLength () const;
+
+ // Calculates the distance between the left and right
+ // edges of the frustum pyramid at the near plane
+ float CalculateNearPlaneWorldSpaceLength () const;
+
+ void WindowSizeHasChanged ();
+
+ void AddImageFilter (const ImageFilter& filter);
+ void RemoveImageFilter (const ImageFilter& filter);
+
+ void ClearIntermediateRenderers( size_t startIndex = 0 );
+ IntermediateRenderers& GetIntermediateRenderers() { return *m_IntermediateRenderers; }
+
+ const Vector3f& GetVelocity () const { return m_Velocity; }
+
+ const Matrix4x4f& GetWorldToCameraMatrix () const;
+ Matrix4x4f GetCameraToWorldMatrix () const;
+
+ const Matrix4x4f& GetProjectionMatrix () const;
+ void GetImplicitProjectionMatrix (float overrideNearPlane, Matrix4x4f& outMatrix) const;
+ void GetImplicitProjectionMatrix (float overrideNearPlane, float overrideFarPlane, Matrix4x4f& outMatrix) const;
+
+ void GetClipToWorldMatrix( Matrix4x4f& outMatrix ) const;
+ const Matrix4x4f& GetWorldToClipMatrix() const;
+
+ void SetWorldToCameraMatrix (const Matrix4x4f& matrix);
+ void SetProjectionMatrix (const Matrix4x4f& matrix);
+
+ void ResetWorldToCameraMatrix () { m_ImplicitWorldToCameraMatrix = true; m_DirtyWorldToCameraMatrix = true; m_DirtyWorldToClipMatrix = true; }
+ void ResetProjectionMatrix () { m_ImplicitProjectionMatrix = true; m_DirtyProjectionMatrix = true; m_DirtyWorldToClipMatrix = true; }
+ bool IsImplicitWorldToCameraMatrix() const { return m_ImplicitWorldToCameraMatrix; }
+ bool IsImplicitProjectionMatrix() const { return m_ImplicitProjectionMatrix; }
+
+ void SetReplacementShader( Shader* shader, const std::string& replacementTag );
+ void ResetReplacementShader() { m_ReplacementShader.SetInstanceID(0); m_ReplacementTag.clear(); }
+ Shader *GetReplacementShader() const { return m_ReplacementShader; }
+ string GetReplacementShaderTag() const {return m_ReplacementTag; }
+
+ // Get/Set the texture to render into.
+ RenderTexture *GetTargetTexture () const { return m_TargetTexture; }
+ void SetTargetTexture (RenderTexture *tex);
+
+ void SetTargetBuffers (int colorCount, RenderSurfaceHandle* color, RenderSurfaceHandle depth, RenderTexture* originatedFrom);
+ void SetTargetBuffersScript (int colorCount, const ScriptingRenderBuffer* color, ScriptingRenderBuffer* depth);
+
+ // TODO: mrt support?
+ RenderSurfaceHandle GetTargetColorBuffer() const { return m_TargetColorBuffer[0]; }
+ RenderSurfaceHandle GetTargetDepthBuffer() const { return m_TargetDepthBuffer; }
+
+ const float *GetLayerCullDistances() const { return m_LayerCullDistances; }
+ void SetLayerCullDistances(float *layerCullDistances) {memcpy(m_LayerCullDistances,layerCullDistances,sizeof(float)*kNumLayers);}
+
+ bool GetLayerCullSpherical() const { return m_LayerCullSpherical; }
+ void SetLayerCullSpherical(bool enable) { m_LayerCullSpherical = enable; }
+
+ SortMode GetSortMode() const { return m_SortMode; }
+ void SetSortMode (SortMode m) { m_SortMode = m; }
+
+ // Get the current target. This can be different than the textureTarget if some image filters require
+ // A temporary buffer to render into.
+ RenderTexture *GetCurrentTargetTexture () const { return m_CurrentTargetTexture; }
+ void SetCurrentTargetTexture (RenderTexture* rt) { m_CurrentTargetTexture = rt; }
+
+ void TransformChanged ();
+ static void InitializeClass ();
+ static void CleanupClass () {}
+
+ void CopyFrom( const Camera& other );
+
+ void CalculateFarCullDistances (float* farCullDistances, float baseFarDistance) const;
+
+ enum DepthTextureModes {
+ kDepthTexDepthBit = (1<<0),
+ kDepthTexDepthNormalsBit = (1<<1),
+ };
+ UInt32 GetDepthTextureMode() const { return m_DepthTextureMode; }
+ void SetDepthTextureMode (UInt32 m) { m_DepthTextureMode = m; }
+
+ bool GetClearStencilAfterLightingPass() const { return m_ClearStencilAfterLightingPass; }
+ void SetClearStencilAfterLightingPass (bool clear) { m_ClearStencilAfterLightingPass = clear; }
+
+ RenderingPath CalculateRenderingPath() const;
+ bool CalculateNeedsToRenderIntoRT() const;
+ int CalculateAntiAliasingForRT() const;
+
+ bool GetUsesScreenForCompositing (bool forceIntoRT) const;
+
+
+ // Get the resolved skybox material we want to render with.
+ Material *GetSkyboxMaterial () const;
+
+ // Implementations in EditorCameraDrawing.cpp
+ #if UNITY_EDITOR
+
+ enum EditorDrawingMode {
+ kEditorDrawTextured = 0,
+ kEditorDrawWire = 1,
+ kEditorDrawTexturedWire = 2,
+ kEditorDrawRenderPaths = 3,
+ kEditorDrawLightmapResolution = 4,
+ kEditorDrawModeCount
+ };
+
+
+ void ClearEditorCamera (); // clears
+ void RenderEditorCamera (EditorDrawingMode mode, const DrawGridParameters* gridParam); // renders camera content (does not clear)
+ void FinishRenderingEditorCamera ();
+ void SetOnlyRenderIntermediateObjects() { m_OnlyRenderIntermediateObjects = true; }
+ static bool ShouldShowChannelErrors (const Camera* ptr);
+ void RenderEditorCameraFade (float fade);
+ void SetAnimateMaterials (bool animate);
+ bool GetAnimateMaterials () const { return m_AnimateMaterials; }
+ void SetAnimateMaterialsTime (float time);
+
+ bool IsFiltered (Unity::GameObject& gameObject) const;
+ void SetFilterMode (int filterMode) { m_FilterMode = filterMode; }
+ int GetFilterMode () const { return m_FilterMode; }
+
+ #endif
+
+// Texture* GetUmbraOcclusionBufferTexture ();
+
+private:
+
+ typedef void PerformRenderFunction (Camera& camera, RenderLoop& loop, CullResults& contents);
+ void DoRender( CullResults& cullResults, PerformRenderFunction* customRender, int renderFlags ); // Render all objects
+
+ void DoRenderPostLayers(); // Render any post-layers (before image effects)
+ void DoRenderGUILayer();
+
+ void DoClear (UInt32 gfxClearFlags);
+
+ // Behaviour stuff
+ virtual void AddToManager ();
+ virtual void RemoveFromManager ();
+
+ void SetCameraShaderProps();
+
+ void UpdateDepthTextures (const CullResults& cullResults);
+ void RenderDepthTexture (const CullResults& cullResults, RenderTexture** rt, RenderTextureFormat format, Shader* shader, const ColorRGBAf& clearColor, ShaderLab::FastPropertyName name);
+
+ void CleanupDepthTextures ();
+
+ void DisplayHDRWarnings() const;
+
+ Rectf GetCameraRect (bool zeroOrigin) const;
+
+ bool GetRenderImmediateObjects () const;
+
+private:
+
+ mutable Matrix4x4f m_WorldToCameraMatrix;
+ mutable Matrix4x4f m_ProjectionMatrix;
+ mutable Matrix4x4f m_WorldToClipMatrix;
+
+
+ // NOTE: whenever adding new camera properties, make sure they are copied as
+ // appropriate in CopyFrom(), and extend CameraCopyFromWorks runtime test
+ // to cover it.
+
+
+ RenderLoop* m_RenderLoop;
+
+ PPtr<RenderTexture> m_TargetTexture; ///< The texture to render this camera into
+
+ RenderSurfaceHandle m_TargetColorBuffer[kMaxSupportedRenderTargets];
+ int m_TargetColorBufferCount;
+ RenderSurfaceHandle m_TargetDepthBuffer;
+ // this is here to set as active RT along with render buffers
+ // dx uses current rt to check if we render onscreen (and tweak projection/offsets/etc)
+ // image filters use target RT in calculations of rt to draw to
+ // while ideally we want simple IsRenderingOnscreen + image effects to use render buffers
+ // we want it to work naow
+ RenderTexture* m_TargetBuffersOriginatedFrom;
+
+ RenderTexture* m_DepthTexture;
+ RenderTexture* m_DepthNormalsTexture;
+
+ RenderTexture* m_CurrentTargetTexture; // The texture we're rendering into _right now_
+
+ PPtr<Shader> m_ReplacementShader;
+ std::string m_ReplacementTag;
+
+ IntermediateRenderers* m_IntermediateRenderers;
+
+ unsigned int m_ClearFlags; ///< enum { Skybox = 1, Solid Color = 2, Depth only = 3, Don't Clear = 4 }
+ ColorRGBAf m_BackGroundColor; ///< The color to which camera clears the screen
+ Rectf m_NormalizedViewPortRect;
+
+ BitField m_CullingMask; ///< Which layers the camera does render
+ BitField m_EventMask; ///< Which layers receive events
+
+ float m_Depth; ///< A camera with a larger depth is drawn on top of a camera with a smaller depth range {-100, 100}
+ Vector3f m_Velocity;
+ Vector3f m_LastPosition;
+
+ float m_OrthographicSize;
+ float m_FieldOfView; ///< Field of view of the camera range { 0.00001, 179 }
+ float m_NearClip; ///< Near clipping plane
+ float m_FarClip; ///< Far clipping plane
+ int m_RenderingPath; ///< enum { Use Player Settings = -1, Vertex Lit=0, Forward=1, Deferred Lighting=2 } Rendering path to use.
+
+ float m_LayerCullDistances[kNumLayers];
+ float m_Aspect;
+ SortMode m_SortMode;
+
+ CubemapFace m_CurrentTargetFace; // current cubemap face we're rendering into (only used while rendering into a cubemap)
+
+ UInt32 m_DepthTextureMode;
+
+ mutable bool m_DirtyWorldToCameraMatrix;
+ mutable bool m_DirtyProjectionMatrix;
+ mutable bool m_DirtyWorldToClipMatrix;
+ bool m_ImplicitWorldToCameraMatrix;
+ bool m_ImplicitProjectionMatrix;
+ bool m_ImplicitAspect;
+ bool m_Orthographic; ///< Is camera orthographic?
+ bool m_OcclusionCulling;
+ bool m_LayerCullSpherical;
+ bool m_HDR;
+ bool m_UsingHDR;
+ bool m_IsRendering;
+ bool m_ClearStencilAfterLightingPass;
+
+
+ // NOTE: whenever adding new camera properties, make sure they are copied as
+ // appropriate in CopyFrom(), and extend CameraCopyFromWorks runtime test
+ // to cover it.
+
+
+ void SetTargetTextureBuffers(RenderTexture* tex, int colorCount, RenderSurfaceHandle* color, RenderSurfaceHandle depth, RenderTexture* rbOrigin);
+
+ #if UNITY_EDITOR
+ int m_FilterMode;
+ bool m_OnlyRenderIntermediateObjects;
+ bool m_IsSceneCamera;
+ CameraRenderOldState m_OldCameraState;
+ bool m_AnimateMaterials;
+ float m_AnimateMaterialsTime;
+ #endif
+};
+
+void StoreRenderState (CameraRenderOldState& state);
+void RestoreRenderState (CameraRenderOldState& state);
+
+Shader* GetCameraDepthTextureShader ();
+Shader* GetCameraDepthNormalsTextureShader ();
+
+void ClearWithSkybox (bool clearDepth, Camera const* camera);
+
+Rectf GetCameraOrWindowRect (const Camera* camera);
+
+#endif