Unity中URP实现水体效果(水的深度)

文章目录

  • 前言
  • 一、搭建预备场景
    • 1、新建一个面片,使其倾斜一个角度,来模拟水底和岸边的效果
    • 2、随便创建几个物体,作为与水面接触的物体
    • 3、再新建一个面片,作为水面
  • 二、开始编写水体的Shader效果
    • 1、新建一个URP基础Shader
    • 2、把水体Shader分解为以下几个部分
  • 三、实现水的深度效果
    • 1、在URP管线设置下,打开深度图
    • 2、在SubShader中,申明深度图纹理和采样器
    • 3、修改水体渲染为半透明队列
    • 4、在Pass中关闭深度写入
    • 5、获取水体顶点在观察空间下的坐标
    • 6、把采样到的深度图转化到观察空间下
    • 7、最后,用观察空间下的 深度图 和 水体顶点坐标的Z值相加即可
  • 四、最终代码 及 效果
    • 1、最终效果
    • 2、最终代码


前言

在之后的文章中,我们在URP下实现水面的效果。
在该文章中,我们来看一下水的深度是怎么实现的。


一、搭建预备场景

1、新建一个面片,使其倾斜一个角度,来模拟水底和岸边的效果

在这里插入图片描述

2、随便创建几个物体,作为与水面接触的物体

在这里插入图片描述

3、再新建一个面片,作为水面

在这里插入图片描述


二、开始编写水体的Shader效果

1、新建一个URP基础Shader

