Unity中URP实现水体(水下的扭曲)
文章目录
- 前言
- 一、使用一张法线纹理,作为水下扭曲的纹理
- 1、在属性面板定义一个纹理,用于传入法线贴图
- 2、在Pass中,定义对应的纹理和采样器
- 3、在常量缓冲区,申明修改 Tilling 和 Offset 的ST
- 4、在顶点着色器,计算得到 应用了 ST 和 随时间流动的UV,用于纹理采样(_WaterSpeed是上篇文章中用到的)
- 5、在片元着色器中,对其进行法线纹理进行采样
- 二、实现水下扭曲的效果
- 1、定义一个扰度值,控制扭曲水下的扭曲程度
- 2、在URP设置中,开启抓屏
- 3、在Pass中,定义抓屏的 纹理 和 采样器
- 4、使用线性插值后的结果,进行抓屏的纹理采样
- 5、最后,与上篇文章计算得到的水的颜色混合
- 请添加图片描述
- 三、最终代码
前言
在上篇文章中,我们实现了水体中 和 物体接触时,产生泡沫的效果。
- Unity中URP实现水体效果(泡沫)
在这篇文章中,我们在上一篇文章的基础上来实现水下扭曲的效果。
一、使用一张法线纹理,作为水下扭曲的纹理
原理:
- Unity中Shader的UV扭曲效果的实现
1、在属性面板定义一个纹理,用于传入法线贴图
_DistortTex(“DistortNormalTex”,2D) = “white”{}

2、在Pass中,定义对应的纹理和采样器
TEXTURE2D(_DistortTex);SAMPLER(sampler_DistortTex);
3、在常量缓冲区,申明修改 Tilling 和 Offset 的ST
half4 _DistortTex_ST;
4、在顶点着色器,计算得到 应用了 ST 和 随时间流动的UV,用于纹理采样(_WaterSpeed是上篇文章中用到的)
o.uv.xy = TRANSFORM_TEX(v.uv,_DistortTex)+_Time.y * _WaterSpeed;
5、在片元着色器中,对其进行法线纹理进行采样
half4 distortTex = SAMPLE_TEXTURE2D(_DistortTex,sampler_DistortTex,i.uv.xy);
二、实现水下扭曲的效果
原理:把抓取到的屏幕纹理,使用进行流动扭曲
- Unity中URP下抓屏的 开启 和 使用
1、定义一个扰度值,控制扭曲水下的扭曲程度
- 屏幕UV 和 法线纹理扭曲之间线性插值
float2 distortUV = lerp(screenUV,distortTex,_Distort);
2、在URP设置中,开启抓屏

3、在Pass中,定义抓屏的 纹理 和 采样器
TEXTURE2D(_CameraOpaqueTexture);SAMPLER(sampler_CameraOpaqueTexture);
4、使用线性插值后的结果,进行抓屏的纹理采样
half4 cameraOpaqueTex = SAMPLE_TEXTURE2D(_CameraOpaqueTexture,sampler_CameraOpaqueTexture,distortUV);


