Unity中URP下实现深度贴花(雾效支持和BRP适配)

文章目录

  • 前言
  • 一、让我们的贴画支持雾效
    • 1、我们舍弃内部的MixFog方法
    • 2、使用 雾效混合因子 对最后输出颜色进行线性插值相乘
  • 二、在Shader中,限制贴花纹理的采样方式
    • 1、申明 纹理 和 限制采样方式的采样器
    • 2、在片元着色器进行纹理采样
  • 三、BRP适配
    • 1、C#脚本中,打开摄像机深度图
    • 2、适配代码
  • 四、最终代码
    • 1、地缝效果
    • 2、魔法阵
    • 3、芙宁娜贴花


前言

在上一篇文章中,我们实现了贴花的效果。但是,细节效果需要优化。

  • Unity中URP下实现深度贴花

我们在这篇文章中,来优化一下贴花Shader的细节。


一、让我们的贴画支持雾效

  • 原雾效使用方法是只支持不透明对象的。
  • 但是,我们的贴画是半透明的。所以,需要对其进行调整。

1、我们舍弃内部的MixFog方法

col.rgb = MixFog(col.rgb,i.fogCoord);

2、使用 雾效混合因子 对最后输出颜色进行线性插值相乘

  • 这样就可以实现 贴花 融入 雾 的效果
  • 针对Blend One One 的半透明雾效混合

col.rgb*=col.a;
col.rgb *= saturate(lerp(0.5,0,i.fogCoord));


二、在Shader中,限制贴花纹理的采样方式

  • 防止在Unity中,针对单独的纹理设置了不同的重和平铺方式,影响最终效果。

1、申明 纹理 和 限制采样方式的采样器

TEXTURE2D(_MainTex);
#define smp _linear_clamp
SAMPLER(smp);

2、在片元着色器进行纹理采样

half4 mainTex = SAMPLE_TEXTURE2D(_MainTex, smp, uv);


三、BRP适配

1、C#脚本中,打开摄像机深度图

Camera.main.depthTextureMode = DepthTextureMode.Depth;

