Created
August 30, 2025 23:50
-
-
Save mrkybe/a4d136a430812d8a77c651d28f405ae9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using Drawing; | |
| using FX; | |
| using Sirenix.OdinInspector; | |
| using Unity.Collections; | |
| using Unity.Mathematics; | |
| using UnityEngine; | |
| using UnityEngine.Experimental.Rendering; | |
| using UnityEngine.Rendering; | |
| using UnityEngine.Rendering.RenderGraphModule; | |
| using UnityEngine.Rendering.Universal; | |
| using DrawingSettings = UnityEngine.Rendering.DrawingSettings; | |
| #pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable. | |
| namespace RenderFX | |
| { | |
| public class ShipCloudRenderGraphFeature : ScriptableRendererFeature | |
| { | |
| [System.Serializable] | |
| public class Settings | |
| { | |
| [Header("Scene")] public LayerMask shipLayer = 0; | |
| public Material shipMaskMaterial; | |
| private readonly float[] validScales = new float[6] { 0.03125f, 0.0625f, 0.125f, 0.25f, 0.5f, 1f }; | |
| [ValueDropdown("validScales")] public float cloudScale = .25f; | |
| [Header("Blur (fullRT_desc‑res)")] public Material blurMat; | |
| [Min(1)] public int blurPasses = 2; | |
| [Header("Clouds & Composite (quarter‑res)")] | |
| public Material cloudMat; | |
| public Material compositeMat; | |
| public int stencilRef = 1; | |
| [Header("Compute Shader Parameters")] | |
| public ComputeShader CloudComputeShader; | |
| public Texture3D _Simplex3D; | |
| public Texture3D _Worley3D; | |
| public Color cs_CloudColor; | |
| public Color cs_SunColor; | |
| public Vector4 cs_ShipOrigin; | |
| public float cs_Angle; | |
| public Vector4 cs_Position; | |
| public Vector4 cs_Velocity; | |
| public float cs_DensityThreshold = 1; | |
| public float cs_DensityMul = 1; | |
| public float cs_DensityPower = 1; | |
| public Vector3 cs_LightDir = new Vector3(0,0, -1); | |
| [Range(0.02f, 1f)] | |
| public float cs_LightStep; | |
| [Range(0.02f, 1f)] | |
| public float cs_StepSize; | |
| public float cs_ShadowMul; | |
| public float cs_MaxDistance; | |
| [Range(-10, 10)] | |
| public float cs_CloudStartZ; | |
| [Range(-10, 100)] | |
| public float cs_CloudEndZ; | |
| [Range(0,0.8f)] | |
| public float cs_ExtinctionScale; | |
| public Vector3 cs_DebugPos; | |
| public bool Valid => blurMat && cloudMat && compositeMat && cloudScale > 0f && cloudScale <= 1f; | |
| } | |
| [SerializeField] Settings settings = new(); | |
| ShipCloudPass m_Pass; | |
| protected static readonly Vector4 scaleBias = new Vector4(1f, 1f, 0f, 0f); | |
| private static readonly int ShadowVpId = Shader.PropertyToID("_ShadowVP"); | |
| public override void Create() | |
| { | |
| m_Pass = new ShipCloudPass(settings) { renderPassEvent = RenderPassEvent.AfterRenderingTransparents }; | |
| } | |
| public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData rd) | |
| { | |
| if (settings.Valid) | |
| { | |
| renderer.EnqueuePass(m_Pass); | |
| } | |
| } | |
| sealed class ShipCloudPass : ScriptableRenderPass | |
| { | |
| private readonly Settings s; | |
| private const string s_shipMask = "ShipMask"; | |
| private const string sTag_UniversalForward = "UniversalForward"; | |
| private const string s_BlitTexture = "_BlitTexture"; | |
| private readonly int kernel; | |
| int threadGroupX, threadGroupY; | |
| private static int frameCount; | |
| public ShipCloudPass(Settings settings) | |
| { | |
| s = settings; | |
| kernel = settings.CloudComputeShader.FindKernel("CSMain"); | |
| } | |
| // helper struct to gather per‑frame data once | |
| struct Frame | |
| { | |
| public UniversalResourceData res; | |
| public UniversalRenderingData urn; | |
| public UniversalCameraData cam; | |
| public UniversalLightData light; | |
| } | |
| // main entry | |
| public override void RecordRenderGraph(RenderGraph rg, ContextContainer frame) | |
| { | |
| var frameData = new Frame { res = frame.Get<UniversalResourceData>(), urn = frame.Get<UniversalRenderingData>(), cam = frame.Get<UniversalCameraData>(), light = frame.Get<UniversalLightData>() }; | |
| // ── texture descriptors | |
| var fullRT_desc = frameData.cam.cameraTargetDescriptor; | |
| fullRT_desc.graphicsFormat = UnityEngine.Experimental.Rendering.GraphicsFormat.R32G32B32A32_SFloat; | |
| fullRT_desc.depthBufferBits = 0; | |
| fullRT_desc.msaaSamples = 1; | |
| var cloudQuarterResRT_desc = fullRT_desc; | |
| cloudQuarterResRT_desc.width = Mathf.CeilToInt(fullRT_desc.width * s.cloudScale); | |
| cloudQuarterResRT_desc.height = Mathf.CeilToInt(fullRT_desc.height * s.cloudScale); | |
| cloudQuarterResRT_desc.msaaSamples = 1; | |
| var shadowMaskRT_desc = fullRT_desc; | |
| shadowMaskRT_desc.width = Mathf.CeilToInt(fullRT_desc.width); | |
| shadowMaskRT_desc.height = Mathf.CeilToInt(fullRT_desc.height); | |
| var sunShadowMaskRT_desc = fullRT_desc; | |
| sunShadowMaskRT_desc.autoGenerateMips = true; | |
| sunShadowMaskRT_desc.graphicsFormat = GraphicsFormat.D32_SFloat; | |
| sunShadowMaskRT_desc.depthBufferBits = 0; | |
| var debugTextureRT_desc = fullRT_desc; | |
| debugTextureRT_desc.enableRandomWrite = true; | |
| debugTextureRT_desc.width = Mathf.CeilToInt(fullRT_desc.width * s.cloudScale); | |
| debugTextureRT_desc.height = Mathf.CeilToInt(fullRT_desc.height * s.cloudScale); | |
| // clouds need full RGBA, match the camera's format: | |
| var cloudsRT_desc = frameData.cam.cameraTargetDescriptor; | |
| cloudsRT_desc.graphicsFormat = UnityEngine.Experimental.Rendering.GraphicsFormat.R32G32B32A32_SFloat; | |
| cloudsRT_desc.width = cloudQuarterResRT_desc.width; | |
| cloudsRT_desc.height = cloudQuarterResRT_desc.height; | |
| cloudsRT_desc.msaaSamples = 1; | |
| cloudsRT_desc.volumeDepth = 64; | |
| cloudsRT_desc.dimension = TextureDimension.Tex3D; | |
| cloudsRT_desc.enableRandomWrite = true; | |
| cloudsRT_desc.useMipMap = true; | |
| float maxShadowDistance = s.cs_DebugPos.y; | |
| ShadowMatrixUtility.BuildDirectionalLightMatrices(frameData.cam.camera, s.cs_LightDir, maxShadowDistance, | |
| out var shadowViewM, out var shadowProjM); | |
| Matrix4x4 worldToShadow = shadowProjM * shadowViewM; | |
| // ── RG‑managed textures | |
| var shipMask = UniversalRenderer.CreateRenderGraphTexture(rg, fullRT_desc, s_shipMask, false); | |
| var clouds3d = UniversalRenderer.CreateRenderGraphTexture(rg, cloudsRT_desc, "Clouds3D", false); | |
| var shadowMap = UniversalRenderer.CreateRenderGraphTexture(rg, sunShadowMaskRT_desc, "ShadowMap", false); | |
| var debugTexture = UniversalRenderer.CreateRenderGraphTexture(rg, debugTextureRT_desc, "DebugTexture", false); | |
| BuildShipMask(rg, frameData, shipMask); | |
| BuildShadowMask(rg, frameData, shadowMap, shadowViewM, shadowProjM); | |
| BlurMask(rg, shipMask); | |
| RaymarchCloudsCS(rg, frameData, shipMask, shadowMap, s.cloudScale, clouds3d, worldToShadow, debugTexture); | |
| Composite(rg, frameData, clouds3d, shipMask); | |
| } | |
| // ─────────────────────── ship depth + stencil mask (full‑res) | |
| void BuildShipMask(RenderGraph rg, Frame f, TextureHandle dst) | |
| { | |
| using var builder = rg.AddRasterRenderPass<ShipMaskPD>(s_shipMask, out var pd); | |
| var depthTag = new ShaderTagId("DepthOnly"); | |
| // drawing + filtering | |
| var sort = new SortingSettings(f.cam.camera) { criteria = SortingCriteria.CommonTransparent }; | |
| var draw = new DrawingSettings(shaderPassName: new ShaderTagId(sTag_UniversalForward), sortingSettings: sort) { perObjectData = PerObjectData.None }; | |
| draw.overrideMaterial = s.shipMaskMaterial; | |
| draw.overrideMaterialPassIndex = 0; | |
| var filter = new FilteringSettings(RenderQueueRange.all, s.shipLayer); | |
| // stencil override | |
| var rs = new RenderStateBlock(RenderStateMask.Stencil) { stencilReference = s.stencilRef, stencilState = new StencilState(enabled: true, compareFunction: CompareFunction.Always, passOperation: StencilOp.Replace) }; | |
| // RendererListHandle via helper below | |
| pd.list = RendererListHelpers.CreateWithState(rg, ref f.urn.cullResults, draw, filter, rs, depthTag); | |
| builder.UseRendererList(pd.list); | |
| builder.SetRenderAttachment(dst, 0); | |
| builder.SetRenderAttachmentDepth(f.res.activeDepthTexture, AccessFlags.Write); | |
| builder.SetRenderFunc((ShipMaskPD d, RasterGraphContext ctx) => { ctx.cmd.DrawRendererList(d.list); }); | |
| } | |
| class ShipMaskPD | |
| { | |
| public RendererListHandle list; | |
| } | |
| void BuildShadowMask(RenderGraph rg, Frame f, TextureHandle dst, Matrix4x4 shadowViewM, Matrix4x4 shadowProjM) | |
| { | |
| using var builder = rg.AddRasterRenderPass<ShadowMaskPD>("ShadowMask", out var pd); | |
| var depthTag = new ShaderTagId("DepthOnly"); | |
| var sort = new SortingSettings(f.cam.camera) { criteria = SortingCriteria.CommonTransparent }; | |
| var draw = new DrawingSettings(shaderPassName: new ShaderTagId(sTag_UniversalForward), sortingSettings: sort) { perObjectData = PerObjectData.None }; | |
| draw.overrideMaterial = s.shipMaskMaterial; | |
| draw.overrideMaterialPassIndex = 0; | |
| var filter = new FilteringSettings(RenderQueueRange.all, s.shipLayer); | |
| // stencil override | |
| var rs = new RenderStateBlock(RenderStateMask.Stencil) { stencilReference = s.stencilRef, stencilState = new StencilState(enabled: true, compareFunction: CompareFunction.Always, passOperation: StencilOp.Replace) }; | |
| // RendererListHandle via helper below | |
| pd.list = RendererListHelpers.CreateWithState(rg, ref f.urn.cullResults, draw, filter, rs, depthTag); | |
| pd.shadowRT = dst; | |
| pd.view = shadowViewM; | |
| pd.proj = shadowProjM; | |
| builder.AllowPassCulling(false); | |
| builder.UseRendererList(pd.list); | |
| builder.SetRenderAttachmentDepth(pd.shadowRT, AccessFlags.Write); | |
| builder.SetRenderFunc((ShadowMaskPD d, RasterGraphContext ctx) => | |
| { | |
| //ctx.cmd.SetViewProjectionMatrices(d.view, d.proj); | |
| s.shipMaskMaterial.EnableKeyword("USE_SHADOW_VP"); | |
| s.shipMaskMaterial.SetMatrix(ShadowVpId, d.proj * d.view); | |
| ctx.cmd.DrawRendererList(d.list); | |
| s.shipMaskMaterial.DisableKeyword("USE_SHADOW_VP"); | |
| }); | |
| } | |
| class ShadowMaskPD { | |
| public RendererListHandle list; | |
| public Matrix4x4 view; | |
| public Matrix4x4 proj; | |
| public TextureHandle shadowRT; | |
| } | |
| // ─────────────────────── separable Gaussian blur (full‑res) | |
| void BlurMask(RenderGraph rg, TextureHandle shipMask) | |
| { | |
| // ------------------------------------------------------------------ | |
| // 1. Allocate a transient temp texture (same descriptor as the mask) | |
| // ------------------------------------------------------------------ | |
| var tmpDesc = shipMask.GetDescriptor(rg); | |
| tmpDesc.name = "ShipMaskBlurTmp"; | |
| TextureHandle tmp = rg.CreateTexture(tmpDesc); | |
| for (int i = 0; i < s.blurPasses; i++) | |
| { | |
| // ------------------------------------------------------------------ | |
| // 2. Horizontal blur (shipMask → tmp) | |
| // ------------------------------------------------------------------ | |
| using (var hPass = rg.AddRasterRenderPass<BlurPD>("BlurMask_H", out var h)) | |
| { | |
| h.src = shipMask; | |
| h.dst = tmp; | |
| h.dir = new Vector2(1, 0); | |
| hPass.UseTexture(h.src, AccessFlags.Read); // sample from | |
| hPass.SetRenderAttachment(h.dst, 0); // render into | |
| hPass.AllowGlobalStateModification(true); | |
| hPass.SetRenderFunc((BlurPD d, RasterGraphContext ctx) => | |
| { | |
| ctx.cmd.SetGlobalVector("_BlurDir", d.dir); | |
| ctx.cmd.SetGlobalTexture(s_BlitTexture, d.src); // add this | |
| Blitter.BlitTexture(ctx.cmd, d.src, scaleBias, s.blurMat, 0); | |
| }); | |
| } | |
| // ------------------------------------------------------------------ | |
| // 3. Vertical blur (tmp → shipMask) | |
| // ------------------------------------------------------------------ | |
| using (var vPass = rg.AddRasterRenderPass<BlurPD>("BlurMask_V", out var v)) | |
| { | |
| v.src = tmp; | |
| v.dst = shipMask; | |
| v.dir = new Vector2(0, 1); | |
| vPass.UseTexture(v.src, AccessFlags.Read); | |
| vPass.SetRenderAttachment(v.dst, 0); | |
| vPass.AllowGlobalStateModification(true); | |
| vPass.SetRenderFunc((BlurPD d, RasterGraphContext ctx) => | |
| { | |
| ctx.cmd.SetGlobalVector("_BlurDir", d.dir); | |
| Blitter.BlitTexture(ctx.cmd, d.src, scaleBias, s.blurMat, 0); | |
| }); | |
| } | |
| } | |
| } | |
| class BlurPD | |
| { | |
| public TextureHandle src, dst; | |
| public Vector2 dir; | |
| } | |
| void RaymarchCloudsCS(RenderGraph rg, Frame f, TextureHandle shipMask, TextureHandle shadowMap, float cloudRTScale, TextureHandle clouds3d, Matrix4x4 worldToShadow, TextureHandle debugTexture) | |
| { | |
| using var builder = rg.AddComputePass("Cloud Volume Compute Pass", out ComputeData computeData); | |
| computeData.shipMask = shipMask; | |
| computeData.shadowMap = shadowMap; | |
| computeData.clouds3D = clouds3d; | |
| computeData.worldToShadow = worldToShadow; | |
| computeData.debugTexture = debugTexture; | |
| builder.UseTexture(shipMask, AccessFlags.Read); | |
| builder.UseTexture(shadowMap, AccessFlags.Read); | |
| builder.UseTexture(clouds3d, AccessFlags.ReadWrite); | |
| builder.UseTexture(debugTexture, AccessFlags.ReadWrite); | |
| int fullResolutionX = 1920; | |
| int fullResolutionY = 1080; | |
| int scaledWidthPx = 1920 / 8; | |
| int scaledHeightPx = 1080 / 8; | |
| int CloudColorId = Shader.PropertyToID("_CloudColor"); | |
| int SunColorId = Shader.PropertyToID("_SunColor"); | |
| int ShipOriginId = Shader.PropertyToID("_ShipOrigin"); | |
| int AngleId = Shader.PropertyToID("_Angle"); | |
| int ExtinctionScaleId = Shader.PropertyToID("_ExtinctionScale"); | |
| int PositionId = Shader.PropertyToID("_Position"); | |
| int VelocityId = Shader.PropertyToID("_Velocity"); | |
| int DensityThresholdId = Shader.PropertyToID("_DensityThreshold"); | |
| int DensityMulId = Shader.PropertyToID("_DensityMul"); | |
| int DensityPowerId = Shader.PropertyToID("_DensityPower"); | |
| int LightDirId = Shader.PropertyToID("_LightDir"); | |
| int ViewDirId = Shader.PropertyToID("_ViewDir"); | |
| int LightStepId = Shader.PropertyToID("_LightStep"); | |
| int StepSizeId = Shader.PropertyToID("_StepSize"); | |
| int ShadowMulId = Shader.PropertyToID("_ShadowMul"); | |
| int CloudRTScaleId = Shader.PropertyToID("_CloudRTScale"); | |
| int MaxDistanceId = Shader.PropertyToID("_MaxDistance"); | |
| int CloudStartZId = Shader.PropertyToID("_CloudStartZ"); | |
| int CloudEndZId = Shader.PropertyToID("_CloudEndZ"); | |
| int ScreenInfosId = Shader.PropertyToID("_ScreenInfos"); | |
| int kInvViewProjId = Shader.PropertyToID("_InvViewProj"); | |
| int kViewProjId = Shader.PropertyToID("_ViewProj"); | |
| int kProjId = Shader.PropertyToID("_Proj"); | |
| int kInvProjId = Shader.PropertyToID("_InvProj"); | |
| int debugWorldPosId = Shader.PropertyToID("_DebugWorldPos"); | |
| int CameraFarClipId = Shader.PropertyToID("_FarClip"); | |
| int CameraNearClipId = Shader.PropertyToID("_NearClip"); | |
| int OrthoCameraId = Shader.PropertyToID("_OrthoCamera"); | |
| int CameraPosWSId = Shader.PropertyToID("_CameraPosWS"); | |
| int InvViewId = Shader.PropertyToID("_InvView"); | |
| builder.SetRenderFunc((ComputeData data, ComputeGraphContext context) => | |
| { | |
| var cs = s.CloudComputeShader; | |
| var cam = f.cam.camera; | |
| // ── correct inverse view-projection (single matrix) | |
| Matrix4x4 invVP = (GL.GetGPUProjectionMatrix(cam.projectionMatrix, true) * | |
| cam.worldToCameraMatrix).inverse; | |
| Matrix4x4 ViewProjectMat = cam.worldToCameraMatrix; | |
| Matrix4x4 ProjectionMat = cam.projectionMatrix; | |
| Matrix4x4 InvProjectionMat = cam.projectionMatrix.inverse; | |
| Matrix4x4 bias = Matrix4x4.identity; | |
| bias.m00 = bias.m11 = bias.m22 = s.cs_DebugPos.z; | |
| bias.m03 = bias.m13 = bias.m23 = s.cs_DebugPos.z; // [-1..1] ➜ [0..1] | |
| /* | |
| Vector3 p = s.cs_DebugPos; | |
| Vector4 sc = worldToShadow * new Vector4(p.x,p.y,p.z,1); | |
| sc /= sc.w; | |
| Debug.Log(sc); | |
| using (Draw.WithDuration(0.5f)) | |
| { | |
| Draw.Arrow(p, new float3(sc.x, sc.y, sc.z)); | |
| }*/ | |
| context.cmd.SetComputeMatrixParam(cs, "_WorldToShadow", bias * data.worldToShadow); | |
| float nearClip = cam.nearClipPlane; | |
| float farClip = cam.farClipPlane; | |
| context.cmd.SetComputeIntParam(cs, OrthoCameraId, cam.orthographic ? 1 : 0); | |
| context.cmd.SetComputeMatrixParam(cs, kInvViewProjId, invVP); | |
| // Scalar & vector parameters | |
| context.cmd.SetComputeVectorParam(cs, CloudColorId, s.cs_CloudColor); | |
| context.cmd.SetComputeVectorParam(cs, SunColorId, s.cs_SunColor); | |
| context.cmd.SetComputeVectorParam(cs, ShipOriginId, s.cs_ShipOrigin); | |
| context.cmd.SetComputeFloatParam (cs, AngleId, s.cs_Angle); | |
| context.cmd.SetComputeVectorParam(cs, PositionId, s.cs_Position); | |
| context.cmd.SetComputeVectorParam(cs, VelocityId, s.cs_Velocity); | |
| context.cmd.SetComputeFloatParam (cs, DensityThresholdId,s.cs_DensityThreshold); | |
| context.cmd.SetComputeFloatParam (cs, DensityMulId, s.cs_DensityMul); | |
| context.cmd.SetComputeFloatParam (cs, DensityPowerId, s.cs_DensityPower); | |
| context.cmd.SetComputeVectorParam(cs, LightDirId, s.cs_LightDir); | |
| context.cmd.SetComputeFloatParam (cs, LightStepId, s.cs_LightStep); | |
| context.cmd.SetComputeFloatParam (cs, StepSizeId, s.cs_StepSize); | |
| context.cmd.SetComputeFloatParam (cs, ShadowMulId, s.cs_ShadowMul); | |
| context.cmd.SetComputeFloatParam (cs, ExtinctionScaleId, s.cs_ExtinctionScale); | |
| context.cmd.SetComputeFloatParam (cs, CloudRTScaleId, cloudRTScale); | |
| context.cmd.SetComputeFloatParam (cs, MaxDistanceId, s.cs_MaxDistance); | |
| context.cmd.SetComputeFloatParam (cs, CloudStartZId, s.cs_CloudStartZ); | |
| context.cmd.SetComputeFloatParam (cs, CloudEndZId, s.cs_CloudEndZ); | |
| context.cmd.SetComputeFloatParam (cs, CameraFarClipId, farClip); | |
| context.cmd.SetComputeFloatParam (cs, CameraNearClipId, nearClip); | |
| context.cmd.SetComputeMatrixParam(cs, kViewProjId, ViewProjectMat); | |
| context.cmd.SetComputeMatrixParam(cs, kProjId, ProjectionMat); | |
| context.cmd.SetComputeMatrixParam(cs, kInvProjId, InvProjectionMat); | |
| context.cmd.SetComputeMatrixParam(cs, InvViewId, cam.cameraToWorldMatrix); | |
| context.cmd.SetComputeVectorParam(cs, debugWorldPosId, s.cs_DebugPos); | |
| context.cmd.SetComputeVectorParam(cs, CameraPosWSId, f.cam.worldSpaceCameraPos); | |
| context.cmd.SetComputeVectorParam (cs, Shader.PropertyToID("_Clock"), new Vector4(Time.time / 20f, Time.time, Mathf.Sin(Time.time),Mathf.Cos(Time.time))); | |
| context.cmd.SetComputeVectorParam(cs, ScreenInfosId, new Vector4(fullResolutionX, fullResolutionY, 1.0f + 1.0f / (float)fullResolutionX, 1.0f + 1.0f / fullResolutionY)); | |
| context.cmd.SetComputeTextureParam(cs, kernel, "_ShipMask", data.shipMask); | |
| context.cmd.SetComputeTextureParam(cs, kernel, "_ShadowMap", data.shadowMap); | |
| context.cmd.SetComputeTextureParam(cs, kernel, "_CloudVolume", data.clouds3D); | |
| context.cmd.SetComputeTextureParam(cs, kernel, "_DebugTexture", data.debugTexture); | |
| context.cmd.DispatchCompute(cs, kernel, Mathf.CeilToInt(fullResolutionX / 8f), Mathf.CeilToInt(fullResolutionY / 8f), 1); | |
| }); | |
| } | |
| class ComputeData | |
| { | |
| public TextureHandle shipMask, shadowMap, clouds3D, debugTexture; | |
| public Matrix4x4 worldToShadow; | |
| } | |
| void RaymarchClouds(RenderGraph rg, Frame f, TextureHandle mask, TextureHandle clouds3d, float cloudRTScale) | |
| { | |
| using var builder = rg.AddRasterRenderPass<CloudPD>("CloudRaymarch", out var pd); | |
| pd.mask = mask; | |
| pd.clouds3d = clouds3d; | |
| builder.UseTexture(pd.mask, AccessFlags.Read); | |
| builder.UseTexture(pd.black, AccessFlags.Read); | |
| builder.SetRandomAccessAttachment(pd.clouds3d, 0, AccessFlags.Write); | |
| builder.AllowGlobalStateModification(true); | |
| builder.SetRenderFunc((CloudPD d, RasterGraphContext ctx) => | |
| { | |
| ctx.cmd.SetGlobalFloat("_CloudRTScale", cloudRTScale); | |
| ctx.cmd.SetGlobalTexture("_ShipShadowMask", d.mask); | |
| Blitter.BlitTexture(ctx.cmd, ctx.defaultResources.blackTexture, scaleBias, s.cloudMat, 0); | |
| }); | |
| } | |
| class CloudPD | |
| { | |
| public TextureHandle mask, black, clouds3d; | |
| } | |
| // ─────────────────────── upsample & blend into camera target | |
| void Composite(RenderGraph rg, Frame f, TextureHandle clouds, TextureHandle shipMask) | |
| { | |
| using var builder = rg.AddRasterRenderPass<CompositePD>("CloudComposite", out var pd); | |
| pd.clouds = clouds; | |
| pd.shipMask = shipMask; | |
| builder.UseTexture(pd.clouds, AccessFlags.Read); | |
| builder.UseTexture(pd.shipMask, AccessFlags.Read); | |
| builder.SetRenderAttachment(f.res.activeColorTexture, 0); | |
| builder.AllowGlobalStateModification(true); | |
| builder.SetRenderFunc((CompositePD d, RasterGraphContext ctx) => | |
| { | |
| ctx.cmd.SetGlobalTexture("_Clouds3D", d.clouds); | |
| s.compositeMat.SetFloat(Shader.PropertyToID("_CloudStartZ"), s.cs_CloudStartZ); | |
| s.compositeMat.SetFloat(Shader.PropertyToID("_CloudEndZ"), s.cs_CloudEndZ); | |
| ctx.cmd.SetGlobalTexture("_ShipShadowMask", d.shipMask); | |
| Blitter.BlitTexture(ctx.cmd, ctx.defaultResources.blackTexture, scaleBias, s.compositeMat, 0); | |
| }); | |
| } | |
| class CompositePD | |
| { | |
| public TextureHandle black, clouds, cloudsB, shipMask; | |
| } | |
| } | |
| // ───────────────────────── helper to stay out of internals | |
| static class RendererListHelpers | |
| { | |
| static readonly ShaderTagId[] _tags = { ShaderTagId.none }; | |
| static readonly RenderStateBlock[] _blocks = { default }; | |
| public static RendererListHandle CreateWithState(RenderGraph rg, ref CullingResults cull, DrawingSettings draw, FilteringSettings filter, RenderStateBlock stateBlock, ShaderTagId depthOnlyTag) | |
| { | |
| _tags[0] = depthOnlyTag; | |
| _blocks[0] = stateBlock; | |
| var tagNA = new NativeArray<ShaderTagId>(_tags, Allocator.Temp); | |
| var blockNA = new NativeArray<RenderStateBlock>(_blocks, Allocator.Temp); | |
| var desc = new RendererListParams(cull, draw, filter) { tagValues = tagNA, stateBlocks = blockNA, isPassTagName = false }; | |
| return rg.CreateRendererList(desc); | |
| } | |
| } | |
| public static void SetCameraMatrices(ComputeCommandBuffer cmd, ComputeShader cs, | |
| Matrix4x4 worldToCameraMatrix, | |
| Matrix4x4 cameraToWorldMatrix, | |
| Matrix4x4 inverseViewMatrix, | |
| Matrix4x4 inverseViewProjection, | |
| Matrix4x4 inverseProjectionMatrix) | |
| { | |
| cmd.SetComputeMatrixParam(cs, ShaderPropertyId.worldToCameraMatrix, worldToCameraMatrix); | |
| cmd.SetComputeMatrixParam(cs, ShaderPropertyId.cameraToWorldMatrix, cameraToWorldMatrix); | |
| cmd.SetComputeMatrixParam(cs, ShaderPropertyId.inverseViewMatrix, inverseViewMatrix); | |
| cmd.SetComputeMatrixParam(cs, ShaderPropertyId.inverseProjectionMatrix, inverseProjectionMatrix); | |
| cmd.SetComputeMatrixParam(cs, ShaderPropertyId.inverseViewAndProjectionMatrix, inverseViewProjection); | |
| } | |
| public static class ShaderPropertyId | |
| { | |
| public static readonly int glossyEnvironmentColor = Shader.PropertyToID("_GlossyEnvironmentColor"); | |
| public static readonly int subtractiveShadowColor = Shader.PropertyToID("_SubtractiveShadowColor"); | |
| public static readonly int glossyEnvironmentCubeMap = Shader.PropertyToID("_GlossyEnvironmentCubeMap"); | |
| public static readonly int glossyEnvironmentCubeMapHDR = Shader.PropertyToID("_GlossyEnvironmentCubeMap_HDR"); | |
| public static readonly int ambientSkyColor = Shader.PropertyToID("unity_AmbientSky"); | |
| public static readonly int ambientEquatorColor = Shader.PropertyToID("unity_AmbientEquator"); | |
| public static readonly int ambientGroundColor = Shader.PropertyToID("unity_AmbientGround"); | |
| public static readonly int time = Shader.PropertyToID("_Time"); | |
| public static readonly int sinTime = Shader.PropertyToID("_SinTime"); | |
| public static readonly int cosTime = Shader.PropertyToID("_CosTime"); | |
| public static readonly int deltaTime = Shader.PropertyToID("unity_DeltaTime"); | |
| public static readonly int timeParameters = Shader.PropertyToID("_TimeParameters"); | |
| public static readonly int lastTimeParameters = Shader.PropertyToID("_LastTimeParameters"); | |
| public static readonly int scaledScreenParams = Shader.PropertyToID("_ScaledScreenParams"); | |
| public static readonly int worldSpaceCameraPos = Shader.PropertyToID("_WorldSpaceCameraPos"); | |
| public static readonly int screenParams = Shader.PropertyToID("_ScreenParams"); | |
| public static readonly int alphaToMaskAvailable = Shader.PropertyToID("_AlphaToMaskAvailable"); | |
| public static readonly int projectionParams = Shader.PropertyToID("_ProjectionParams"); | |
| public static readonly int zBufferParams = Shader.PropertyToID("_ZBufferParams"); | |
| public static readonly int orthoParams = Shader.PropertyToID("unity_OrthoParams"); | |
| public static readonly int globalMipBias = Shader.PropertyToID("_GlobalMipBias"); | |
| public static readonly int screenSize = Shader.PropertyToID("_ScreenSize"); | |
| public static readonly int screenCoordScaleBias = Shader.PropertyToID("_ScreenCoordScaleBias"); | |
| public static readonly int screenSizeOverride = Shader.PropertyToID("_ScreenSizeOverride"); | |
| public static readonly int viewMatrix = Shader.PropertyToID("unity_MatrixV"); | |
| public static readonly int projectionMatrix = Shader.PropertyToID("glstate_matrix_projection"); | |
| public static readonly int viewAndProjectionMatrix = Shader.PropertyToID("unity_MatrixVP"); | |
| public static readonly int inverseViewMatrix = Shader.PropertyToID("unity_MatrixInvV"); | |
| public static readonly int inverseProjectionMatrix = Shader.PropertyToID("unity_MatrixInvP"); | |
| public static readonly int inverseViewAndProjectionMatrix = Shader.PropertyToID("unity_MatrixInvVP"); | |
| public static readonly int cameraProjectionMatrix = Shader.PropertyToID("unity_CameraProjection"); | |
| public static readonly int inverseCameraProjectionMatrix = Shader.PropertyToID("unity_CameraInvProjection"); | |
| public static readonly int worldToCameraMatrix = Shader.PropertyToID("unity_WorldToCamera"); | |
| public static readonly int cameraToWorldMatrix = Shader.PropertyToID("unity_CameraToWorld"); | |
| public static readonly int shadowBias = Shader.PropertyToID("_ShadowBias"); | |
| public static readonly int lightDirection = Shader.PropertyToID("_LightDirection"); | |
| public static readonly int lightPosition = Shader.PropertyToID("_LightPosition"); | |
| public static readonly int cameraWorldClipPlanes = Shader.PropertyToID("unity_CameraWorldClipPlanes"); | |
| public static readonly int billboardNormal = Shader.PropertyToID("unity_BillboardNormal"); | |
| public static readonly int billboardTangent = Shader.PropertyToID("unity_BillboardTangent"); | |
| public static readonly int billboardCameraParams = Shader.PropertyToID("unity_BillboardCameraParams"); | |
| public static readonly int previousViewProjectionNoJitter = Shader.PropertyToID("_PrevViewProjMatrix"); | |
| public static readonly int viewProjectionNoJitter = Shader.PropertyToID("_NonJitteredViewProjMatrix"); | |
| #if ENABLE_VR && ENABLE_XR_MODULE | |
| public static readonly int previousViewProjectionNoJitterStereo = Shader.PropertyToID("_PrevViewProjMatrixStereo"); | |
| public static readonly int viewProjectionNoJitterStereo = Shader.PropertyToID("_NonJitteredViewProjMatrixStereo"); | |
| #endif | |
| public static readonly int blitTexture = Shader.PropertyToID("_BlitTexture"); | |
| public static readonly int blitScaleBias = Shader.PropertyToID("_BlitScaleBias"); | |
| public static readonly int sourceTex = Shader.PropertyToID("_SourceTex"); | |
| public static readonly int scaleBias = Shader.PropertyToID("_ScaleBias"); | |
| public static readonly int scaleBiasRt = Shader.PropertyToID("_ScaleBiasRt"); | |
| // This uniform is specific to the RTHandle system | |
| public static readonly int rtHandleScale = Shader.PropertyToID("_RTHandleScale"); | |
| // Required for 2D Unlit Shadergraph master node as it doesn't currently support hidden properties. | |
| public static readonly int rendererColor = Shader.PropertyToID("_RendererColor"); | |
| public static readonly int ditheringTexture = Shader.PropertyToID("_DitheringTexture"); | |
| public static readonly int ditheringTextureInvSize = Shader.PropertyToID("_DitheringTextureInvSize"); | |
| public static readonly int renderingLayerMaxInt = Shader.PropertyToID("_RenderingLayerMaxInt"); | |
| public static readonly int overlayUITexture = Shader.PropertyToID("_OverlayUITexture"); | |
| public static readonly int hdrOutputLuminanceParams = Shader.PropertyToID("_HDROutputLuminanceParams"); | |
| public static readonly int hdrOutputGradingParams = Shader.PropertyToID("_HDROutputGradingParams"); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment