using System.Collections.Generic; using RebootKit.Engine.Main; using RebootReality.jelycho.Main; using Unity.Mathematics; using UnityEngine; using UnityEngine.Experimental.Rendering; using UnityEngine.Rendering; using UnityEngine.Rendering.RendererUtils; using UnityEngine.Rendering.RenderGraphModule; using UnityEngine.Rendering.RenderGraphModule.Util; using UnityEngine.Rendering.Universal; namespace RebootReality.jelycho.InfectedArea { class InfectedAreaRenderPass : ScriptableRenderPass { const string k_InfectedTextureName = "_InfectedTexture"; const string k_InfectedRenderPass = "InfectedRenderPass"; const string k_CompositeInfectedRenderPass = "CompositeInfectedRenderPass"; class MainPassData { internal List Areas; internal Material Material; internal int PassIndex; } class CompositePassData { internal Material Material; internal int PassIndex; internal TextureHandle FrameTexture; internal TextureHandle InfectedTexture; } static MaterialPropertyBlock s_SharedPropertyBlock = new MaterialPropertyBlock(); static readonly int s_Center = Shader.PropertyToID("_Center"); static readonly int s_Radius = Shader.PropertyToID("_Radius"); static readonly int s_FrameTexture = Shader.PropertyToID("_FrameTexture"); static readonly int s_InfectedTexture = Shader.PropertyToID("_InfectedTexture"); Material m_Material; Material m_CompositeMaterial; Shader m_StencilShader; public InfectedAreaRenderPass(Material material, Material compositeMaterial) { m_Material = material; m_CompositeMaterial = compositeMaterial; } public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData) { if (RR.World == null || RR.World.Context is not WorldContext worldContext) { return; } UniversalResourceData resourceData = frameData.Get(); UniversalCameraData cameraData = frameData.Get(); if (resourceData.isActiveTargetBackBuffer) { return; } TextureHandle source = resourceData.activeColorTexture; TextureDesc infectedTextureDesc = resourceData.activeColorTexture.GetDescriptor(renderGraph); infectedTextureDesc.name = "InfectedColor"; infectedTextureDesc.colorFormat = GraphicsFormat.R8G8B8A8_SRGB; TextureHandle infectedColorTexture = renderGraph.CreateTexture(infectedTextureDesc); TextureDesc finalTextureDesc = resourceData.activeColorTexture.GetDescriptor(renderGraph); finalTextureDesc.name = "InfectedCombined"; TextureHandle finalColorTexture = renderGraph.CreateTexture(finalTextureDesc); if (!source.IsValid() || !infectedColorTexture.IsValid() || !finalColorTexture.IsValid()) { return; } using (IRasterRenderGraphBuilder builder = renderGraph.AddRasterRenderPass(passName, out MainPassData passData, profilingSampler)) { passData.Material = m_Material; passData.PassIndex = 0; passData.Areas = worldContext.InfectedAreaManager.InfectedAreas; builder.SetRenderAttachment(infectedColorTexture, 0, AccessFlags.Write); builder.SetRenderAttachmentDepth(resourceData.activeDepthTexture, AccessFlags.Write); builder.SetRenderFunc((MainPassData data, RasterGraphContext rgContext) => { s_SharedPropertyBlock.Clear(); foreach (InfectedAreaInfo infectedAreaInfo in data.Areas) { s_SharedPropertyBlock.SetVector(s_Center, infectedAreaInfo.Center.xyzz); s_SharedPropertyBlock.SetFloat(s_Radius, infectedAreaInfo.Radius); rgContext.cmd.DrawProcedural(Matrix4x4.identity, data.Material, data.PassIndex, MeshTopology.Triangles, 3, 1, s_SharedPropertyBlock); } }); } using (IRasterRenderGraphBuilder builder = renderGraph.AddRasterRenderPass(passName + " Composite", out CompositePassData passData, profilingSampler)) { passData.Material = m_CompositeMaterial; passData.PassIndex = 0; passData.FrameTexture = resourceData.activeColorTexture; passData.InfectedTexture = infectedColorTexture; builder.UseTexture(passData.FrameTexture, AccessFlags.Read); builder.UseTexture(passData.InfectedTexture, AccessFlags.Read); builder.SetRenderAttachment(finalColorTexture, 0, AccessFlags.Write); builder.SetRenderFunc((CompositePassData data, RasterGraphContext rgContext) => { s_SharedPropertyBlock.Clear(); s_SharedPropertyBlock.SetTexture(s_FrameTexture, data.FrameTexture); s_SharedPropertyBlock.SetTexture(s_InfectedTexture, data.InfectedTexture); rgContext.cmd.DrawProcedural(Matrix4x4.identity, data.Material, data.PassIndex, MeshTopology.Triangles, 3, 1, s_SharedPropertyBlock); }); } resourceData.cameraColor = finalColorTexture; } } public class InfectedAreaRendererFeature : ScriptableRendererFeature { [SerializeField] Material m_Material; [SerializeField] Material m_CompositeMaterial; InfectedAreaRenderPass m_InfectedAreaRenderPass; public override void Create() { m_InfectedAreaRenderPass = new InfectedAreaRenderPass(m_Material, m_CompositeMaterial) { renderPassEvent = RenderPassEvent.BeforeRenderingTransparents }; } protected override void Dispose(bool disposing) { } public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) { if (m_InfectedAreaRenderPass == null) { return; } if (renderingData.cameraData.cameraType == CameraType.Game) { renderer.EnqueuePass(m_InfectedAreaRenderPass); } } } }