| | |
| | | using System.Collections.Generic; |
| | | using UnityEngine.Rendering; |
| | | |
| | | namespace UnityEngine.PostProcessing |
| | | { |
| | | using Mode = BuiltinDebugViewsModel.Mode; |
| | | |
| | | public sealed class BuiltinDebugViewsComponent : PostProcessingComponentCommandBuffer<BuiltinDebugViewsModel> |
| | | { |
| | | static class Uniforms |
| | | { |
| | | internal static readonly int _DepthScale = Shader.PropertyToID("_DepthScale"); |
| | | internal static readonly int _TempRT = Shader.PropertyToID("_TempRT"); |
| | | internal static readonly int _Opacity = Shader.PropertyToID("_Opacity"); |
| | | internal static readonly int _MainTex = Shader.PropertyToID("_MainTex"); |
| | | internal static readonly int _TempRT2 = Shader.PropertyToID("_TempRT2"); |
| | | internal static readonly int _Amplitude = Shader.PropertyToID("_Amplitude"); |
| | | internal static readonly int _Scale = Shader.PropertyToID("_Scale"); |
| | | } |
| | | |
| | | const string k_ShaderString = "Hidden/Post FX/Builtin Debug Views"; |
| | | |
| | | enum Pass |
| | | { |
| | | Depth, |
| | | Normals, |
| | | MovecOpacity, |
| | | MovecImaging, |
| | | MovecArrows |
| | | } |
| | | |
| | | ArrowArray m_Arrows; |
| | | |
| | | class ArrowArray |
| | | { |
| | | public Mesh mesh { get; private set; } |
| | | |
| | | public int columnCount { get; private set; } |
| | | public int rowCount { get; private set; } |
| | | |
| | | public void BuildMesh(int columns, int rows) |
| | | { |
| | | // Base shape |
| | | var arrow = new Vector3[6] |
| | | { |
| | | new Vector3(0f, 0f, 0f), |
| | | new Vector3(0f, 1f, 0f), |
| | | new Vector3(0f, 1f, 0f), |
| | | new Vector3(-1f, 1f, 0f), |
| | | new Vector3(0f, 1f, 0f), |
| | | new Vector3(1f, 1f, 0f) |
| | | }; |
| | | |
| | | // make the vertex array |
| | | int vcount = 6 * columns * rows; |
| | | var vertices = new List<Vector3>(vcount); |
| | | var uvs = new List<Vector2>(vcount); |
| | | |
| | | for (int iy = 0; iy < rows; iy++) |
| | | { |
| | | for (int ix = 0; ix < columns; ix++) |
| | | { |
| | | var uv = new Vector2( |
| | | (0.5f + ix) / columns, |
| | | (0.5f + iy) / rows |
| | | ); |
| | | |
| | | for (int i = 0; i < 6; i++) |
| | | { |
| | | vertices.Add(arrow[i]); |
| | | uvs.Add(uv); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // make the index array |
| | | var indices = new int[vcount]; |
| | | |
| | | for (int i = 0; i < vcount; i++) |
| | | indices[i] = i; |
| | | |
| | | // initialize the mesh object |
| | | mesh = new Mesh { hideFlags = HideFlags.DontSave }; |
| | | mesh.SetVertices(vertices); |
| | | mesh.SetUVs(0, uvs); |
| | | mesh.SetIndices(indices, MeshTopology.Lines, 0); |
| | | mesh.UploadMeshData(true); |
| | | |
| | | // update the properties |
| | | columnCount = columns; |
| | | rowCount = rows; |
| | | } |
| | | |
| | | public void Release() |
| | | { |
| | | GraphicsUtils.Destroy(mesh); |
| | | mesh = null; |
| | | } |
| | | } |
| | | |
| | | public override bool active |
| | | { |
| | | get |
| | | { |
| | | return model.IsModeActive(Mode.Depth) |
| | | || model.IsModeActive(Mode.Normals) |
| | | || model.IsModeActive(Mode.MotionVectors); |
| | | } |
| | | } |
| | | |
| | | public override DepthTextureMode GetCameraFlags() |
| | | { |
| | | var mode = model.settings.mode; |
| | | var flags = DepthTextureMode.None; |
| | | |
| | | switch (mode) |
| | | { |
| | | case Mode.Normals: |
| | | flags |= DepthTextureMode.DepthNormals; |
| | | break; |
| | | case Mode.MotionVectors: |
| | | flags |= DepthTextureMode.MotionVectors | DepthTextureMode.Depth; |
| | | break; |
| | | case Mode.Depth: |
| | | flags |= DepthTextureMode.Depth; |
| | | break; |
| | | } |
| | | |
| | | return flags; |
| | | } |
| | | |
| | | public override CameraEvent GetCameraEvent() |
| | | { |
| | | return model.settings.mode == Mode.MotionVectors |
| | | ? CameraEvent.BeforeImageEffects |
| | | : CameraEvent.BeforeImageEffectsOpaque; |
| | | } |
| | | |
| | | public override string GetName() |
| | | { |
| | | return "Builtin Debug Views"; |
| | | } |
| | | |
| | | public override void PopulateCommandBuffer(CommandBuffer cb) |
| | | { |
| | | var settings = model.settings; |
| | | var material = context.materialFactory.Get(k_ShaderString); |
| | | material.shaderKeywords = null; |
| | | |
| | | if (context.isGBufferAvailable) |
| | | material.EnableKeyword("SOURCE_GBUFFER"); |
| | | |
| | | switch (settings.mode) |
| | | { |
| | | case Mode.Depth: |
| | | DepthPass(cb); |
| | | break; |
| | | case Mode.Normals: |
| | | DepthNormalsPass(cb); |
| | | break; |
| | | case Mode.MotionVectors: |
| | | MotionVectorsPass(cb); |
| | | break; |
| | | } |
| | | |
| | | context.Interrupt(); |
| | | } |
| | | |
| | | void DepthPass(CommandBuffer cb) |
| | | { |
| | | var material = context.materialFactory.Get(k_ShaderString); |
| | | var settings = model.settings.depth; |
| | | |
| | | cb.SetGlobalFloat(Uniforms._DepthScale, 1f / settings.scale); |
| | | cb.Blit((Texture)null, BuiltinRenderTextureType.CameraTarget, material, (int)Pass.Depth); |
| | | } |
| | | |
| | | void DepthNormalsPass(CommandBuffer cb) |
| | | { |
| | | var material = context.materialFactory.Get(k_ShaderString); |
| | | cb.Blit((Texture)null, BuiltinRenderTextureType.CameraTarget, material, (int)Pass.Normals); |
| | | } |
| | | |
| | | void MotionVectorsPass(CommandBuffer cb) |
| | | { |
| | | #if UNITY_EDITOR |
| | | // Don't render motion vectors preview when the editor is not playing as it can in some |
| | | // cases results in ugly artifacts (i.e. when resizing the game view). |
| | | if (!Application.isPlaying) |
| | | return; |
| | | #endif |
| | | |
| | | var material = context.materialFactory.Get(k_ShaderString); |
| | | var settings = model.settings.motionVectors; |
| | | |
| | | // Blit the original source image |
| | | int tempRT = Uniforms._TempRT; |
| | | cb.GetTemporaryRT(tempRT, context.width, context.height, 0, FilterMode.Bilinear); |
| | | cb.SetGlobalFloat(Uniforms._Opacity, settings.sourceOpacity); |
| | | cb.SetGlobalTexture(Uniforms._MainTex, BuiltinRenderTextureType.CameraTarget); |
| | | cb.Blit(BuiltinRenderTextureType.CameraTarget, tempRT, material, (int)Pass.MovecOpacity); |
| | | |
| | | // Motion vectors (imaging) |
| | | if (settings.motionImageOpacity > 0f && settings.motionImageAmplitude > 0f) |
| | | { |
| | | int tempRT2 = Uniforms._TempRT2; |
| | | cb.GetTemporaryRT(tempRT2, context.width, context.height, 0, FilterMode.Bilinear); |
| | | cb.SetGlobalFloat(Uniforms._Opacity, settings.motionImageOpacity); |
| | | cb.SetGlobalFloat(Uniforms._Amplitude, settings.motionImageAmplitude); |
| | | cb.SetGlobalTexture(Uniforms._MainTex, tempRT); |
| | | cb.Blit(tempRT, tempRT2, material, (int)Pass.MovecImaging); |
| | | cb.ReleaseTemporaryRT(tempRT); |
| | | tempRT = tempRT2; |
| | | } |
| | | |
| | | // Motion vectors (arrows) |
| | | if (settings.motionVectorsOpacity > 0f && settings.motionVectorsAmplitude > 0f) |
| | | { |
| | | PrepareArrows(); |
| | | |
| | | float sy = 1f / settings.motionVectorsResolution; |
| | | float sx = sy * context.height / context.width; |
| | | |
| | | cb.SetGlobalVector(Uniforms._Scale, new Vector2(sx, sy)); |
| | | cb.SetGlobalFloat(Uniforms._Opacity, settings.motionVectorsOpacity); |
| | | cb.SetGlobalFloat(Uniforms._Amplitude, settings.motionVectorsAmplitude); |
| | | cb.DrawMesh(m_Arrows.mesh, Matrix4x4.identity, material, 0, (int)Pass.MovecArrows); |
| | | } |
| | | |
| | | cb.SetGlobalTexture(Uniforms._MainTex, tempRT); |
| | | cb.Blit(tempRT, BuiltinRenderTextureType.CameraTarget); |
| | | cb.ReleaseTemporaryRT(tempRT); |
| | | } |
| | | |
| | | void PrepareArrows() |
| | | { |
| | | int row = model.settings.motionVectors.motionVectorsResolution; |
| | | int col = row * Screen.width / Screen.height; |
| | | |
| | | if (m_Arrows == null) |
| | | m_Arrows = new ArrowArray(); |
| | | |
| | | if (m_Arrows.columnCount != col || m_Arrows.rowCount != row) |
| | | { |
| | | m_Arrows.Release(); |
| | | m_Arrows.BuildMesh(col, row); |
| | | } |
| | | } |
| | | |
| | | public override void OnDisable() |
| | | { |
| | | if (m_Arrows != null) |
| | | m_Arrows.Release(); |
| | | |
| | | m_Arrows = null; |
| | | } |
| | | } |
| | | } |
| | | using System.Collections.Generic;
|
| | | using UnityEngine.Rendering;
|
| | |
|
| | | namespace UnityEngine.PostProcessing
|
| | | {
|
| | | using Mode = BuiltinDebugViewsModel.Mode;
|
| | |
|
| | | public sealed class BuiltinDebugViewsComponent : PostProcessingComponentCommandBuffer<BuiltinDebugViewsModel>
|
| | | {
|
| | | static class Uniforms
|
| | | {
|
| | | internal static readonly int _DepthScale = Shader.PropertyToID("_DepthScale");
|
| | | internal static readonly int _TempRT = Shader.PropertyToID("_TempRT");
|
| | | internal static readonly int _Opacity = Shader.PropertyToID("_Opacity");
|
| | | internal static readonly int _MainTex = Shader.PropertyToID("_MainTex");
|
| | | internal static readonly int _TempRT2 = Shader.PropertyToID("_TempRT2");
|
| | | internal static readonly int _Amplitude = Shader.PropertyToID("_Amplitude");
|
| | | internal static readonly int _Scale = Shader.PropertyToID("_Scale");
|
| | | }
|
| | |
|
| | | const string k_ShaderString = "Hidden/Post FX/Builtin Debug Views";
|
| | |
|
| | | enum Pass
|
| | | {
|
| | | Depth,
|
| | | Normals,
|
| | | MovecOpacity,
|
| | | MovecImaging,
|
| | | MovecArrows
|
| | | }
|
| | |
|
| | | ArrowArray m_Arrows;
|
| | |
|
| | | class ArrowArray
|
| | | {
|
| | | public Mesh mesh { get; private set; }
|
| | |
|
| | | public int columnCount { get; private set; }
|
| | | public int rowCount { get; private set; }
|
| | |
|
| | | public void BuildMesh(int columns, int rows)
|
| | | {
|
| | | // Base shape
|
| | | var arrow = new Vector3[6]
|
| | | {
|
| | | new Vector3(0f, 0f, 0f),
|
| | | new Vector3(0f, 1f, 0f),
|
| | | new Vector3(0f, 1f, 0f),
|
| | | new Vector3(-1f, 1f, 0f),
|
| | | new Vector3(0f, 1f, 0f),
|
| | | new Vector3(1f, 1f, 0f)
|
| | | };
|
| | |
|
| | | // make the vertex array
|
| | | int vcount = 6 * columns * rows;
|
| | | var vertices = new List<Vector3>(vcount);
|
| | | var uvs = new List<Vector2>(vcount);
|
| | |
|
| | | for (int iy = 0; iy < rows; iy++)
|
| | | {
|
| | | for (int ix = 0; ix < columns; ix++)
|
| | | {
|
| | | var uv = new Vector2(
|
| | | (0.5f + ix) / columns,
|
| | | (0.5f + iy) / rows
|
| | | );
|
| | |
|
| | | for (int i = 0; i < 6; i++)
|
| | | {
|
| | | vertices.Add(arrow[i]);
|
| | | uvs.Add(uv);
|
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | // make the index array
|
| | | var indices = new int[vcount];
|
| | |
|
| | | for (int i = 0; i < vcount; i++)
|
| | | indices[i] = i;
|
| | |
|
| | | // initialize the mesh object
|
| | | mesh = new Mesh { hideFlags = HideFlags.DontSave };
|
| | | mesh.SetVertices(vertices);
|
| | | mesh.SetUVs(0, uvs);
|
| | | mesh.SetIndices(indices, MeshTopology.Lines, 0);
|
| | | mesh.UploadMeshData(true);
|
| | |
|
| | | // update the properties
|
| | | columnCount = columns;
|
| | | rowCount = rows;
|
| | | }
|
| | |
|
| | | public void Release()
|
| | | {
|
| | | GraphicsUtils.Destroy(mesh);
|
| | | mesh = null;
|
| | | }
|
| | | }
|
| | |
|
| | | public override bool active
|
| | | {
|
| | | get
|
| | | {
|
| | | return model.IsModeActive(Mode.Depth)
|
| | | || model.IsModeActive(Mode.Normals)
|
| | | || model.IsModeActive(Mode.MotionVectors);
|
| | | }
|
| | | }
|
| | |
|
| | | public override DepthTextureMode GetCameraFlags()
|
| | | {
|
| | | var mode = model.settings.mode;
|
| | | var flags = DepthTextureMode.None;
|
| | |
|
| | | switch (mode)
|
| | | {
|
| | | case Mode.Normals:
|
| | | flags |= DepthTextureMode.DepthNormals;
|
| | | break;
|
| | | case Mode.MotionVectors:
|
| | | flags |= DepthTextureMode.MotionVectors | DepthTextureMode.Depth;
|
| | | break;
|
| | | case Mode.Depth:
|
| | | flags |= DepthTextureMode.Depth;
|
| | | break;
|
| | | }
|
| | |
|
| | | return flags;
|
| | | }
|
| | |
|
| | | public override CameraEvent GetCameraEvent()
|
| | | {
|
| | | return model.settings.mode == Mode.MotionVectors
|
| | | ? CameraEvent.BeforeImageEffects
|
| | | : CameraEvent.BeforeImageEffectsOpaque;
|
| | | }
|
| | |
|
| | | public override string GetName()
|
| | | {
|
| | | return "Builtin Debug Views";
|
| | | }
|
| | |
|
| | | public override void PopulateCommandBuffer(CommandBuffer cb)
|
| | | {
|
| | | var settings = model.settings;
|
| | | var material = context.materialFactory.Get(k_ShaderString);
|
| | | material.shaderKeywords = null;
|
| | |
|
| | | if (context.isGBufferAvailable)
|
| | | material.EnableKeyword("SOURCE_GBUFFER");
|
| | |
|
| | | switch (settings.mode)
|
| | | {
|
| | | case Mode.Depth:
|
| | | DepthPass(cb);
|
| | | break;
|
| | | case Mode.Normals:
|
| | | DepthNormalsPass(cb);
|
| | | break;
|
| | | case Mode.MotionVectors:
|
| | | MotionVectorsPass(cb);
|
| | | break;
|
| | | }
|
| | |
|
| | | context.Interrupt();
|
| | | }
|
| | |
|
| | | void DepthPass(CommandBuffer cb)
|
| | | {
|
| | | var material = context.materialFactory.Get(k_ShaderString);
|
| | | var settings = model.settings.depth;
|
| | |
|
| | | cb.SetGlobalFloat(Uniforms._DepthScale, 1f / settings.scale);
|
| | | cb.Blit((Texture)null, BuiltinRenderTextureType.CameraTarget, material, (int)Pass.Depth);
|
| | | }
|
| | |
|
| | | void DepthNormalsPass(CommandBuffer cb)
|
| | | {
|
| | | var material = context.materialFactory.Get(k_ShaderString);
|
| | | cb.Blit((Texture)null, BuiltinRenderTextureType.CameraTarget, material, (int)Pass.Normals);
|
| | | }
|
| | |
|
| | | void MotionVectorsPass(CommandBuffer cb)
|
| | | {
|
| | | #if UNITY_EDITOR
|
| | | // Don't render motion vectors preview when the editor is not playing as it can in some
|
| | | // cases results in ugly artifacts (i.e. when resizing the game view).
|
| | | if (!Application.isPlaying)
|
| | | return;
|
| | | #endif
|
| | |
|
| | | var material = context.materialFactory.Get(k_ShaderString);
|
| | | var settings = model.settings.motionVectors;
|
| | |
|
| | | // Blit the original source image
|
| | | int tempRT = Uniforms._TempRT;
|
| | | cb.GetTemporaryRT(tempRT, context.width, context.height, 0, FilterMode.Bilinear);
|
| | | cb.SetGlobalFloat(Uniforms._Opacity, settings.sourceOpacity);
|
| | | cb.SetGlobalTexture(Uniforms._MainTex, BuiltinRenderTextureType.CameraTarget);
|
| | | cb.Blit(BuiltinRenderTextureType.CameraTarget, tempRT, material, (int)Pass.MovecOpacity);
|
| | |
|
| | | // Motion vectors (imaging)
|
| | | if (settings.motionImageOpacity > 0f && settings.motionImageAmplitude > 0f)
|
| | | {
|
| | | int tempRT2 = Uniforms._TempRT2;
|
| | | cb.GetTemporaryRT(tempRT2, context.width, context.height, 0, FilterMode.Bilinear);
|
| | | cb.SetGlobalFloat(Uniforms._Opacity, settings.motionImageOpacity);
|
| | | cb.SetGlobalFloat(Uniforms._Amplitude, settings.motionImageAmplitude);
|
| | | cb.SetGlobalTexture(Uniforms._MainTex, tempRT);
|
| | | cb.Blit(tempRT, tempRT2, material, (int)Pass.MovecImaging);
|
| | | cb.ReleaseTemporaryRT(tempRT);
|
| | | tempRT = tempRT2;
|
| | | }
|
| | |
|
| | | // Motion vectors (arrows)
|
| | | if (settings.motionVectorsOpacity > 0f && settings.motionVectorsAmplitude > 0f)
|
| | | {
|
| | | PrepareArrows();
|
| | |
|
| | | float sy = 1f / settings.motionVectorsResolution;
|
| | | float sx = sy * context.height / context.width;
|
| | |
|
| | | cb.SetGlobalVector(Uniforms._Scale, new Vector2(sx, sy));
|
| | | cb.SetGlobalFloat(Uniforms._Opacity, settings.motionVectorsOpacity);
|
| | | cb.SetGlobalFloat(Uniforms._Amplitude, settings.motionVectorsAmplitude);
|
| | | cb.DrawMesh(m_Arrows.mesh, Matrix4x4.identity, material, 0, (int)Pass.MovecArrows);
|
| | | }
|
| | |
|
| | | cb.SetGlobalTexture(Uniforms._MainTex, tempRT);
|
| | | cb.Blit(tempRT, BuiltinRenderTextureType.CameraTarget);
|
| | | cb.ReleaseTemporaryRT(tempRT);
|
| | | }
|
| | |
|
| | | void PrepareArrows()
|
| | | {
|
| | | int row = model.settings.motionVectors.motionVectorsResolution;
|
| | | int col = row * Screen.width / Screen.height;
|
| | |
|
| | | if (m_Arrows == null)
|
| | | m_Arrows = new ArrowArray();
|
| | |
|
| | | if (m_Arrows.columnCount != col || m_Arrows.rowCount != row)
|
| | | {
|
| | | m_Arrows.Release();
|
| | | m_Arrows.BuildMesh(col, row);
|
| | | }
|
| | | }
|
| | |
|
| | | public override void OnDisable()
|
| | | {
|
| | | if (m_Arrows != null)
|
| | | m_Arrows.Release();
|
| | |
|
| | | m_Arrows = null;
|
| | | }
|
| | | }
|
| | | }
|