本文主要是介绍Unity URP Fullscreen 全屏特效 绘制全屏四边面并重建世界空间位置,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
在URP中我们可以插入自己的RenderFeature来实现一些特殊的效果。
首先我们需要创建两个C#类,分别继承ScriptableRendererFeature
、ScriptableRenderPass
。
这里我创建了TestRenderFeature
和TestPass
。
我在TestRenderFeature
的Create
方法中初始化TestPass
,在AddRenderPasses
中调用renderer.EnqueuePass(_testPass);
执行相关的渲染操作。
TestRenderFeature.cs
public class TestRenderFeature : ScriptableRendererFeature{public Material _material;private TestPass _testPass;public override void Create(){if (_material== null){Debug.LogError("material can't be null");}_testPass=new TestPass (_material);}public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData){renderer.EnqueuePass(_testPass);}}
TestPass.cs
public class TestPass : ScriptableRenderPass
{const string m_ProfilerTag = "Test Pass";private Material material;public TestPass (Material material){this.material = material;renderPassEvent = RenderPassEvent.AfterRenderingTransparents;// 设置Pass插入的位置}public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData){if (material == null)return;var camera = renderingData.cameraData.camera;var cmd = CommandBufferPool.Get(m_ProfilerTag);///以下为绘制全屏四边面的代码/cmd.SetViewProjectionMatrices(Matrix4x4.identity, Matrix4x4.identity);cmd.DrawMesh(RenderingUtils.fullscreenMesh, Matrix4x4.identity, material);cmd.SetViewProjectionMatrices(camera.worldToCameraMatrix, camera.projectionMatrix);context.ExecuteCommandBuffer(cmd);CommandBufferPool.Release(cmd);}
}
Shader相关代码
使用GetPositionInput
,传入屏幕坐标、屏幕尺寸的倒数、原始深度、UNITY_MATRIX_I_VP、UNITY_MATRIX_V,返回一个PositionInputs类型的结构体,结构体内包含世界空间坐标(positionWS)、归一化的屏幕坐标positionNDC
、线性深度linearDepth
。
这个函数定义在com.unity.render-pipelines.core\ShaderLibrary\Common.hlsl
,我使用的版本为8.2.0
Pass{ZTest AlwaysZWrite Off//用HLSL吧HLSLPROGRAM#pragma vertex vert#pragma fragment frag//记得引入这个头文件#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;};struct v2f{float2 uv : TEXCOORD0;float4 vertex : SV_POSITION;};v2f vert (appdata v){v2f o;o.vertex = TransformObjectToHClip(v.vertex);//uv直接传过去即可o.uv=v.uv;return o;}float4 frag (v2f i) : SV_Target{float depth = LoadSceneDepth(i.uv*_ScreenParams.xy);//PositionInputs GetPositionInput(float2 positionSS, float2 invScreenSize, float deviceDepth,float4x4 invViewProjMatrix, float4x4 viewMatrix)//这里的i.uv实际上相当于归一化的屏幕坐标,让它乘以屏幕尺寸得到未归一化的屏幕坐标 PositionInputs inputs= GetPositionInput(i.uv * _ScreenParams.xy, _ScreenParams.zw-1, depth,UNITY_MATRIX_I_VP,UNITY_MATRIX_V);return float4(min(inputs.positionWS.x,1),min(inputs.positionWS.y,1),min(inputs.positionWS.z,1),1);}ENDHLSL}
效果图
这篇关于Unity URP Fullscreen 全屏特效 绘制全屏四边面并重建世界空间位置的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!