您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

255 行
9.6 KiB

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Experimental.Rendering;
using UnityObject = UnityEngine.Object;
namespace UnityEngine.Experimental.ScriptableRenderLoop
{
[Flags]
public enum ClearFlag
{
ClearNone = 0,
ClearColor = 1,
ClearDepth = 2
}
public class Utilities
{
public const RendererConfiguration kRendererConfigurationBakedLighting = RendererConfiguration.PerObjectLightProbe | RendererConfiguration.PerObjectReflectionProbes | RendererConfiguration.PerObjectLightmaps | RendererConfiguration.PerObjectLightProbeProxyVolume;
// Render Target Management.
public const ClearFlag kClearAll = ClearFlag.ClearDepth | ClearFlag.ClearColor;
public static void SetRenderTarget(RenderLoop renderLoop, RenderTargetIdentifier buffer, ClearFlag clearFlag = ClearFlag.ClearNone, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown)
{
var cmd = new CommandBuffer();
cmd.name = "";
cmd.SetRenderTarget(buffer, miplevel, cubemapFace);
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
public static void SetRenderTarget(RenderLoop renderLoop, RenderTargetIdentifier colorBuffer, RenderTargetIdentifier depthBuffer, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown)
{
SetRenderTarget(renderLoop, colorBuffer, depthBuffer, ClearFlag.ClearNone, new Color(0.0f, 0.0f, 0.0f, 0.0f), miplevel, cubemapFace);
}
public static void SetRenderTarget(RenderLoop renderLoop, RenderTargetIdentifier colorBuffer, RenderTargetIdentifier depthBuffer, ClearFlag clearFlag, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown)
{
SetRenderTarget(renderLoop, colorBuffer, depthBuffer, clearFlag, new Color(0.0f, 0.0f, 0.0f, 0.0f), miplevel, cubemapFace);
}
public static void SetRenderTarget(RenderLoop renderLoop, RenderTargetIdentifier colorBuffer, RenderTargetIdentifier depthBuffer, ClearFlag clearFlag, Color clearColor, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown)
{
var cmd = new CommandBuffer();
cmd.name = "";
cmd.SetRenderTarget(colorBuffer, depthBuffer, miplevel, cubemapFace);
if (clearFlag != ClearFlag.ClearNone)
cmd.ClearRenderTarget((clearFlag & ClearFlag.ClearDepth) != 0, (clearFlag & ClearFlag.ClearColor) != 0, clearColor);
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
public static void SetRenderTarget(RenderLoop renderLoop, RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier depthBuffer)
{
SetRenderTarget(renderLoop, colorBuffers, depthBuffer, ClearFlag.ClearNone, Color.black);
}
public static void SetRenderTarget(RenderLoop renderLoop, RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier depthBuffer, ClearFlag clearFlag = ClearFlag.ClearNone)
{
SetRenderTarget(renderLoop, colorBuffers, depthBuffer, clearFlag, Color.black);
}
public static void SetRenderTarget(RenderLoop renderLoop, RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier depthBuffer, ClearFlag clearFlag, Color clearColor)
{
var cmd = new CommandBuffer();
cmd.name = "";
cmd.SetRenderTarget(colorBuffers, depthBuffer);
if (clearFlag != ClearFlag.ClearNone)
cmd.ClearRenderTarget((clearFlag & ClearFlag.ClearDepth) != 0, (clearFlag & ClearFlag.ClearColor) != 0, clearColor);
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
// Miscellanous
public static Material CreateEngineMaterial(string shaderPath)
{
var mat = new Material(Shader.Find(shaderPath))
{
hideFlags = HideFlags.HideAndDontSave
};
return mat;
}
public static void Destroy(UnityObject obj)
{
if (obj != null)
{
#if UNITY_EDITOR
if (Application.isPlaying)
UnityObject.Destroy(obj);
else
UnityObject.DestroyImmediate(obj);
#else
UnityObject.Destroy(obj);
#endif
obj = null;
}
}
public static void SafeRelease(ComputeBuffer buffer)
{
if (buffer != null)
{
buffer.Release();
buffer = null;
}
}
public class ProfilingSample
: IDisposable
{
bool disposed = false;
RenderLoop renderLoop;
string name;
public ProfilingSample(string _name, RenderLoop _renderloop)
{
renderLoop = _renderloop;
name = _name;
CommandBuffer cmd = new CommandBuffer();
cmd.name = "";
cmd.BeginSample(name);
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
~ProfilingSample()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
}
// Protected implementation of Dispose pattern.
protected virtual void Dispose(bool disposing)
{
if (disposed)
return;
if (disposing)
{
CommandBuffer cmd = new CommandBuffer();
cmd.name = "";
cmd.EndSample(name);
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
}
disposed = true;
}
}
public static Matrix4x4 GetViewProjectionMatrix(Matrix4x4 worldToViewMatrix, Matrix4x4 projectionMatrix)
{
// The actual projection matrix used in shaders is actually massaged a bit to work across all platforms
// (different Z value ranges etc.)
var gpuProj = GL.GetGPUProjectionMatrix(projectionMatrix, false);
var gpuVP = gpuProj * worldToViewMatrix * Matrix4x4.Scale(new Vector3(1.0f, 1.0f, -1.0f)); // Need to scale -1.0 on Z to match what is being done in the camera.wolrdToCameraMatrix API.
return gpuVP;
}
public static HDRenderLoop.HDCamera GetHDCamera(Camera camera)
{
HDRenderLoop.HDCamera hdCamera = new HDRenderLoop.HDCamera();
hdCamera.camera = camera;
hdCamera.screenSize = new Vector4(camera.pixelWidth, camera.pixelHeight, 1.0f / camera.pixelWidth, 1.0f / camera.pixelHeight);
// The actual projection matrix used in shaders is actually massaged a bit to work across all platforms
// (different Z value ranges etc.)
var gpuProj = GL.GetGPUProjectionMatrix(camera.projectionMatrix, false);
var gpuVP = gpuProj * camera.worldToCameraMatrix;
hdCamera.viewProjectionMatrix = gpuVP;
hdCamera.invViewProjectionMatrix = gpuVP.inverse;
return hdCamera;
}
public static void SetupMaterialHDCamera(HDRenderLoop.HDCamera hdCamera, Material material)
{
material.SetVector("_ScreenSize", hdCamera.screenSize);
material.SetMatrix("_ViewProjMatrix", hdCamera.viewProjectionMatrix);
material.SetMatrix("_InvViewProjMatrix", hdCamera.invViewProjectionMatrix);
}
// TEMP: These functions should be implemented C++ side, for now do it in C#
public static void SetMatrixCS(CommandBuffer cmd, ComputeShader shadercs, string name, Matrix4x4 mat)
{
var data = new float[16];
for (int c = 0; c < 4; c++)
for (int r = 0; r < 4; r++)
data[4 * c + r] = mat[r, c];
cmd.SetComputeFloatParams(shadercs, name, data);
}
public static void SetMatrixArrayCS(CommandBuffer cmd, ComputeShader shadercs, string name, Matrix4x4[] matArray)
{
int numMatrices = matArray.Length;
var data = new float[numMatrices * 16];
for (int n = 0; n < numMatrices; n++)
for (int c = 0; c < 4; c++)
for (int r = 0; r < 4; r++)
data[16 * n + 4 * c + r] = matArray[n][r, c];
cmd.SetComputeFloatParams(shadercs, name, data);
}
public static void SetVectorArrayCS(CommandBuffer cmd, ComputeShader shadercs, string name, Vector4[] vecArray)
{
int numVectors = vecArray.Length;
var data = new float[numVectors * 4];
for (int n = 0; n < numVectors; n++)
for (int i = 0; i < 4; i++)
data[4 * n + i] = vecArray[n][i];
cmd.SetComputeFloatParams(shadercs, name, data);
}
public static void SetKeyword(Material m, string keyword, bool state)
{
if (state)
m.EnableKeyword(keyword);
else
m.DisableKeyword(keyword);
}
public static HDRenderLoop GetHDRenderLoop()
{
HDRenderLoop renderLoop = UnityEngine.Rendering.GraphicsSettings.renderPipeline as HDRenderLoop;
if (renderLoop == null)
{
Debug.LogWarning("SkyParameters component can only be used with HDRenderLoop custom RenderPipeline.");
return null;
}
return renderLoop;
}
}
}