Unity优化之Camera相关

Unity优化之Camera相关

//Using more than one camera//

When created, a Unity scene
 contains just a single camera and this is all you need for most situations. However, you can have as many cameras
 in a scene as you like and their views can be combined in different ways, as described below.

Switching cameras

By default, a camera renders its view to cover the whole screen and so only one camera view can be seen at a time (the visible camera is the one that has the highest value for its depth property). By disabling one camera and enabling another from a script, you can “cut” from one camera to another to give different views of a scene. You might do this, for example, to switch between an overhead map view and a first-person view.

using UnityEngine; public class ExampleScript : MonoBehaviour { public Camera firstPersonCamera; public Camera overheadCamera; // Call this function to disable FPS camera, // and enable overhead camera. public void ShowOverheadView() { firstPersonCamera.enabled = false; overheadCamera.enabled = true; } // Call this function to enable FPS camera, // and disable overhead camera. public void ShowFirstPersonView() { firstPersonCamera.enabled = true; overheadCamera.enabled = false; } }

Rendering a small camera view inside a larger one

Usually, you want at least one camera view covering the whole screen (the default setting) but it is often useful to show another view inside a small area of the screen. For example, you might show a rear view mirror in a driving game or show an overhead mini-map in the corner of the screen while the main view is first-person. You can set the size of a camera’s onscreen rectangle using its Viewport Rect property.

The coordinates of the viewport
 rectangle are “normalized” with respect to the screen. The bottom and left edges are at the 0.0 coordinate, while the top and right edges are at 1.0. A coordinate value of 0.5 is halfway across. In addition to the viewport size, you should also set the depth property of the camera with the smaller view to a higher value than the background camera. The exact value does not matter but the rule is that a camera with a higher depth value is rendered over one with a lower value.

//

 

 

 

//Dynamic Resolution/

Dynamic resolution

Dynamic resolution is a Camera
 setting that allows you to dynamically scale individual render targets, to reduce workload on the GPU. In cases where the application’s frame rate reduces, you can gradually scale down the resolution to maintain a consistent frame rate instead. Unity triggers this scaling if performance data suggests that the frame rate is about to decrease as a result of the application being GPU-bound. You can also trigger the scaling manually by preempting a particularly GPU-intensive section of the application and controlling the scaling via a script. If scaled gradually, dynamic resolution can be almost unnoticeable.

Supported platforms

Unity supports dynamic resolution on Xbox One
, PS4, Nintendo Switch, iOS
, macOS and tvOS (Metal only), Android (Vulkan only), Windows Standalone and UWP (DirectX 12 only).

Impact on render targets

With dynamic resolution, Unity does not re-allocate render targets. Conceptually, Unity scales the render target; however, in reality, Unity uses aliasing, and the scaled-down render target only uses a small portion of the original render target. Unity allocates the render targets at their full resolution, and then the dynamic resolution system scales them down and back up again, using a portion of the original target instead of re-allocating a new target.

Scaling render targets

With dynamic resolution, render targets have the DynamicallyScalable flag. You can set this to state whether Unity should scale this render texture
 as part of the dynamic resolution process or not. Cameras also have the allowDynamicResolution flag, which you can use to set up dynamic resolution so that there is no need to override the render target if you just want to apply dynamic resolution to a less complex Scene
.

MRT buffers

When you enable Allow Dynamic Resolution on the Camera, Unity scales all of that Camera’s targets.

Controlling the scaling

You can control the scale through the ScalableBufferManager. The ScalableBufferManager gives you control of the dynamic width and height scale for all render targets you have marked for the dynamic resolution system to scale.

As an example, assume your application is running at a desirable frame rate, but under some circumstances the GPU performance decreases, due to a combination of increased particles, post-effects and screen complexity. The Unity FrameTimingManager allows you to detect when the CPU or GPU performance start to decrease. So you can use the FrameTimingManager to calculate a new desired width and height scale to keep the frame rate within your desired range, and bring the scale down to that value to keep performance stable (either instantly or gradually over a set amount of frames). When the screen complexity reduces and the GPU is performing consistently, you may then raise the width and height scale back to a value that you’ve calculated the GPU can handle.

Example

This example script demonstrates basic use of the API. Add it to a Camera in your Scene, and check Allow Dynamic Resolution in the Camera settings. You also need to open the Player settings (menu: Edit > Project Settings, then select the Player category) and check the Enable Frame Timing Statscheckbox.

Clicking the mouse, or tapping the screen with one finger, lowers the height and width resolution by the amount in the scaleWidthIncrement and scaleHeightIncrement variables respectively. Tapping with two fingers raises the resolutions by the same increment.

using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class DynamicResolutionTest : MonoBehaviour { public Text screenText; FrameTiming[] frameTimings = new FrameTiming[3]; public float maxResolutionWidthScale = 1.0f; public float maxResolutionHeightScale = 1.0f; public float minResolutionWidthScale = 0.5f; public float minResolutionHeightScale = 0.5f; public float scaleWidthIncrement = 0.1f; public float scaleHeightIncrement = 0.1f; float m_widthScale = 1.0f; float m_heightScale = 1.0f; // Variables for dynamic resolution algorithm that persist across frames uint m_frameCount = 0; const uint kNumFrameTimings = 2; double m_gpuFrameTime; double m_cpuFrameTime; // Use this for initialization void Start() { int rezWidth = (int)Mathf.Ceil(ScalableBufferManager.widthScaleFactor * Screen.currentResolution.width); int rezHeight = (int)Mathf.Ceil(ScalableBufferManager.heightScaleFactor * Screen.currentResolution.height); screenText.text = string.Format("Scale: {0:F3}x{1:F3}\nResolution: {2}x{3}\n", m_widthScale, m_heightScale, rezWidth, rezHeight); } // Update is called once per frame void Update() { float oldWidthScale = m_widthScale; float oldHeightScale = m_heightScale; // One finger lowers the resolution if (Input.GetButtonDown("Fire1")) { m_heightScale = Mathf.Max(minResolutionHeightScale, m_heightScale - scaleHeightIncrement); m_widthScale = Mathf.Max(minResolutionWidthScale, m_widthScale - scaleWidthIncrement); } // Two fingers raises the resolution if (Input.GetButtonDown("Fire2")) { m_heightScale = Mathf.Min(maxResolutionHeightScale, m_heightScale + scaleHeightIncrement); m_widthScale = Mathf.Min(maxResolutionWidthScale, m_widthScale + scaleWidthIncrement); } if (m_widthScale != oldWidthScale || m_heightScale != oldHeightScale) { ScalableBufferManager.ResizeBuffers(m_widthScale, m_heightScale); } DetermineResolution(); int rezWidth = (int)Mathf.Ceil(ScalableBufferManager.widthScaleFactor * Screen.currentResolution.width); int rezHeight = (int)Mathf.Ceil(ScalableBufferManager.heightScaleFactor * Screen.currentResolution.height); screenText.text = string.Format("Scale: {0:F3}x{1:F3}\nResolution: {2}x{3}\nScaleFactor: {4:F3}x{5:F3}\nGPU: {6:F3} CPU: {7:F3}", m_widthScale, m_heightScale, rezWidth, rezHeight, ScalableBufferManager.widthScaleFactor, ScalableBufferManager.heightScaleFactor, m_gpuFrameTime, m_cpuFrameTime); } // Estimate the next frame time and update the resolution scale if necessary. private void DetermineResolution() { ++m_frameCount; if (m_frameCount <= kNumFrameTimings) { return; } FrameTimingManager.CaptureFrameTimings(); FrameTimingManager.GetLatestTimings(kNumFrameTimings, frameTimings); if (frameTimings.Length < kNumFrameTimings) { Debug.LogFormat("Skipping frame {0}, didn't get enough frame timings.", m_frameCount); return; } m_gpuFrameTime = (double)frameTimings[0].gpuFrameTime; m_cpuFrameTime = (double)frameTimings[0].cpuFrameTime; } }

//

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值