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"
}

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL认证方法介绍

阅读本文之前请参阅----MySQL 数据库安装教程详解(linux系统和windows系统) MySQL数据库的认证方法对于确保数据安全和维护系统完整性至关重要。在MySQL中,有多种认证方法可供选择,每种方法都有其特定的用途和配置方式。本文将详细…

Windows 开机启动 | 启动项管理

开机启动 开机启动对于保障系统的正常运行、提高用户体验、及时响应系统事件以及自动化管理和维护系统都具有重要意义。合理管理开机启动项,系统启动时自动运行必要的程序和服务。 但是,随着操作系统使用时长的增加启动项越来越多,而且还很难…

Unity(第五部)新手图层和标签的理解

1、标记用于在物体上显示名字,方便开发 2、标签(某一类物体,方便给某一类进行组件脚本编写) 而且有了标签之后,我们在写代码的时候就可以直接通过标签找到一系列我们需要的游戏物体了 Untagged未标记Respawn重生Edi…

QT GUI编程常用控件学习

1 GUI编程应该学什么 2 QT常用模块结构 QtCore: 包含了核心的非GUI的功能。主要和时间、文件与文件夹、各种数据、流、URLs、mime类文件、进程与线程一起使用 QtGui: 包含了窗口系统、事件处理、2D图像、基本绘画、字体和文字类 QtWidgets: 包含了一些列创建桌面应用的UI元素…

基于相位的运动放大:如何检测和放大难以察觉的运动(01/2)

基于相位的运动放大:如何检测和放大难以察觉的运动 目录 一、说明二、结果的峰值三、金字塔背景3.1 可操纵金字塔3.2 亚倍频程复数可控金字塔 四、基本方针4.1 1D 问题陈述4.2 一维方法4.3 实际实施说明 五、放大倍率的限制5.1 空间支持的影响5.2 频带的影响 六、推…

matlab simulink永磁同步电机pid控制

1、内容简介 略 53-可以交流、咨询、答疑 2、内容说明 略 摘 要 19世纪90年代,美国西屋电气公司研制出了世界上第一台交流同步电机。随着科学技术的迅猛发展和生产工艺的持续进步,在20世纪50年代出现了永磁同步电机。它以永磁体代替电励磁绕组&#…

Camera sensor调试与bringup帧率计算

Camera sensor调试 前言DVP并行接口sensor调试方法硬件调试出图调试错误调试地址无响应问题获取帧缓存失败 DVP Wrapper调试 MIPI 串行差分接口sensor调试方法硬件调试MIPI错误调试PCB设计要求ISP时钟大小要求CSI Controller配置时钟部分其他部分 Sensor HS-PREPARE配置 Camera…

python-可视化篇-简单-条形图输出主要省份GDP排名情况

条形图输出主要省份GDP排名情况 代码 gdp广东:97277.77:107671.07 江苏:92595.40:99631.52 山东:76469.70:71067.5 浙江:56197.00:62353 河南:48055.90:54259.2 四川:40678.10:46615.82 湖北:39366.60:45828.31 湖南:36425.78:39752.12 河北:36010.30:35104.5 福建:35804.04:…

JSONVUE

1.JSON学习 1.概念: JSON是把JS对象变成字符串. 2.作用: 多用于网络中数据传输. JavaScript对象 let person{name:"张三",age:18}//将JS对象转换为 JSON数据let person2JSON{"name":"张三","age":18}; 3.JS对象与JSON字符串转换…

【深入理解设计模式】代理设计模式

代理设计模式: 代理设计模式是一种结构型设计模式,它允许你提供一个替代物或占位符来控制对其他对象的访问。在代理模式中,一个类代表另一个类的功能。这种类型的设计模式属于结构型模式,因为该模式涉及类和对象的组合。 概述 …

CFS的覆灭,Linux新调度器EEVDF详解

本文主要总结了EEVDF论文和Linux内核实现中关键逻辑的推导,着重强调代码逻辑和论文公式之间的关系,它又长又全,像今天的汤圆又大又圆:D Warn:多行的公式编号渲染有点问题,当存在多行公式时,仅对最后一条式…

Nest.js权限管理系统开发(四)Swagger API接入

什么是swagger Swagger 是一个规范和完整的框架&#xff0c;用于生成、描述、调用和可视化 RESTful 风格的 Web 服务(<https://swagger.io/>)。 它的主要作用是&#xff1a; 1. 使得前后端分离开发更加方便&#xff0c;有利于团队协作 2. 接口的文档在线自动生成&#xf…

matlab|基于DistFlow潮流的配电网故障重构(输入任意线路)

目录 1 主要内容 2 部分代码 3 程序结果 4 下载链接 1 主要内容 程序采用适用于辐射状网络的DistFlow潮流模型&#xff0c;可输入任意故障线路编号&#xff0c;得到优化重构结果。这个程序是配电网故障重构可视化matlabyalmip的升级版&#xff0c;原来的程序是以电压质量作…

Java基于SpringBoot的口腔医院管理平台,附源码

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

国企行政题库--校园招聘

国企行政题库是为准备参加国有企业行政类岗位校园招聘的应聘者提供的一套专门准备的试题资料。国有企业在中国经济中扮演着重要的角色&#xff0c;其行政类岗位需求量大&#xff0c;竞争激烈。通过系统学习和准备国企行政题库&#xff0c;将有助于应聘者更好地了解国企行政类岗…

Linux进程 ----- 信号处理

前言 从信号产生到信号保存&#xff0c;中间经历了很多&#xff0c;当操作系统准备对信号进行处理时&#xff0c;还需要判断时机是否 “合适”&#xff0c;在绝大多数情况下&#xff0c;只有在 “合适” 的时机才能处理信号&#xff0c;即调用信号的执行动作。 一、信号的处理…

PX4FMU和PX4IO最底层启动过程分析(上)

PX4FMU和PX4IO最底层启动过程分析&#xff08;上&#xff09; 主处理器和协处理器的固件烧写和运行过程 PX4FMU&#xff1a;各种传感器数据读取、姿态解算、PWM控制量的计算、与PX4IO通信。负责飞控最主要的工作。 PX4IO&#xff08;STM32F103&#xff09;&#xff1a;为PIXHA…

java spring 01 IOC源码

01.spring 中的基础是IOC 中有一个方法 例子&#xff1a;

《最新出炉》系列初窥篇-Python+Playwright自动化测试-26-处理单选和多选按钮-下篇

1.简介 今天这一篇宏哥主要是讲解一下&#xff0c;如何使用Playwright来遍历单选和多选按钮。大致两部分内容&#xff1a;一部分是宏哥在本地弄的一个小demo&#xff0c;另一部分&#xff0c;宏哥是利用JQueryUI网站里的单选和多选按钮进行实战。 2.demo准备 2.1demo页面的H…

【MySQL面试复习】什么是聚簇索引(聚集索引)和非聚簇索引(二级索引)/什么是回表?

系列文章目录 在MySQL中&#xff0c;如何定位慢查询&#xff1f; 发现了某个SQL语句执行很慢&#xff0c;如何进行分析&#xff1f; 了解过索引吗&#xff1f;(索引的底层原理)/B 树和B树的区别是什么&#xff1f; 系列文章目录什么是聚簇索引&#xff08;聚集索引&#xff09…