浏览代码
Merge pull request #440 from Unity-Technologies/refactor-episode-1
Merge pull request #440 from Unity-Technologies/refactor-episode-1
Refactoring: Episode 1 - The Dawn of Utilities/stochastic_alpha_test
GitHub
7 年前
当前提交
bbaee114
共有 22 个文件被更改,包括 629 次插入 和 640 次删除
-
4ScriptableRenderPipeline/Core/Shadow/Shadow.cs
-
4ScriptableRenderPipeline/HDRenderPipeline/Debug/DebugDisplay.cs
-
68ScriptableRenderPipeline/HDRenderPipeline/Editor/HDRenderPipelineInspector.cs
-
190ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs
-
2ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipelineAsset.cs
-
17ScriptableRenderPipeline/HDRenderPipeline/Lighting/AmbientOcclusion/ScreenSpaceAmbientOcclusion.cs
-
100ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs
-
8ScriptableRenderPipeline/HDRenderPipeline/Lighting/Volumetrics/VolumetricLighting.cs
-
8ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.cs
-
6ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/SubsurfaceScatteringProfile.cs
-
6ScriptableRenderPipeline/HDRenderPipeline/RenderPipelineResources/RenderPipelineResources.cs
-
10ScriptableRenderPipeline/HDRenderPipeline/Sky/HDRISky/HDRISkyRenderer.cs
-
8ScriptableRenderPipeline/HDRenderPipeline/Sky/ProceduralSky/ProceduralSkyRenderer.cs
-
16ScriptableRenderPipeline/HDRenderPipeline/Sky/RuntimeFilterIBL.cs
-
46ScriptableRenderPipeline/HDRenderPipeline/Sky/SkyManager.cs
-
268ScriptableRenderPipeline/Core/CoreUtils.cs
-
13ScriptableRenderPipeline/Core/CoreUtils.cs.meta
-
41ScriptableRenderPipeline/Core/ProfilingSample.cs
-
13ScriptableRenderPipeline/Core/ProfilingSample.cs.meta
-
51ScriptableRenderPipeline/HDRenderPipeline/HDUtils.cs
-
390ScriptableRenderPipeline/HDRenderPipeline/Utilities.cs
-
0/ScriptableRenderPipeline/HDRenderPipeline/HDUtils.cs.meta
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using UnityEngine.Experimental.Rendering.HDPipeline; |
|||
using UnityEngine.Rendering; |
|||
using UnityEngine.Rendering.PostProcessing; |
|||
|
|||
namespace UnityEngine.Experimental.Rendering |
|||
{ |
|||
using UnityObject = UnityEngine.Object; |
|||
|
|||
[Flags] |
|||
public enum ClearFlag |
|||
{ |
|||
None = 0, |
|||
Color = 1, |
|||
Depth = 2, |
|||
|
|||
All = Depth | Color |
|||
} |
|||
|
|||
public static class CoreUtils |
|||
{ |
|||
public static List<RenderPipelineMaterial> GetRenderPipelineMaterialList() |
|||
{ |
|||
var baseType = typeof(RenderPipelineMaterial); |
|||
var assembly = baseType.Assembly; |
|||
|
|||
var types = assembly.GetTypes() |
|||
.Where(t => t.IsSubclassOf(baseType)) |
|||
.Select(Activator.CreateInstance) |
|||
.Cast<RenderPipelineMaterial>() |
|||
.ToList(); |
|||
|
|||
// Note: If there is a need for an optimization in the future of this function, user can
|
|||
// simply fill the materialList manually by commenting the code abode and returning a
|
|||
// custom list of materials they use in their game.
|
|||
//
|
|||
// return new List<RenderPipelineMaterial>
|
|||
// {
|
|||
// new Lit(),
|
|||
// new Unlit(),
|
|||
// ...
|
|||
// };
|
|||
|
|||
return types; |
|||
} |
|||
|
|||
// Render Target Management.
|
|||
public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier buffer, ClearFlag clearFlag, Color clearColor, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown) |
|||
{ |
|||
cmd.SetRenderTarget(buffer, miplevel, cubemapFace); |
|||
|
|||
if (clearFlag != ClearFlag.None) |
|||
cmd.ClearRenderTarget((clearFlag & ClearFlag.Depth) != 0, (clearFlag & ClearFlag.Color) != 0, clearColor); |
|||
} |
|||
|
|||
public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier buffer, ClearFlag clearFlag = ClearFlag.None, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown) |
|||
{ |
|||
SetRenderTarget(cmd, buffer, clearFlag, Color.black, miplevel, cubemapFace); |
|||
} |
|||
|
|||
public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier colorBuffer, RenderTargetIdentifier depthBuffer, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown) |
|||
{ |
|||
SetRenderTarget(cmd, colorBuffer, depthBuffer, ClearFlag.None, Color.black, miplevel, cubemapFace); |
|||
} |
|||
|
|||
public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier colorBuffer, RenderTargetIdentifier depthBuffer, ClearFlag clearFlag, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown) |
|||
{ |
|||
SetRenderTarget(cmd, colorBuffer, depthBuffer, clearFlag, Color.black, miplevel, cubemapFace); |
|||
} |
|||
|
|||
public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier colorBuffer, RenderTargetIdentifier depthBuffer, ClearFlag clearFlag, Color clearColor, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown) |
|||
{ |
|||
cmd.SetRenderTarget(colorBuffer, depthBuffer, miplevel, cubemapFace); |
|||
|
|||
if (clearFlag != ClearFlag.None) |
|||
cmd.ClearRenderTarget((clearFlag & ClearFlag.Depth) != 0, (clearFlag & ClearFlag.Color) != 0, clearColor); |
|||
} |
|||
|
|||
public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier depthBuffer) |
|||
{ |
|||
SetRenderTarget(cmd, colorBuffers, depthBuffer, ClearFlag.None, Color.black); |
|||
} |
|||
|
|||
public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier depthBuffer, ClearFlag clearFlag = ClearFlag.None) |
|||
{ |
|||
SetRenderTarget(cmd, colorBuffers, depthBuffer, clearFlag, Color.black); |
|||
} |
|||
|
|||
public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier depthBuffer, ClearFlag clearFlag, Color clearColor) |
|||
{ |
|||
cmd.SetRenderTarget(colorBuffers, depthBuffer); |
|||
|
|||
if (clearFlag != ClearFlag.None) |
|||
cmd.ClearRenderTarget((clearFlag & ClearFlag.Depth) != 0, (clearFlag & ClearFlag.Color) != 0, clearColor); |
|||
} |
|||
|
|||
public static void ClearCubemap(CommandBuffer cmd, RenderTargetIdentifier buffer, Color clearColor) |
|||
{ |
|||
for(int i = 0; i < 6; ++i) |
|||
SetRenderTarget(cmd, buffer, ClearFlag.Color, Color.black, 0, (CubemapFace)i); |
|||
} |
|||
|
|||
// Draws a full screen triangle as a faster alternative to drawing a full screen quad.
|
|||
public static void DrawFullScreen(CommandBuffer commandBuffer, Material material, |
|||
MaterialPropertyBlock properties = null, int shaderPassId = 0) |
|||
{ |
|||
commandBuffer.DrawProcedural(Matrix4x4.identity, material, shaderPassId, MeshTopology.Triangles, 3, 1, properties); |
|||
} |
|||
|
|||
public static void DrawFullScreen(CommandBuffer commandBuffer, Material material, |
|||
RenderTargetIdentifier colorBuffer, |
|||
MaterialPropertyBlock properties = null, int shaderPassId = 0) |
|||
{ |
|||
commandBuffer.SetRenderTarget(colorBuffer); |
|||
commandBuffer.DrawProcedural(Matrix4x4.identity, material, shaderPassId, MeshTopology.Triangles, 3, 1, properties); |
|||
} |
|||
|
|||
public static void DrawFullScreen(CommandBuffer commandBuffer, Material material, |
|||
RenderTargetIdentifier colorBuffer, RenderTargetIdentifier depthStencilBuffer, |
|||
MaterialPropertyBlock properties = null, int shaderPassId = 0) |
|||
{ |
|||
commandBuffer.SetRenderTarget(colorBuffer, depthStencilBuffer); |
|||
commandBuffer.DrawProcedural(Matrix4x4.identity, material, shaderPassId, MeshTopology.Triangles, 3, 1, properties); |
|||
} |
|||
|
|||
public static void DrawFullScreen(CommandBuffer commandBuffer, Material material, |
|||
RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier depthStencilBuffer, |
|||
MaterialPropertyBlock properties = null, int shaderPassId = 0) |
|||
{ |
|||
commandBuffer.SetRenderTarget(colorBuffers, depthStencilBuffer); |
|||
commandBuffer.DrawProcedural(Matrix4x4.identity, material, shaderPassId, MeshTopology.Triangles, 3, 1, properties); |
|||
} |
|||
|
|||
// Important: the first RenderTarget must be created with 0 depth bits!
|
|||
public static void DrawFullScreen(CommandBuffer commandBuffer, Material material, |
|||
RenderTargetIdentifier[] colorBuffers, |
|||
MaterialPropertyBlock properties = null, int shaderPassId = 0) |
|||
{ |
|||
// It is currently not possible to have MRT without also setting a depth target.
|
|||
// To work around this deficiency of the CommandBuffer.SetRenderTarget() API,
|
|||
// we pass the first color target as the depth target. If it has 0 depth bits,
|
|||
// no depth target ends up being bound.
|
|||
DrawFullScreen(commandBuffer, material, colorBuffers, colorBuffers[0], properties, shaderPassId); |
|||
} |
|||
|
|||
// Post-processing misc
|
|||
public static bool IsPostProcessingActive(PostProcessLayer layer) |
|||
{ |
|||
return layer != null |
|||
&& layer.enabled; |
|||
} |
|||
|
|||
public static bool IsTemporalAntialiasingActive(PostProcessLayer layer) |
|||
{ |
|||
return IsPostProcessingActive(layer) |
|||
&& layer.antialiasingMode == PostProcessLayer.Antialiasing.TemporalAntialiasing |
|||
&& layer.temporalAntialiasing.IsSupported(); |
|||
} |
|||
|
|||
// Unity specifics
|
|||
public static Material CreateEngineMaterial(string shaderPath) |
|||
{ |
|||
var mat = new Material(Shader.Find(shaderPath)) |
|||
{ |
|||
hideFlags = HideFlags.HideAndDontSave |
|||
}; |
|||
return mat; |
|||
} |
|||
|
|||
public static Material CreateEngineMaterial(Shader shader) |
|||
{ |
|||
var mat = new Material(shader) |
|||
{ |
|||
hideFlags = HideFlags.HideAndDontSave |
|||
}; |
|||
return mat; |
|||
} |
|||
|
|||
public static void SetKeyword(Material m, string keyword, bool state) |
|||
{ |
|||
if (state) |
|||
m.EnableKeyword(keyword); |
|||
else |
|||
m.DisableKeyword(keyword); |
|||
} |
|||
|
|||
public static void SelectKeyword(Material material, string keyword1, string keyword2, bool enableFirst) |
|||
{ |
|||
material.EnableKeyword(enableFirst ? keyword1 : keyword2); |
|||
material.DisableKeyword(enableFirst ? keyword2 : keyword1); |
|||
} |
|||
|
|||
public static void SelectKeyword(Material material, string[] keywords, int enabledKeywordIndex) |
|||
{ |
|||
material.EnableKeyword(keywords[enabledKeywordIndex]); |
|||
|
|||
for (int i = 0; i < keywords.Length; i++) |
|||
{ |
|||
if (i != enabledKeywordIndex) |
|||
material.DisableKeyword(keywords[i]); |
|||
} |
|||
} |
|||
|
|||
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
|
|||
} |
|||
} |
|||
|
|||
public static void SafeRelease(ComputeBuffer buffer) |
|||
{ |
|||
if (buffer != null) |
|||
buffer.Release(); |
|||
} |
|||
|
|||
// Just a sort function that doesn't allocate memory
|
|||
// Note: Shoud be repalc by a radix sort for positive integer
|
|||
public static int Partition(uint[] numbers, int left, int right) |
|||
{ |
|||
uint pivot = numbers[left]; |
|||
while (true) |
|||
{ |
|||
while (numbers[left] < pivot) |
|||
left++; |
|||
|
|||
while (numbers[right] > pivot) |
|||
right--; |
|||
|
|||
if (left < right) |
|||
{ |
|||
uint temp = numbers[right]; |
|||
numbers[right] = numbers[left]; |
|||
numbers[left] = temp; |
|||
} |
|||
else |
|||
{ |
|||
return right; |
|||
} |
|||
} |
|||
} |
|||
|
|||
public static void QuickSort(uint[] arr, int left, int right) |
|||
{ |
|||
// For Recusrion
|
|||
if (left < right) |
|||
{ |
|||
int pivot = Partition(arr, left, right); |
|||
|
|||
if (pivot > 1) |
|||
QuickSort(arr, left, pivot - 1); |
|||
|
|||
if (pivot + 1 < right) |
|||
QuickSort(arr, pivot + 1, right); |
|||
} |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: c86deb7236b4fe146b8b75ab0ac89586 |
|||
timeCreated: 1507041147 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System; |
|||
using UnityEngine.Rendering; |
|||
|
|||
namespace UnityEngine.Experimental.Rendering |
|||
{ |
|||
public struct ProfilingSample : IDisposable |
|||
{ |
|||
public readonly CommandBuffer cmd; |
|||
public readonly string name; |
|||
|
|||
bool m_Disposed; |
|||
|
|||
public ProfilingSample(string name, CommandBuffer cmd) |
|||
{ |
|||
this.cmd = cmd; |
|||
this.name = name; |
|||
m_Disposed = false; |
|||
cmd.BeginSample(name); |
|||
} |
|||
|
|||
public void Dispose() |
|||
{ |
|||
Dispose(true); |
|||
} |
|||
|
|||
// Protected implementation of Dispose pattern.
|
|||
void Dispose(bool disposing) |
|||
{ |
|||
if (m_Disposed) |
|||
return; |
|||
|
|||
// As this is a struct, it could have been initialized using an empty constructor so we
|
|||
// need to make sure `cmd` isn't null to avoid a crash. Switching to a class would fix
|
|||
// this but will generate garbage on every frame (and this struct is used quite a lot).
|
|||
if (disposing && cmd != null) |
|||
cmd.EndSample(name); |
|||
|
|||
m_Disposed = true; |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: a9115e9ffa8b6df4ba69fe5eb9b541db |
|||
timeCreated: 1507043252 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
#if UNITY_EDITOR
|
|||
using System.IO; |
|||
using UnityEditor; |
|||
#endif
|
|||
|
|||
namespace UnityEngine.Experimental.Rendering.HDPipeline |
|||
{ |
|||
public class HDUtils |
|||
{ |
|||
#if UNITY_EDITOR
|
|||
public static string GetHDRenderPipelinePath() |
|||
{ |
|||
// User can create their own directory for SRP, so we need to find the current path that they use.
|
|||
// We know that DefaultHDMaterial exist and we know where it is, let's use that to find the current directory.
|
|||
var guid = AssetDatabase.FindAssets("DefaultHDMaterial t:material"); |
|||
string path = AssetDatabase.GUIDToAssetPath(guid[0]); |
|||
path = Path.GetDirectoryName(path); // Asset is in HDRenderPipeline/RenderPipelineResources/DefaultHDMaterial.mat
|
|||
path = path.Replace("RenderPipelineResources", ""); // Keep only path with HDRenderPipeline
|
|||
|
|||
return path; |
|||
} |
|||
#endif
|
|||
|
|||
public const RendererConfiguration k_RendererConfigurationBakedLighting = RendererConfiguration.PerObjectLightProbe | RendererConfiguration.PerObjectLightmaps | RendererConfiguration.PerObjectLightProbeProxyVolume; |
|||
|
|||
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; |
|||
} |
|||
|
|||
// Helper to help to display debug info on screen
|
|||
static float s_OverlayLineHeight = -1.0f; |
|||
public static void NextOverlayCoord(ref float x, ref float y, float overlayWidth, float overlayHeight, float width) |
|||
{ |
|||
x += overlayWidth; |
|||
s_OverlayLineHeight = Mathf.Max(overlayHeight, s_OverlayLineHeight); |
|||
// Go to next line if it goes outside the screen.
|
|||
if (x + overlayWidth > width) |
|||
{ |
|||
x = 0; |
|||
y -= s_OverlayLineHeight; |
|||
s_OverlayLineHeight = -1.0f; |
|||
} |
|||
} |
|||
} |
|||
} |
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq.Expressions; |
|||
using System.Text; |
|||
using UnityEngine.Rendering; |
|||
using UnityObject = UnityEngine.Object; |
|||
using System.Reflection; |
|||
using UnityEngine.Rendering.PostProcessing; |
|||
|
|||
#if UNITY_EDITOR
|
|||
using System.IO; |
|||
using UnityEditor; |
|||
#endif
|
|||
|
|||
namespace UnityEngine.Experimental.Rendering.HDPipeline |
|||
{ |
|||
[Flags] |
|||
public enum ClearFlag |
|||
{ |
|||
ClearNone = 0, |
|||
ClearColor = 1, |
|||
ClearDepth = 2 |
|||
} |
|||
|
|||
public class Utilities |
|||
{ |
|||
|
|||
#if UNITY_EDITOR
|
|||
public static string GetHDRenderPipelinePath() |
|||
{ |
|||
// User can create their own directory for SRP, so we need to find the current path that they use.
|
|||
// We know that DefaultHDMaterial exist and we know where it is, let's use that to find the current directory.
|
|||
var guid = AssetDatabase.FindAssets("DefaultHDMaterial t:material"); |
|||
string path = AssetDatabase.GUIDToAssetPath(guid[0]); |
|||
path = Path.GetDirectoryName(path); // Asset is in HDRenderPipeline/RenderPipelineResources/DefaultHDMaterial.mat
|
|||
path = path.Replace("RenderPipelineResources", ""); // Keep only path with HDRenderPipeline
|
|||
|
|||
return path; |
|||
} |
|||
#endif
|
|||
|
|||
public static List<RenderPipelineMaterial> GetRenderPipelineMaterialList() |
|||
{ |
|||
List<RenderPipelineMaterial> materialList = new List<RenderPipelineMaterial>(); |
|||
|
|||
var baseType = typeof(RenderPipelineMaterial); |
|||
var assembly = baseType.Assembly; |
|||
|
|||
System.Type[] types = assembly.GetTypes(); |
|||
foreach (System.Type type in types) |
|||
{ |
|||
if (type.IsSubclassOf(baseType)) |
|||
{ |
|||
// Create an instance object of the given type
|
|||
var obj = (RenderPipelineMaterial)Activator.CreateInstance(type); |
|||
materialList.Add(obj); |
|||
} |
|||
} |
|||
|
|||
// Note: If there is a need for an optimization in the future of this function, user can simply fill the materialList manually by commenting the code abode and
|
|||
// adding to the list material they used in their game.
|
|||
// materialList.Add(new Lit());
|
|||
// materialList.Add(new Unlit());
|
|||
// ...
|
|||
|
|||
return materialList; |
|||
} |
|||
|
|||
public const RendererConfiguration kRendererConfigurationBakedLighting = RendererConfiguration.PerObjectLightProbe | RendererConfiguration.PerObjectLightmaps | RendererConfiguration.PerObjectLightProbeProxyVolume; |
|||
|
|||
|
|||
// Render Target Management.
|
|||
public const ClearFlag kClearAll = ClearFlag.ClearDepth | ClearFlag.ClearColor; |
|||
|
|||
public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier buffer, ClearFlag clearFlag, Color clearColor, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown) |
|||
{ |
|||
cmd.SetRenderTarget(buffer, miplevel, cubemapFace); |
|||
if (clearFlag != ClearFlag.ClearNone) |
|||
cmd.ClearRenderTarget((clearFlag & ClearFlag.ClearDepth) != 0, (clearFlag & ClearFlag.ClearColor) != 0, clearColor); |
|||
} |
|||
|
|||
public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier buffer, ClearFlag clearFlag = ClearFlag.ClearNone, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown) |
|||
{ |
|||
SetRenderTarget(cmd, buffer, clearFlag, Color.black, miplevel, cubemapFace); |
|||
} |
|||
|
|||
public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier colorBuffer, RenderTargetIdentifier depthBuffer, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown) |
|||
{ |
|||
SetRenderTarget(cmd, colorBuffer, depthBuffer, ClearFlag.ClearNone, Color.black, miplevel, cubemapFace); |
|||
} |
|||
|
|||
public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier colorBuffer, RenderTargetIdentifier depthBuffer, ClearFlag clearFlag, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown) |
|||
{ |
|||
SetRenderTarget(cmd, colorBuffer, depthBuffer, clearFlag, Color.black, miplevel, cubemapFace); |
|||
} |
|||
|
|||
public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier colorBuffer, RenderTargetIdentifier depthBuffer, ClearFlag clearFlag, Color clearColor, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown) |
|||
{ |
|||
cmd.SetRenderTarget(colorBuffer, depthBuffer, miplevel, cubemapFace); |
|||
if (clearFlag != ClearFlag.ClearNone) |
|||
cmd.ClearRenderTarget((clearFlag & ClearFlag.ClearDepth) != 0, (clearFlag & ClearFlag.ClearColor) != 0, clearColor); |
|||
} |
|||
|
|||
public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier depthBuffer) |
|||
{ |
|||
SetRenderTarget(cmd, colorBuffers, depthBuffer, ClearFlag.ClearNone, Color.black); |
|||
} |
|||
|
|||
public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier depthBuffer, ClearFlag clearFlag = ClearFlag.ClearNone) |
|||
{ |
|||
SetRenderTarget(cmd, colorBuffers, depthBuffer, clearFlag, Color.black); |
|||
} |
|||
|
|||
public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier depthBuffer, ClearFlag clearFlag, Color clearColor) |
|||
{ |
|||
cmd.SetRenderTarget(colorBuffers, depthBuffer); |
|||
if (clearFlag != ClearFlag.ClearNone) |
|||
cmd.ClearRenderTarget((clearFlag & ClearFlag.ClearDepth) != 0, (clearFlag & ClearFlag.ClearColor) != 0, clearColor); |
|||
} |
|||
|
|||
public static void ClearCubemap(CommandBuffer cmd, RenderTargetIdentifier buffer, Color clearColor) |
|||
{ |
|||
for(int i = 0 ; i < 6 ; ++i) |
|||
{ |
|||
SetRenderTarget(cmd, buffer, ClearFlag.ClearColor, Color.black, 0, (CubemapFace)i); |
|||
} |
|||
} |
|||
|
|||
// Post-processing misc
|
|||
public static bool IsPostProcessingActive(PostProcessLayer layer) |
|||
{ |
|||
return layer != null |
|||
&& layer.enabled; |
|||
} |
|||
|
|||
public static bool IsTemporalAntialiasingActive(PostProcessLayer layer) |
|||
{ |
|||
return IsPostProcessingActive(layer) |
|||
&& layer.antialiasingMode == PostProcessLayer.Antialiasing.TemporalAntialiasing |
|||
&& layer.temporalAntialiasing.IsSupported(); |
|||
} |
|||
|
|||
// Miscellanous
|
|||
public static Material CreateEngineMaterial(string shaderPath) |
|||
{ |
|||
var mat = new Material(Shader.Find(shaderPath)) |
|||
{ |
|||
hideFlags = HideFlags.HideAndDontSave |
|||
}; |
|||
return mat; |
|||
} |
|||
|
|||
public static Material CreateEngineMaterial(Shader shader) |
|||
{ |
|||
var mat = new Material(shader) |
|||
{ |
|||
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
|
|||
} |
|||
} |
|||
|
|||
public static void SafeRelease(ComputeBuffer buffer) |
|||
{ |
|||
if (buffer != null) |
|||
buffer.Release(); |
|||
} |
|||
|
|||
public static string GetFieldPath<TType, TValue>(Expression<Func<TType, TValue>> expr) |
|||
{ |
|||
MemberExpression me; |
|||
switch (expr.Body.NodeType) |
|||
{ |
|||
case ExpressionType.Convert: |
|||
case ExpressionType.ConvertChecked: |
|||
var ue = expr.Body as UnaryExpression; |
|||
me = (ue != null ? ue.Operand : null) as MemberExpression; |
|||
break; |
|||
default: |
|||
me = expr.Body as MemberExpression; |
|||
break; |
|||
} |
|||
|
|||
var members = new List<string>(); |
|||
while (me != null) |
|||
{ |
|||
members.Add(me.Member.Name); |
|||
me = me.Expression as MemberExpression; |
|||
} |
|||
|
|||
var sb = new StringBuilder(); |
|||
for (int i = members.Count - 1; i >= 0; i--) |
|||
{ |
|||
sb.Append(members[i]); |
|||
if (i > 0) sb.Append('.'); |
|||
} |
|||
|
|||
return sb.ToString(); |
|||
} |
|||
|
|||
public struct ProfilingSample |
|||
: IDisposable |
|||
{ |
|||
bool disposed; |
|||
CommandBuffer cmd; |
|||
string name; |
|||
|
|||
public ProfilingSample(string _name, CommandBuffer _cmd) |
|||
{ |
|||
cmd = _cmd; |
|||
disposed = false; |
|||
name = _name; |
|||
cmd.BeginSample(name); |
|||
} |
|||
|
|||
public void Dispose() |
|||
{ |
|||
Dispose(true); |
|||
} |
|||
|
|||
// Protected implementation of Dispose pattern.
|
|||
void Dispose(bool disposing) |
|||
{ |
|||
if (disposed) |
|||
return; |
|||
|
|||
if (disposing) |
|||
{ |
|||
cmd.EndSample(name); |
|||
} |
|||
|
|||
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 void SetKeyword(Material m, string keyword, bool state) |
|||
{ |
|||
if (state) |
|||
m.EnableKeyword(keyword); |
|||
else |
|||
m.DisableKeyword(keyword); |
|||
} |
|||
|
|||
public static void SelectKeyword(Material material, string keyword1, string keyword2, bool enableFirst) |
|||
{ |
|||
material.EnableKeyword(enableFirst ? keyword1 : keyword2); |
|||
material.DisableKeyword(enableFirst ? keyword2 : keyword1); |
|||
} |
|||
|
|||
public static void SelectKeyword(Material material, string[] keywords, int enabledKeywordIndex) |
|||
{ |
|||
material.EnableKeyword(keywords[enabledKeywordIndex]); |
|||
|
|||
for (int i = 0; i < keywords.Length; i++) |
|||
{ |
|||
if (i != enabledKeywordIndex) |
|||
{ |
|||
material.DisableKeyword(keywords[i]); |
|||
} |
|||
} |
|||
} |
|||
|
|||
// Draws a full screen triangle as a faster alternative to drawing a full screen quad.
|
|||
public static void DrawFullScreen(CommandBuffer commandBuffer, Material material, |
|||
MaterialPropertyBlock properties = null, int shaderPassID = 0) |
|||
{ |
|||
commandBuffer.DrawProcedural(Matrix4x4.identity, material, shaderPassID, MeshTopology.Triangles, 3, 1, properties); |
|||
} |
|||
|
|||
// Draws a full screen triangle as a faster alternative to drawing a full screen quad.
|
|||
public static void DrawFullScreen(CommandBuffer commandBuffer, Material material, |
|||
RenderTargetIdentifier colorBuffer, |
|||
MaterialPropertyBlock properties = null, int shaderPassID = 0) |
|||
{ |
|||
commandBuffer.SetRenderTarget(colorBuffer); |
|||
commandBuffer.DrawProcedural(Matrix4x4.identity, material, shaderPassID, MeshTopology.Triangles, 3, 1, properties); |
|||
} |
|||
|
|||
// Draws a full screen triangle as a faster alternative to drawing a full screen quad.
|
|||
public static void DrawFullScreen(CommandBuffer commandBuffer, Material material, |
|||
RenderTargetIdentifier colorBuffer, RenderTargetIdentifier depthStencilBuffer, |
|||
MaterialPropertyBlock properties = null, int shaderPassID = 0) |
|||
{ |
|||
commandBuffer.SetRenderTarget(colorBuffer, depthStencilBuffer); |
|||
commandBuffer.DrawProcedural(Matrix4x4.identity, material, shaderPassID, MeshTopology.Triangles, 3, 1, properties); |
|||
} |
|||
|
|||
// Draws a full screen triangle as a faster alternative to drawing a full screen quad.
|
|||
public static void DrawFullScreen(CommandBuffer commandBuffer, Material material, |
|||
RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier depthStencilBuffer, |
|||
MaterialPropertyBlock properties = null, int shaderPassID = 0) |
|||
{ |
|||
commandBuffer.SetRenderTarget(colorBuffers, depthStencilBuffer); |
|||
commandBuffer.DrawProcedural(Matrix4x4.identity, material, shaderPassID, MeshTopology.Triangles, 3, 1, properties); |
|||
} |
|||
|
|||
// Draws a full screen triangle as a faster alternative to drawing a full screen quad.
|
|||
// Important: the first RenderTarget must be created with 0 depth bits!
|
|||
public static void DrawFullScreen(CommandBuffer commandBuffer, Material material, |
|||
RenderTargetIdentifier[] colorBuffers, |
|||
MaterialPropertyBlock properties = null, int shaderPassID = 0) |
|||
{ |
|||
// It is currently not possible to have MRT without also setting a depth target.
|
|||
// To work around this deficiency of the CommandBuffer.SetRenderTarget() API,
|
|||
// we pass the first color target as the depth target. If it has 0 depth bits,
|
|||
// no depth target ends up being bound.
|
|||
DrawFullScreen(commandBuffer, material, colorBuffers, colorBuffers[0], properties, shaderPassID); |
|||
} |
|||
|
|||
// Helper to help to display debug info on screen
|
|||
static float overlayLineHeight = -1.0f; |
|||
public static void NextOverlayCoord(ref float x, ref float y, float overlayWidth, float overlayHeight, float width) |
|||
{ |
|||
x += overlayWidth; |
|||
overlayLineHeight = Mathf.Max(overlayHeight, overlayLineHeight); |
|||
// Go to next line if it goes outside the screen.
|
|||
if (x + overlayWidth > width) |
|||
{ |
|||
x = 0; |
|||
y -= overlayLineHeight; |
|||
overlayLineHeight = -1.0f; |
|||
} |
|||
} |
|||
|
|||
// Just a sort function that doesn't allocate memory
|
|||
// Note: Shoud be repalc by a radix sort for positive integer
|
|||
static public int Partition(uint[] numbers, int left, int right) |
|||
{ |
|||
uint pivot = numbers[left]; |
|||
while (true) |
|||
{ |
|||
while (numbers[left] < pivot) |
|||
left++; |
|||
|
|||
while (numbers[right] > pivot) |
|||
right--; |
|||
|
|||
if (left < right) |
|||
{ |
|||
uint temp = numbers[right]; |
|||
numbers[right] = numbers[left]; |
|||
numbers[left] = temp; |
|||
} |
|||
else |
|||
{ |
|||
return right; |
|||
} |
|||
} |
|||
} |
|||
|
|||
static public void QuickSort(uint[] arr, int left, int right) |
|||
{ |
|||
// For Recusrion
|
|||
if (left < right) |
|||
{ |
|||
int pivot = Partition(arr, left, right); |
|||
|
|||
if (pivot > 1) |
|||
QuickSort(arr, left, pivot - 1); |
|||
|
|||
if (pivot + 1 < right) |
|||
QuickSort(arr, pivot + 1, right); |
|||
} |
|||
} |
|||
} |
|||
} |
撰写
预览
正在加载...
取消
保存
Reference in new issue