1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
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
|