5、最后,与上篇文章计算得到的水的颜色混合
col *= cameraOpaqueTex;
三、最终代码
//水的深度
Shader "MyShader/URP/P4_8"
{Properties {[Header(Base)]_WaterColor1("WaterColor1",Color) = (1,1,1,1)_WaterColor2("WaterColor2",Color) = (1,1,1,1)_WaterSpeed("WaterSpeed",Range(0,1)) = 0.1[Header(Foam)]_FoamTex("FoamTex",2D) = "white"{} _FoamColor("FoamColor",Color) = (1,1,1,1)_FoamRange("FoamRange",Range(0,5)) = 1_FoamNoise("FoamNoise",Range(0,3)) = 1[Header(Distort)]_DistortTex("DistortNormalTex",2D) = "white"{}[PowerSlider(3)]_Distort("Distort",Range(0,0.5)) = 0}SubShader{Tags{//告诉引擎,该Shader只用于 URP 渲染管线"RenderPipeline"="UniversalPipeline"//渲染类型"RenderType"="Transparent"//渲染队列"Queue"="Transparent"}//Blend SrcAlpha OneMinusSrcAlphaZWrite 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 _WaterColor1;half4 _WaterColor2;half _FoamRange;half _WaterSpeed;half4 _FoamColor;half _FoamNoise;half4 _FoamTex_ST;half _Distort;half4 _DistortTex_ST;CBUFFER_ENDTEXTURE2D(_CameraDepthTexture);SAMPLER(sampler_CameraDepthTexture);TEXTURE2D(_FoamTex);SAMPLER(sampler_FoamTex);TEXTURE2D(_CameraOpaqueTexture);SAMPLER(sampler_CameraOpaqueTexture);TEXTURE2D(_DistortTex);SAMPLER(sampler_DistortTex);//struct appdata//顶点着色器的输入struct Attributes{float3 positionOS : POSITION;float2 uv : TEXCOORD0;};//struct v2f//片元着色器的输入struct Varyings{float4 positionCS : SV_POSITION;float4 uv : TEXCOORD0;// xy = distortUV,zw = foamUVfloat4 screenPos : TEXCOORD1;float3 positionVS : TEXCOORD2;float3 positionWS : TEXCOORD3;};//v2f vert(Attributes v)//顶点着色器Varyings vert(Attributes v){Varyings o = (Varyings)0;o.positionWS = TransformObjectToWorld(v.positionOS);o.positionVS = TransformWorldToView(o.positionWS);o.positionCS = TransformWViewToHClip(o.positionVS);o.screenPos = ComputeScreenPos(o.positionCS);//计算得到泡沫纹理采样需要的顶点世界空间下的坐标值的流动效果o.uv.zw += o.positionWS.xz *_FoamTex_ST.xy + _Time.y * _WaterSpeed;//计算得到水下扭曲纹理的流动UVo.uv.xy = TRANSFORM_TEX(v.uv,_DistortTex)+_Time.y * _WaterSpeed;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);//获取水面模型顶点在观察空间下的Z值(可以在顶点着色器中,对其直接进行转化得到顶点观察空间下的坐标)float4 depthWater = depthScene + i.positionVS.z;//2、水的颜色,线性插值得到水 和 接触物体的水的 颜色的过度half4 waterColor = lerp(_WaterColor1,_WaterColor2,depthWater);//3、水面泡沫//对泡沫纹理进行采样(这里使用顶点世界空间下的坐标进行纹理采样,防止水体缩放影响泡沫的平铺和重复方式)half4 foamTex = SAMPLE_TEXTURE2D(_FoamTex,sampler_FoamTex,i.uv.zw);foamTex = pow(foamTex,_FoamNoise);//这里增加一个调整深度图范围的功能half4 foamRange = depthWater * _FoamRange;//使用泡沫纹理 和 泡沫范围 比较得到泡沫遮罩half4 foamMask = step(foamRange,foamTex);//给泡沫加上颜色half4 foamColor = foamMask * _FoamColor;half4 col = foamColor + waterColor;//4、水下的扭曲half4 distortTex = SAMPLE_TEXTURE2D(_DistortTex,sampler_DistortTex,i.uv.xy);float2 distortUV = lerp(screenUV,distortTex,_Distort);half4 cameraOpaqueTex = SAMPLE_TEXTURE2D(_CameraOpaqueTexture,sampler_CameraOpaqueTexture,distortUV);col *= cameraOpaqueTex;//水的高光//水的反射//水的焦散return col;}ENDHLSL}}FallBack "Hidden/Shader Graph/FallbackError"
}
相关文章:
Unity中URP实现水体(水下的扭曲)
文章目录 前言一、使用一张法线纹理,作为水下扭曲的纹理1、在属性面板定义一个纹理,用于传入法线贴图2、在Pass中,定义对应的纹理和采样器3、在常量缓冲区,申明修改 Tilling 和 Offset 的ST4、在顶点着色器,计算得到 应…...
anaconda指定目录创建环境无效/环境无法创建到指定位置
已经设置目录到D盘 创建环境时还是分配到C盘 可能是指定位置没有开启读写权限,如我在这里安装到了anaconda文件夹,则打开该文件夹的属性->安全->编辑 allusers下的权限全都打勾...
《Docker极简教程》--Docker在生产环境的应用--Docker在生产环境的部署
一、准备工作 1.1 硬件和基础设施要求 硬件和基础设施要求是在部署 Docker 到生产环境之前需要认真考虑和准备的重要方面,以下是一般性的要求: 服务器硬件: CPU:建议使用多核处理器,以支持同时运行多个容器。内存&a…...
算法D31 | 贪心算法1 | 455.分发饼干 376. 摆动序列 53. 最大子序和
贪心算法其实就是没有什么规律可言,所以大家了解贪心算法 就了解它没有规律的本质就够了。 不用花心思去研究其规律, 没有思路就立刻看题解。 基本贪心的题目 有两个极端,要不就是特简单,要不就是死活想不出来。 学完贪心之后再…...
在IDEA中创建vue hello-world项目
工作中最近在接触vue前端项目,记录一下从0搭建一个vue hello world项目的步骤 1、本地电脑安装配置node、npm D:\Project\vue\hello-world>node -v v14.21.3 D:\Project\vue\hello-world>npm -v 6.14.18 D:\Project\vue\hello-world> 2、设置npm国内淘…...
如何获取pnpm存储目录
现在你可以做 得到:\path\to.pnpm-store\v3 pnpm store path注:从v7.0.0开始,pnpm 存储位于不同的文件夹中。它将位于$XDG_DATA_HOMELinux Linux : ~/.local/share/pnpm/store (default) Windows : C:\Users\YOUR_NAME\AppData\Local\pn…...
QT两个类之间使用信号槽
在做一些东西的时候,习惯性的引入头文件并且调用,因此出现了很多bug,qt的信号槽机制便可以有效的避免一些问题。 A类 #ifndef A_H #define A_H#include <QObject> #include <QDebug> class A : public QObject {Q_OBJECT public:explicit A…...
【Ubuntu】使用WSL安装Ubuntu
WSL 适用于 Linux 的 Windows 子系统 (WSL) 是 Windows 的一项功能,可用于在 Windows 计算机上运行 Linux 环境,而无需单独的虚拟机或双引导。 WSL 旨在为希望同时使用 Windows 和 Linux 的开发人员提供无缝高效的体验。安装 Linux 发行版时,…...
【Node.js】自动生成 API 文档
目录 1、直接使用swagger-ui-express 2、配合swagger-jsdoc 如何在Node.js项目中使用 Swagger 来自动生成 API接口文档,使用生成方式有很多种。本文基于swagger-jsdocswagger-ui-express快速实现 1、直接使用swagger-ui-express // 方便来浏览和测试api npm i sw…...
小红书3C家电行业种草营销策略打法,纯干货
小红书作为国内种草营销的鼻祖,拥有庞大的年轻用户群体,特别是在3C家电行业,小红书的种草营销效应更是明显。据相关数据显示,小红书3C家电行业的用户关注度持续攀升,尤其是90后和00后,他们对新鲜事物的接受…...
防火墙的内容安全
目录 1. 内容安全 1.1 IAE引擎 DPI---深度包检测技术 DFI---深度流检测技术 结论(优缺点): 1.2 入侵防御(检测)(IPS) IPS的优势: 入侵检测的方法: 入侵检测的流程 签名 查看预定义签名的内容 新建自定义签名 入侵防御的检测…...
Redis 管道详解
Redis 管道 关键词:Pipeline Pipeline 简介 Redis 是一种基于 C/S 模型以及请求/响应协议的 TCP 服务。通常情况下,一个 Redis 命令的请求、响应遵循以下步骤: 客户端向服务端发送一个查询请求,并监听 Socket 返回(…...
【Redis】理论进阶篇------浅谈Redis的缓存穿透和雪崩原理
一、缓存穿透 1、概念 缓存穿透(查不到数据),是指当用户想要查询数据的时候,会先去Redis中取命中,如果Redis中没有该数据,那么就会向数据库中去查找数据。如果数据库中也没有,则该次查询结果失…...
Rocky Linux安装部署Elasticsearch(ELK日志服务器)
一、Elasticsearch的简介 Elasticsearch是一个强大的开源搜索和分析引擎,可用于实时处理和查询大量数据。它具有高性能、可扩展性和分布式特性,支持全文搜索、聚合分析、地理空间搜索等功能,是构建实时应用和大规模数据分析平台的首选工具。 …...
Linux浅学笔记04
目录 Linux实用操作 Linux系统下载软件 yum命令 apt systemctl命令 ln命令 日期和时区 IP地址 主机名 网络传输-下载和网络请求 ping命令 wget命令 curl命令 网络传输-端口 进程 ps 命令 关闭进程命令: 主机状态监控命令 磁盘信息监控:…...
【Day59】代码随想录之动态规划_647回文子串_516最长回文子序列
文章目录 动态规划理论基础动规五部曲:出现结果不正确: 1. 647回文子串2. 516最长回文子序列 动态规划理论基础 动规五部曲: 确定dp数组 下标及dp[i] 的含义。递推公式:比如斐波那契数列 dp[i] dp[i-1] dp[i-2]。初始化dp数组…...
ECLIP
denote the representation of the positive prompt produced by the momentum model as h ξ i h_{\xi}^{i} hξi 辅助信息 作者未提供代码...
STM32 +合宙1.54“ 电子墨水屏(e-paper)驱动显示示例
STM32 合宙1.54“ 电子墨水屏(e-paper)驱动显示示例 📍相关篇《Arduino框架下ESP32/ESP8266合宙1.54“ 电子墨水屏(e-paper)驱动显示示例》🔖程序是从GooDisplay品牌和微雪电子下同型号规格墨水屏的示例程序…...
使用Postman和JMeter进行signature签名
一、前言 有些接口的请求会带上sign(签名)进行请求,各接口对sign的签名内容、方式可能不一样,但一般都是从接口的入参中选择部分内容组成一个字符串,然后再进行签名操作, 将结果赋值给sign; 完整规范的接口文档都会…...
uni-app nvue vue3 setup中实现加载webview,解决nvue中获取不到webview实例的问题
注意下面的方法只能在app端使用, let wv plus.webview.create("","custom-webview",{plusrequire:"none", uni-app: none, width: 300,height:400,top:uni.getSystemInfoSync().statusBarHeight44 }) wv.loadURL("https://ww…...
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...
为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...
现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...
CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)
漏洞概览 漏洞名称:Apache Flink REST API 任意文件读取漏洞CVE编号:CVE-2020-17519CVSS评分:7.5影响版本:Apache Flink 1.11.0、1.11.1、1.11.2修复版本:≥ 1.11.3 或 ≥ 1.12.0漏洞类型:路径遍历&#x…...
省略号和可变参数模板
本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...
