Unity中URP下使用屏幕坐标采样深度图

文章目录

  • 前言
  • 一、Unity使用了ComputeScreenPos函数得到屏幕坐标
    • 1、 我们来看一下这个函数干了什么
    • 2、我们看一下该函数实现该结果的意义
  • 二、在Shader中使用(法一)
    • 1、在Varying结构体中
    • 2、在顶点着色器中
    • 3、在片元着色器中
  • 三、在Shader中使用(法二)
    • 1、在片元着色器中
  • 四、最终效果


前言

在上一篇文章中,我们实现了URP下深度图的使用。

  • Unity中URP下开启和使用深度图

但是,因为是使用模型UV采样的原因。所以,深度图效果不对

请添加图片描述

所以,在这一篇文章中,我们使用屏幕坐标来采样深度图。


一、Unity使用了ComputeScreenPos函数得到屏幕坐标

1、 我们来看一下这个函数干了什么

在这里插入图片描述

齐次裁剪空间进行透视除法

  • x n d c = x w x_{ndc} = \frac{x}{w} xndc=wx

然后进行如下步骤,化简得到该函数结果

  • x s c r e e n = ( x n d c ∗ 0.5 + 0.5 ) ∗ w i d t h x_{screen} = (x_{ndc}*0.5+0.5)*width xscreen=(xndc0.5+0.5)width
  • x s c r e e n = ( x w ∗ 0.5 + 0.5 ) ∗ w i d t h x_{screen} = (\frac{x}{w}*0.5+0.5)*width xscreen=(wx0.5+0.5)width
  • x s c r e e n w i d t h = ( x w ∗ 0.5 + 0.5 ) \frac{x_{screen}}{width}=(\frac{x}{w}*0.5+0.5) widthxscreen=(wx0.5+0.5)
  • x s c r e e n w i d t h ∗ w = ( x ∗ 0.5 + w ∗ 0.5 ) \frac{x_{screen}}{width}*w=(x*0.5+w*0.5) widthxscreenw=(x0.5+w0.5)

2、我们看一下该函数实现该结果的意义

x s c r e e n w i d t h ∗ w \frac{x_{screen}}{width}*w widthxscreenw

  • x s c r e e n = 0 x_{screen} = 0 xscreen=0
    x s c r e e n w i d t h ∗ w = 0 \frac{x_{screen}}{width}*w = 0 widthxscreenw=0

  • x s c r e e n = w i d t h x_{screen} =width xscreen=width
    x s c r e e n w i d t h ∗ w = w \frac{x_{screen}}{width}*w = w widthxscreenw=w

  • 得到最终o的范围

  • ( [ 0 , w ] , [ 0 , w ] , z , w ) ([0,w],[0,w],z,w) ([0,w],[0,w],z,w)

  • ( [ 0 , w ] w , [ 0 , w ] w , z w , 1 ) (\frac{[0,w]}{w},\frac{[0,w]}{w},\frac{z}{w},1) (w[0,w],w[0,w],wz,1)

  • ( [ 0 , 1 ] , [ 0 , 1 ] , z w , 1 ) ([0,1],[0,1],\frac{z}{w},1) ([0,1],[0,1],wz,1)


二、在Shader中使用(法一)

1、在Varying结构体中

float4 screenPos : TEXCOORD1;

2、在顶点着色器中

o.screenPos = ComputeScreenPos(o.positionCS);

3、在片元着色器中

float2 uv = i.screenPos.xy / i.screenPos.w;

float4 cameraDepthTex = SAMPLE_TEXTURE2D(_CameraDepthTexture,sampler_CameraDepthTexture,uv);
float depthTex = Linear01Depth(cameraDepthTex,_ZBufferParams);
return depthTex;


三、在Shader中使用(法二)

  • 原理:用 齐次裁剪坐标 屏幕宽高 \frac{齐次裁剪坐标} {屏幕宽高} 屏幕宽高齐次裁剪坐标刚好得到[0,1]之间的屏幕uv坐标

1、在片元着色器中

float2 uv = i.positionCS/ _ScreenParams.xy;

float4 cameraDepthTex = SAMPLE_TEXTURE2D(_CameraDepthTexture,sampler_CameraDepthTexture,uv);
float depthTex = Linear01Depth(cameraDepthTex,_ZBufferParams);
return depthTex;


四、最终效果

请添加图片描述