//水的深度
Shader "MyShader/URP/P4_7_2"
{Properties {}SubShader{Tags{//告诉引擎,该Shader只用于 URP 渲染管线"RenderPipeline"="UniversalPipeline"//渲染类型"RenderType"="Opaque"//渲染队列"Queue"="Geometry"}Pass{Name "Universal Forward"Tags{// LightMode: <None>}Cull BackBlend One ZeroZTest LEqualZWrite OnHLSLPROGRAM#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/Input.hlsl"//struct appdata//顶点着色器的输入struct Attributes{float3 positionOS : POSITION;};//struct v2f//片元着色器的输入struct Varyings{float4 positionCS : SV_POSITION;};//v2f vert(Attributes v)//顶点着色器Varyings vert(Attributes v){Varyings o = (Varyings)0;float3 positionWS = TransformObjectToWorld(v.positionOS);o.positionCS = TransformWorldToHClip(positionWS);return o;}//fixed4 frag(v2f i) : SV_TARGET//片元着色器half4 frag(Varyings i) : SV_TARGET{//水的深度//水的高光//水的反射//水的焦散//水下的扭曲half4 c;c.rgb = 0.5;c.a = 1;return c;}ENDHLSL}}FallBack "Hidden/Shader Graph/FallbackError"
}

2、把水体Shader分解为以下几个部分

  • 水的深度
  • 水的高光
  • 水的反射
  • 水的焦散
  • 水下的扭曲
  • 水面泡沫

三、实现水的深度效果

这个可以利用深度图,仿照之前能量罩交接处高光的效果来做

  • Unity中URP下实现能量罩(交接处高亮)

1、在URP管线设置下,打开深度图

在这里插入图片描述

2、在SubShader中,申明深度图纹理和采样器

//申明深度图的 纹理 和 采样器
TEXTURE2D(_CameraDepthTexture);SAMPLER(sampler_CameraDepthTexture);

3、修改水体渲染为半透明队列

Tags
{
//告诉引擎,该Shader只用于 URP 渲染管线
“RenderPipeline”=“UniversalPipeline”
//渲染类型
“RenderType”=“Transparent”
//渲染队列
“Queue”=“Transparent”
}

4、在Pass中关闭深度写入

ZWrite Off

5、获取水体顶点在观察空间下的坐标

  • 在Varyings结构体,定义positionVS变量,用于存储顶点在观察空间下的坐标

struct Varyings
{
float4 positionCS : SV_POSITION;
float2 uv : TEXCOORD0;
float3 positionVS : TEXCOORD1;
};

  • 在顶点着色器中,对把顶点转化到观察空间下

o.positionVS = TransformWorldToView(positionWS);

6、把采样到的深度图转化到观察空间下

float depthScene = LinearEyeDepth(depthTex,_ZBufferParams);

7、最后,用观察空间下的 深度图 和 水体顶点坐标的Z值相加即可

float4 depthWater = depthhScene + i.positionVS.z;


四、最终代码 及 效果

1、最终效果

在这里插入图片描述

2、最终代码

//水的深度
Shader "MyShader/URP/P4_8_2"
{Properties {}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)CBUFFER_ENDTEXTURE2D(_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;float3 positionVS : TEXCOORD2;};//v2f vert(Attributes v)//顶点着色器Varyings vert(Attributes v){Varyings o = (Varyings)0;float3 positionWS = TransformObjectToWorld(v.positionOS);o.positionVS = TransformWorldToView(positionWS);o.positionCS = TransformWViewToHClip(o.positionVS);o.screenPos = ComputeScreenPos(o.positionCS);return o;}//fixed4 frag(v2f i) : SV_TARGET//片元着色器half4 frag(Varyings i) : SV_TARGET{//1、水的深度//获取屏幕空间下的 UV 坐标float2 screenUV = i.positionCS.xy / _ScreenParams.xy;half depthTex = SAMPLE_TEXTURE2D(_CameraDepthTexture,sampler_CameraDepthTexture,screenUV).x;//深度图转化到观察空间下float depthScene = LinearEyeDepth(depthTex,_ZBufferParams);float4 depthWater = depthScene + i.positionVS.z;//获取水面模型顶点在观察空间下的Z值(可以在顶点着色器中,对其直接进行转化得到顶点观察空间下的坐标)//2、水的高光//3、水的反射//4、水的焦散//5、水下的扭曲//6、水面泡沫return depthWater;}ENDHLSL}}FallBack "Hidden/Shader Graph/FallbackError"
}

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

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

相关文章

knife4j springboot3使用

简介 在日常开发中&#xff0c;写接口文档是我们必不可少的&#xff0c;而Knife4j就是一个接口文档工具&#xff0c;可以看作是Swagger的升级版&#xff0c;但是界面比Swagger更好看&#xff0c;功能更丰富 使用 我使用的是springboot3.2.3 knife4j 4.3.0,knife4j 4.4版本有…

自动化操作读写Excel —— xlrd 和 xlwt 模块参数说明与代码实战【第95篇—自动化操作读写Excel 】

自动化操作读写Excel —— xlrd 和 xlwt 模块参数说明与代码实战 在日常工作中&#xff0c;Excel表格是不可或缺的数据处理工具。为了提高工作效率&#xff0c;Python中的xlrd和xlwt模块为我们提供了强大的功能&#xff0c;使得自动化操作Excel变得更加简便。本文将介绍xlrd和…

「优选算法刷题」:两数之和

一、题目 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能重复出现。 你可以按任…

【心得】如何做一个靠谱的程序员

你是否曾经遇到过一些不应该出现的小 BUG &#xff0c;比如路径错了一个字母&#xff0c;进而找不到文件 File no found&#xff0c; 写的小功能 直接用错了变量&#xff0c;进而出现一些莫名其妙的问题。这些问题容易解决&#xff0c;但也浪费了我们不少时间。 那么&#xff…

利用nginx内部访问特性实现静态资源授权访问

在nginx中&#xff0c;将静态资源设为internal&#xff1b;然后将前端的静态资源地址改为指向后端&#xff0c;在后端的响应头部中写上静态资源地址。 近期客户对我们项目做安全性测评&#xff0c;暴露出一些安全性问题&#xff0c;其中一个是有些静态页面&#xff08;*.html&…

线性代数:向量、张量、矩阵和标量

线性代数&#xff1a;向量、张量、矩阵和标量 背景 在线性代数中&#xff0c;向量、张量、矩阵和标量都属于基础概念&#xff0c;特别是最近AI的爆火&#xff0c;向量和张量的概念也越来越普及&#xff0c;本文将介绍下这些基本概念。 1. 标量&#xff08;Scalar&#xff0…

QT QString和QStringLiteral的区别

一、理解QStringLiteral 1、QStringLiteral是Qt提供的一个宏&#xff0c;用于在编译时创建一个QString对象。它的主要作用是将字符串字面值转换为QString对象&#xff0c;同时提高运行性能和减少内存占用。 2、使用QStringLiteral宏可以避免在运行时创建QString对象&#xff…

GORM入门到精通:构建高效Go应用的终极指南

文章目录 什么是GORM&#xff1f;为什么选择GORM&#xff1f; GORM的基本使用GORM的高级特性关联事务钩子 数据迁移与模型定义数据迁移模型定义 预加载与关联查询预加载关联查询 查询构建器基本查询条件查询范围查询排序、分组和限制 事务管理开始事务事务操作提交事务 钩子&am…

【正则】正则表达式总结

文章目录 1 语法总结2 常用匹配表达式2.1 日期匹配2.2 go实现IP匹配 Reference 1 语法总结 元字符&#xff1a; .&#xff1a;匹配任意单个字符&#xff08;除了换行符&#xff09;。 *&#xff1a;匹配前面的子表达式零次或多次。 &#xff1a;匹配前面的子表达式一次或多次。…

2024牛客寒假算法基础集训营5

K soyorin的通知 完全背包加不少于的模型 由于人数只有1000&#xff0c;那么 bi 实际有效的范围只有1000左右&#xff0c;并且&#xff0c;soyorin至少要花一次 p 的代价将消息通知给 1 个人&#xff0c;然后再让这个人去将消息通知给剩下的 n−1 个人。 ​ 那么问题就转化…

解密与恢复:应对. helper勒索病毒的实用建议

引言&#xff1a; 近年来&#xff0c;勒索病毒已成为网络安全领域的一大威胁&#xff0c;而其中一种名为.helper的勒索病毒备受关注。本文将介绍.helper勒索病毒的特点、数据恢复方法以及预防措施&#xff0c;帮助读者更好地理解和防范这种恶意软件的攻击。如不幸感染这个勒索…

【深度学习目标检测】十八、基于深度学习的人脸检测系统-含GUI和源码(python,yolov8)

人脸检测是计算机视觉中的一个重要方向&#xff0c;也是一个和人们生活息息相关的研究方向&#xff0c;因为人脸是人最重要的外貌特征。人脸检测技术的重要性主要体现在以下几个方面&#xff1a; 人脸识别与安全&#xff1a;人脸检测是人脸识别系统的一个关键部分&#xff0c;是…

二维矩阵子集的最大值

登录—专业IT笔试面试备考平台_牛客网 正好遇到了 对于一维,我们只需要贪一次 int ans -1E9; int suf -1E9; for (int i 0; i < n; i) {if (i && (a[i] - a[i - 1]) % 2 0) {suf 0;}suf std::max(suf, 0) a[i];ans std::max(ans, suf); } ans就是最大值…

UglifyJS 对 js 文件进行压缩

简介 UglifyJS 是一款对 JS 代码进行压缩的工具 使用 1、安装 UglifyJS winr 输入 cmd 打开命令提示窗口&#xff0c;打开后运行&#xff1a; npm install uglify-js -g 2、对指定 js 文件进行压缩 在命令提示窗口中进入&#xff08;cd&#xff09;到需要压缩的 js 文件所…

Half-Band filter(半带滤波器)

Half-Band filter 引言正文symmetric half-band filtersamplitude half-band filterspower half-band filters引言 今天看文章的时候遇到了一个名词,Half-Band filter,中文名称半带滤波器,特来记录一下。 正文 假设我们通过采样获取到的信号带宽为 f s f_s

编程笔记 Golang基础 025 列表

编程笔记 Golang基础 025 列表 一、列表的功能二、示例程序三、注意事项 在 Go 语言中&#xff0c;列表是一种数据结构&#xff0c;用于存储有序的元素集合&#xff0c;允许高效地进行插入和删除操作。Go 标准库中的 container/list 包提供了一个内置的双链表实现&#xff0c;它…

2023华为od机试题以及答案解析

求字符串中所有整数的最小和 输入字符串 s&#xff0c;输出 s 中包含所有整数的最小和说明&#xff1a; 字符串 s&#xff0c;只包含 a-z A-Z &#xff1b; 合法的整数包括&#xff1a; 1&#xff09; 正整数 一个或者多个 0-9 组成&#xff0c;如 0 2 3 002 102 2&#xff0…

选择适合你的编程语言

引言 在当今瞬息万变的技术领域中&#xff0c;选择一门合适的编程语言对于个人职业发展和技术成长至关重要。每种语言都拥有独特的设计哲学、应用场景和市场需求&#xff0c;因此&#xff0c;在决定投入时间和精力去学习哪种编程语言时&#xff0c;我们需要综合分析多个因素&a…

力扣热题100_普通数组_56_合并区间

文章目录 题目链接解题思路解题代码 题目链接 56. 合并区间 以数组 intervals 表示若干个区间的集合&#xff0c;其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间&#xff0c;并返回 一个不重叠的区间数组&#xff0c;该数组需恰好覆盖输入中的所有区…

Nginx跳转模块之rewrite

一.location与rewrite模块的区别 rewrite&#xff1a;对访问的域名或者域名内的URL路径地址重写 location&#xff1a;对访问的路径做访问控制或者代理转发 二.rewrite模块基本内容 1.功能 通过正则表达式的匹配来改变URI&#xff0c;可以同时存在一个或多个指令&#xff0c…