2、适配代码

	SubShader{Tags{//渲染类型"RenderType"="Transparent"//渲染队列"Queue"="Transparent"}Pass{Blend One OneZWrite OffName "Unlit"CGPROGRAM#pragma vertex vert#pragma fragment frag#pragma multi_compile_fog// Pragmas#pragma target 2.0// Includes#include "UnityCG.cginc"sampler2D _MainTex;float4 _MainTex_ST;sampler2D _CameraDepthTexture;struct appdata{float3 positionOS : POSITION;float2 uv : TEXCOORD0;};struct v2f{float4 positionCS : SV_POSITION;float2 uv : TEXCOORD0;float3 positionOS : TEXCOORD1;float3 positionVS : TEXCOORD2;};v2f vert(appdata v){v2f o;o.positionCS = UnityObjectToClipPos(v.positionOS);o.uv = TRANSFORM_TEX(v.uv, _MainTex);o.positionOS = v.positionOS;//2、通过模型面片的求出像素在观察空间下的坐标值o.positionVS = UnityWorldToViewPos(mul(unity_ObjectToWorld,o.positionOS));return o;}half4 frag(v2f i) : SV_TARGET{//思路:float4 depthVS = 1;//1、通过深度图求出像素所在视图空间的Z值float2 screenUV = i.positionCS.xy / _ScreenParams.xy;half4 depthTex = tex2D(_CameraDepthTexture, screenUV);half depthZ = LinearEyeDepth(depthTex.r);//2、通过模型面片的求出像素在观察空间下的坐标值//这个在顶点着色器中完成//3、结合两者求出 深度图中像素的 XYZ值depthVS.z = depthZ;depthVS.xy = i.positionVS.xy * depthZ / -i.positionVS.z;//4、再将此坐标转换到模型的本地空间,把XY作为UV来进行纹理采样float4 depthWS = mul(unity_CameraToWorld, depthVS);float4 depthOS = mul(unity_WorldToObject, depthWS);float2 uv = depthOS.xz+0.5;half4 col = 0;half4 mainTex = tex2D(_MainTex,uv);col += mainTex;//针对Blend One One 的半透明雾效混合col.rgb*=col.a;return col;}ENDCG}}

四、最终代码

1、地缝效果

请添加图片描述

2、魔法阵

请添加图片描述

3、芙宁娜贴花

请添加图片描述

//深度贴花
Shader "MyShader/URP/P4_4_2"
{Properties{[Header(MainTex)]_MainTex("MainTex",2D) = "white"{}}SubShader{Tags{//告诉引擎,该Shader只用于 URP 渲染管线"RenderPipeline"="UniversalPipeline"//渲染类型"RenderType"="Transparent"//渲染队列"Queue"="Transparent"}Pass{Blend One OneZWrite OffName "Unlit"HLSLPROGRAM#pragma vertex vert#pragma fragment frag#pragma multi_compile_fog// 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)float4 _MainTex_ST;CBUFFER_ENDTEXTURE2D(_CameraDepthTexture);SAMPLER(sampler_CameraDepthTexture);TEXTURE2D(_MainTex);//SAMPLER(sampler_MainTex);#define smp _linear_clampSAMPLER(smp);//struct appdata//顶点着色器的输入struct Attributes{float3 positionOS : POSITION;float2 uv : TEXCOORD0;};//struct v2f//片元着色器的输入struct Varyings{float4 positionCS : SV_POSITION;float2 uv : TEXCOORD0;float fogCoord : TEXCOORD1;float3 positionOS : TEXCOORD2;float3 positionVS : TEXCOORD3;};//v2f vert(Attributes v)//顶点着色器Varyings vert(Attributes v){Varyings o;o.positionCS = TransformObjectToHClip(v.positionOS);o.uv = TRANSFORM_TEX(v.uv, _MainTex);o.fogCoord = ComputeFogFactor(o.positionCS.z);o.positionOS = v.positionOS;//2、通过模型面片的求出像素在观察空间下的坐标值o.positionVS = TransformWorldToView(TransformObjectToWorld(o.positionOS));return o;}//fixed4 frag(v2f i) : SV_TARGET//片元着色器half4 frag(Varyings i) : SV_TARGET{//思路:float4 depthVS = 1;//1、通过深度图求出像素所在视图空间的Z值float2 screenUV = i.positionCS.xy / _ScreenParams.xy;half4 depthTex = SAMPLE_TEXTURE2D(_CameraDepthTexture, sampler_CameraDepthTexture, screenUV);half depthZ = LinearEyeDepth(depthTex.r, _ZBufferParams);//2、通过模型面片的求出像素在观察空间下的坐标值//这个在顶点着色器中完成//3、结合两者求出 深度图中像素的 XYZ值depthVS.z = depthZ;depthVS.xy = i.positionVS.xy * depthZ / -i.positionVS.z;//4、再将此坐标转换到模型的本地空间,把XY作为UV来进行纹理采样float4 depthWS = mul(unity_CameraToWorld, depthVS);float4 depthOS = mul(unity_WorldToObject, depthWS);float2 uv = depthOS.xz + 0.5;half4 col = 0;half4 mainTex = SAMPLE_TEXTURE2D(_MainTex, smp, uv);col += mainTex;//针对Blend One One 的半透明雾效混合col.rgb *= col.a;col.rgb *= saturate(lerp(1, 0, i.fogCoord));//col.rgb = MixFog(col.rgb,i.fogCoord);return col;}ENDHLSL}}SubShader{Tags{//渲染类型"RenderType"="Transparent"//渲染队列"Queue"="Transparent"}Pass{Blend One OneZWrite OffName "Unlit"CGPROGRAM#pragma vertex vert#pragma fragment frag#pragma multi_compile_fog// Pragmas#pragma target 2.0// Includes#include "UnityCG.cginc"sampler2D _MainTex;float4 _MainTex_ST;sampler2D _CameraDepthTexture;struct appdata{float3 positionOS : POSITION;float2 uv : TEXCOORD0;};struct v2f{float4 positionCS : SV_POSITION;float2 uv : TEXCOORD0;float3 positionOS : TEXCOORD1;float3 positionVS : TEXCOORD2;};v2f vert(appdata v){v2f o;o.positionCS = UnityObjectToClipPos(v.positionOS);o.uv = TRANSFORM_TEX(v.uv, _MainTex);o.positionOS = v.positionOS;//2、通过模型面片的求出像素在观察空间下的坐标值o.positionVS = UnityWorldToViewPos(mul(unity_ObjectToWorld, o.positionOS));return o;}half4 frag(v2f i) : SV_TARGET{//思路:float4 depthVS = 1;//1、通过深度图求出像素所在视图空间的Z值float2 screenUV = i.positionCS.xy / _ScreenParams.xy;half4 depthTex = tex2D(_CameraDepthTexture, screenUV);half depthZ = LinearEyeDepth(depthTex.r);//2、通过模型面片的求出像素在观察空间下的坐标值//这个在顶点着色器中完成//3、结合两者求出 深度图中像素的 XYZ值depthVS.z = depthZ;depthVS.xy = i.positionVS.xy * depthZ / -i.positionVS.z;//4、再将此坐标转换到模型的本地空间,把XY作为UV来进行纹理采样float4 depthWS = mul(unity_CameraToWorld, depthVS);float4 depthOS = mul(unity_WorldToObject, depthWS);float2 uv = depthOS.xz + 0.5;half4 col = 0;half4 mainTex = tex2D(_MainTex, uv);col += mainTex;//针对Blend One One 的半透明雾效混合col.rgb *= col.a;return col;}ENDCG}}
}

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

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

相关文章

仿真验证方法(3)——物理验证

目录 一、物理验证的分类 二、DRC 2.1 设计规则 2.2 规则示例 2.3 线宽违例 2.4 间距违例 2.5 交叠违例 三、金属覆盖图形密度检查 四、天线比率检查 4.1 起因 4.2 计算 4.3 改进 五、LVS检查 六、物理验证常用的EDA工具 七、总结 一、物理验证的分类 对于物理验…

专业课145+合肥工业大学833信号分析与处理考研经验合工大电子信息通信

今年专业课145也是考研科目中最满意的一门,其他基本相对平平,所以这里我总结一下自己的专业课合肥工业大学833信号分析与处理的复习经验。 我所用的教材是郑君里的《信号与系统》(第三版)和高西全、丁玉美的《数字信号处理》&…

java方法的定义和使用

方法 今日目标: 能够知道方法的好处 能够根据两个明确分析方法的参数和返回值 能够编写方法完成授课案例,并在主方法中完成方法的调用 能够知道方法重载及其特点 1:方法的定义和使用 1.1 方法概述 方法(method):就是完成特…

Java常用的加密技术

项目结构: 总体代码: package VirtualUtils; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import java.io.UnsupportedEncodingException; import java.security.*; import java.security.sp…

深入浅出线程原理

Linux 中的线程本质 线程接口由 Native POSIX Thread Library 提供,即:NPTL 库函数 线程被称为轻量级进程 (Light Weight Process) 每一个线程在内核中都对应一个调度实体,拥有独立的结构体 (task_struct) 内核设计:一个进程对…

【python】matplotlib画图常用功能汇总

目录: 一、matplotlib画图风格二、matplotlib图像尺寸和保存分辨率三、matplotlib子图相关功能创建子图:绘制子图:设置子图属性:调整布局:示例代码: 四、matplotlib字体设置字体族和字体的区别字体选择和设置1. Matplo…

亚马逊云科技 WAF 部署小指南(五):在客户端集成 Amazon WAF SDK 抵御 DDoS 攻击...

方案介绍 在 WAF 部署小指南(一)中,我们了解了 Amazon WAF 的原理,并通过创建 WEB ACL 和托管规则防护常见的攻击。也了解了通过创建自定义规则在 HTTP 请求到达应用之前判断是阻断还是允许该请求。在 Amazon WAF 自定义规则中&am…

水果音乐编曲软件 FL Studio v21.2.2.3914 中文免费版(附中文设置教程)

FL studio21中文别名水果编曲软件,是一款全能的音乐制作软件,包括编曲、录音、剪辑和混音等诸多功能,让你的电脑编程一个全能的录音室,它为您提供了一个集成的开发环境,使用起来非常简单有效,您的工作会变得…

【书生·浦语】大模型实战营——第四课作业

教程文档:https://github.com/InternLM/tutorial/blob/main/xtuner/self.md 基础作业需要构建数据集,微调模型,让其明白自己的弟位(OvO!) 微调环境准备 进入开发机后,先bash,再创…

列表解析与快速排序

排序是在对文本、数值等数据进行操作时常用的功能,本文介绍两种常用的排序方式,借此学习列表解析,并巩固递归算法。 1 选择排序 说到排序,以数值为例,肯定涉及到值大小的对比,选择排序即通过依次在子集中…

蓝桥杯 python 第二题 数列排序

这里给出一种解法 """ # 错的 n int(input()) dp[int(i) for i in input().split(" ")] dp.sort() print(" ".join(str(i) for i in dp)) """#这个是对的 num int(input())l list(map(int, input().split()))l.sort()pr…

AI文本生图模型Stable Diffusion部署教程

本文基于CentOS8进行Stable Diffusion开源框架部署. 1. DNS配置(但是今天出现了偶尔无法下载问题) 为了加速Github访问,我在本机配置如下 (sd) [rootshenjian stable-diffusion-webui]# cat /etc/hosts 127.0.0.1 shenjian localhost localhost.localdomain localhost4 loca…

修改权限控制(chmod命令、chown命令)

1.chmod命令 功能:修改文件、文件夹权限(注意,只有文件、文件夹的所属用户或root用户可以修改) 语法:chmod [-R] 权限 参数 权限,要设置的权限,比如755,表示:rwxr-xr-x…

【面试突击】生产部署面试实战

🌈🌈🌈🌈🌈🌈🌈🌈 欢迎关注公众号(通过文章导读关注:【11来了】),及时收到 AI 前沿项目工具及新技术 的推送 发送 资料 可领取 深入理…

如何从电脑找回/恢复误删除的照片

按 Shift Delete 以后会后悔吗?想要恢复已删除的照片吗?好吧,如果是这样的话,那么您来对地方了。在本文中,我们将讨论如何从 PC 中检索已删除的文件。 自从摄影的概念被曝光以来,人们就对它着迷。早期的照…

Markdown编辑器

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

Windows Server 2012 R2部署项目

JDK 下载JDK 1.直接官网下载:http://www.oracle.com/; 2.我用的是1.8,阿里云盘分享地址:https://www.aliyundrive.com/s/u4V9x1AHL2r 安装jdk 双击安装点击下一步如果不改变路径就一直下一步 安装完成直接点击关闭即可&#x…

GPT Store,是否会成为下一个App Store?

经历了一场风波后,原本计划推出的GPT Store终于成功上线。OpenAI在北京时间1月11日推出了GPT Store,被广泛视为类似于苹果的"App Store",为人工智能应用生态系统迈出了重要一步。然而,OpenAI要想将GPT Store打造成苹果般…

一、docker的安装与踩坑

目录 一、安装docker(centos7安装docker)1.安装环境前期准备2.参考官网安装前准备3.参考官网安装步骤开始安装docker4.运行首个容器 二、安装一些软件的踩坑1.启动docker踩坑2.安装mysql踩坑3.罕见问题 三、关于我的虚拟机 一、安装docker(ce…

如何再造宇宙厂所有APP?

本文内容,纯属十年老架构师杜撰,切勿照着实操,可能会给你带来几十亿的流量,怕你的服务器扛不住。 1. 破音 前端用uniapp,花800买个短视频应用模板,后端用golang支持高并发, 数据库用图数据库加elastic se…