Shader "MyShader/URP/P4_1"
{Properties {_Color("Color",Color) = (0,0,0,0)_MainTex("MainTex",2D) = "white"{}}SubShader{Tags{//告诉引擎,该Shader只用于 URP 渲染管线"RenderPipeline"="UniversalPipeline"//渲染类型"RenderType"="Transparent"//渲染队列"Queue"="Transparent"}//Blend One OneZWrite OffPass{Name "Unlit"HLSLPROGRAM#pragma vertex vert#pragma fragment frag// Pragmas#pragma target 2.0// Includes#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl"CBUFFER_START(UnityPerMaterial)half4 _Color;CBUFFER_END//纹理的定义,如果是编译到GLES2.0平台,则相当于sample2D _MainTex;否则相当于 Texture2D _MainTex;TEXTURE2D(_MainTex);SAMPLER(SamplerState_linear_mirrorU_ClampV); float4 _MainTex_ST;TEXTURE2D(_CameraDepthTexture);SAMPLER(sampler_CameraDepthTexture);//struct appdata//顶点着色器的输入struct Attributes{float3 positionOS : POSITION;float2 uv : TEXCOORD0;};//struct v2f//片元着色器的输入struct Varyings{float4 positionCS : SV_POSITION;float2 uv : TEXCOORD0;float4 screenPos : TEXCOORD1;};//v2f vert(Attributes v)//顶点着色器Varyings vert(Attributes v){Varyings o = (Varyings)0;float3 positionWS = TransformObjectToWorld(v.positionOS);o.positionCS = TransformWorldToHClip(positionWS);o.uv = TRANSFORM_TEX(v.uv,_MainTex);o.screenPos = ComputeScreenPos(o.positionCS);return o;}//fixed4 frag(v2f i) : SV_TARGET//片元着色器half4 frag(Varyings i) : SV_TARGET{half4 c;float4 mainTex = SAMPLE_TEXTURE2D(_MainTex,SamplerState_linear_mirrorU_ClampV,i.uv);//c = _Color *  mainTex;//深度图//float2 uv = i.screenPos.xy / i.screenPos.w;float2 uv = i.positionCS/ _ScreenParams.xy;float4 cameraDepthTex = SAMPLE_TEXTURE2D(_CameraDepthTexture,sampler_CameraDepthTexture,uv);float depthTex = Linear01Depth(cameraDepthTex,_ZBufferParams);return depthTex;}ENDHLSL}}FallBack "Hidden/Shader Graph/FallbackError"
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/333444.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux 使用log4cpp记录项目日志

为什么要用log4cpp记录项目日志 在通常情况下,Linux/UNIX 每个程序在开始运行的时刻,都会打开 3 个已经打开的 stream. 分别用来输入,输出,打印错误信息。通常他们会被连接到用户终端。这 3 个句柄的类型为指向 FILE 的指针。可以…

物理环境测评

1.1 物理位置选择 1.1.1 防震防风防雨 安全要求 机房场地选择在具有防震防风防雨等能力的建筑内 测评方法 核查是否有建筑物抗震设防审批文档 核查是否有雨水渗透的痕迹 核查是否有可灵活开启的窗户,若有窗户,是否做了封闭,上锁等防护措…

mongodb基本命令操作

1.创建数据库 语法 use 数据库名字例如:创建hero数据库 use hero查询当前数据库 db如果想查询所有的数据库 show dbs发现并没有刚刚创建的数据库,如果要显示创建的数据库,需要向表中插入一条记录 db.hero.insert({name: "zs",age: 20,country: "china&quo…

【grpc】利用protobuf实现java或kotlin调用python脚本,含实现过程和全部代码

前言 在一些特殊场景中,我们可能需要使用java或者其他任意语言调用python脚本或sdk等。本文的需求衍生也不例外于此,python端有sdk,但只能在python中调用,于是就有了本文章。 常见的调用方式如jython、python提供http rest接口、…

余震强度预测能力升级,Nature 刊文认证基于神经网络的模型性能优于传统模型

作者:李宝珠 编辑:李玮栋、xixi,三羊 地震的发生涉及诸多变量,「预测」存在挑战,但余震发生次数及强度的预测已取得重大进展。 2023 年 12 月 18 日 23 时 59 分,甘肃省临夏州积石山县发生 6.2 级地震&…

你好,2024!再见,2023!

大家好,我是南城余! 今天是2023年最后一天,看到各位大佬都在分享今年的总结,我也来做个年度总结,是第一次做年度总结,希望以后可以每年都做一个好好的回顾。 说来可笑,标题,2023怎么…

tcp/ip协议2实现的插图,数据结构6 (24 - 章)

(142) 142 二四1 TCP传输控制协议 tcpstat统计量与tcp 函数调用链 (143) 143 二四2 TCP传输控制协议 宏定义与常量值–上 (144) 144 二四3 TCP传输控制协议 宏定义与常量值–下 (145) 145 二四4 TCP传输控制协议 结构tcphdr,tcpiphdr (146) 146 二四5 TCP传输控制协议 结构 tcp…

R语言(12):绘图

12.1 创建图形 12.1.1 plot函数 plot(c(1,2,3),c(1,2,4)) plot(c(1,2,3),c(1,2,4),"b") plot(c(-3,3),c(-1,5),"n",xlab "x",ylab "y")12.1.2 添加线条&#xff1a;abline()函数 x <- c(1,2,3) y <- c(1,3,8) plot(x,y) lm…

MySQL万字超详细笔记❗❗❗

MySQL 官网&#xff1a;https://dev.mysql.com/doc/refman/8.0/en/database-use.html 作用&#xff1a;管理逻辑上存在但物理上不存在的数据库和表等大数据环境中的静态资源。 它用于存储结果数据和其他小型数据&#xff0c;避免在大数据环境中存放。 要展示数据成果&#xff…

基于单片机设计的智慧农业大棚检测系统

一、设计目标 本项目基于单片机设计一个智慧农业大棚检测系统&#xff0c;以提供实时监测和管理大棚环境的关键参数。系统支持环境温度、湿度检测&#xff0c;光照强度检测&#xff0c;并能根据预设的阀值进行报警提示。为了实现数据的显示和管理&#xff0c;该系统还利用Qt开…

Linux--系统安全及应用

1.1账号安全控制 用户账号是计算机使用者的身份凭证或标识&#xff0c;每个要访问系统资源的人&#xff0c;必须凭借其用户账号才能进入计算机。在Linux系统中&#xff0c;提供了多种机制来确保用户账号的正当、安全使用。 1.系统账号清理 在Linux系统中&#xff0c;除了用户手…

苹果QQ群聊天记录怎么删除?收藏好这两个技巧!

无论我们使用什么手机&#xff0c;我们都可以在QQ上与好友进行交流和社交。然而&#xff0c;有时候我们可能需要删除一些不需要的聊天记录&#xff0c;特别是群聊记录&#xff0c;以此来扩大手机内存。那么&#xff0c;苹果手机的qq群聊天记录怎么删除呢&#xff1f;小编将为大…