Unity中URP实现水体(水下的扭曲)

news2024/9/7 21:35:00

文章目录

  • 前言
  • 一、使用一张法线纹理,作为水下扭曲的纹理
    • 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 OneMinusSrcAlpha
        ZWrite Off
        Pass
        {
            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_END

            
            TEXTURE2D(_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 = foamUV
                float4 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;
                //计算得到水下扭曲纹理的流动UV
                o.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://www.coloradmin.cn/o/1471569.html

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

相关文章

代码随想录算法刷题训练营day23

代码随想录算法刷题训练营day23:LeetCode(669)修剪二叉搜索树、LeetCode(108)将有序数组转换为二叉搜索树、LeetCode(538)把二叉树转化为累加树 LeetCode(669)修剪二叉搜索树 题目 代码 /*** Definition for a binary tree node.* public class TreeNode {* …

使用解决方案为PowerApps搭建测试环境

为Power Apps搭建另外一套环境 背景描述环境准备开发环境开发项目项目介绍开发环境SharePoint准备测试环境SharePoint准备解决方案创建创建解决方案环境变量准备创建站点环境变量创建文档库环境变量解决方案中创建Apps解决方案中创建power automate测试查看流运行记录查看Share…

TLS1.2抓包解析

1.TLS1.2记录层消息解析 Transport Layer SecurityTLSv1.2 Record Layer: Handshake Protocol: Client HelloContent Type: Handshake (22)Version: TLS 1.0 (0x0301)Length: 253Content Type:消息类型,1个字节。 i 0Version:协议版本&…

并发情况下数据校验-基于数据库实现

并发情况下数据校验-基于数据库实现 数据库行锁原理实际操作数据准备开启事务,更新数据 项目实战项目配置多线程测试 在开发过程中,我们会遇到校验数据的唯一性,数据更新之后是否超过设置的阈值等等。并发情况下数据校验常见方式有使用分布式…

辽宁博学优晨教育视频剪辑培训探索学习新意义

在当今数字化快速发展的时代,视频已成为信息传达的重要载体。辽宁博学优晨教育视频剪辑培训应运而生,不仅为学员提供了专业的学习平台,更在探索学习的意义方面赋予了新的内涵。 视频剪辑作为现代媒体行业的重要技能,其学习意义不仅…

高速稳定、网络隔离,解析“向日葵控控”远控方案在医疗行业应用

在医疗大健康领域,依托高速发展的信息化技术加速布局智能化,通过远程手段提高医疗服务质量、促进医疗资源共享、提升医疗工作效率,已成为医院和各类社区诊所等提供关键医疗服务部门近年来的发展目标之一。 同时,根据医疗领域的特殊…

点云数据处理常用外部库(C++/Windows)的项目配置

一、点云数据处理常用外部库(C版本)的下载安装与项目配置 (一)PCL 基于VS2019编程平台的PCL外部库下载安装及项目配置已有大量博客,本文不再赘述。具体下载安装及项目配置流程可参考外部库编译配置参考资料/*1*/ 。需…

linux+fortify

系统版本:Ubuntu22.04桌面版 一:登录root用户关闭防火墙 sudo passwd root systemctl stop ufw.service systemctl disable ufw.service 二:开启ssh服务 sudo apt update sudo apt install openssh-server sudo systemctl start ssh sudo systemctl status ssh连接上WinS…

开年大吉!安全狗入选工信部工业互联网试点示范名单

近日,工业和信息化部信息通信管理局公布了2023年工业互联网试点示范名单。此次名单根据《工业和信息化部办公厅关于组织开展2023年工业互联网试点示范项目申报工作的通知》(工信厅信管函﹝2023﹞319号),经企业申报、地方推荐、专家…

亚马逊测评 能让买家更快速的喜欢上你的产品,提高转化率

在当今的电子商务时代,亚马逊作为全球最大的在线零售商之一,已经成为了消费者购买各种商品的首选平台。然而,对于消费者来说,如何选择适合自己的产品成为了他们面临的一大难题。因此,本文将介绍亚马逊上如何让买家通过…

盲盒小程序开发:探索技术与创意的融合

盲盒,这种充满惊喜和趣味性的商品销售模式,近年来在国内市场迅速崛起。它结合了收藏、交换、抽奖等多种消费体验,吸引了大量年轻消费者。随着移动互联网的普及,盲盒小程序的开发为这一市场注入了新的活力。本文将探讨盲盒小程序开…

yolov8学习笔记(二)模型训练

目录 yolov8的模型训练 1、制作数据集(标记数据集) 2、模型训练(标记数据集、参数设置、跟踪模型随时间的性能变化) 2.1、租服务器训练 2.2、加训练参数 2.3、看训练时的参数(有条件,就使用TensorBoard&…

BFS中的多源BFS-双端队列BFS

2024-01-30(树与图的深度优先遍历、广度优先遍历、拓扑排序)-CSDN博客 2024-01-31(最短路径)-CSDN博客 多源BFS 173. 矩阵距离 - AcWing题库 求出每个位置到所有为1的点的最短距离 import java.util.*; import java.io.*;class PII{int…

linux系统---安装使用nginx

目录 一、编译安装Nginx 1、关闭防火墙,将安装nginx所需要软件包传到/opt目录下 ​编辑2、安装依赖包 3、创建运行用户、组 4、编译安装nginx 5、创建软链接后直接nginx启动 ​编辑 6、创建nginx自启动文件 ​编辑6.1 重新加载配置、设置开机自启并开启服务…

LeetCode_Java_动态规划系列(1)(题目+思路+代码)

目录 斐波那契类型 746.使用最小花费爬楼梯 矩阵 120. 三角形最小路径和 斐波那契类型 746.使用最小花费爬楼梯 给你一个整数数组 cost ,其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。…

知网G4《教育界》正规期刊吗?投稿难吗?

知网G4《教育界》正规期刊吗?投稿难吗? 《教育界》杂志,定位于教育专业的教育类权威性学术期刊,教育类核心期刊,本刊是经国家新闻出版出版总署批准的纯教育类权威期刊。 《教育界》知网G4,刊期24年底,收幼…

【ArcGIS】基于DEM/LUCC等数据统计得到各集水区流域特征

基于DEM/LUCC等数据统计得到各集水区流域特征 提取不同集水区各类土地利用类型比例步骤1:划分集水区为独立面单元步骤2:批量掩膜提取得到各集水区土地利用类型比例步骤3:导入各集水区LUCC数据并统计得到各类型占比 提取坡度特征提取河网密度特…

SQL-多表查询

多表关系 一对多(多对一) 在多的一方建立外键,指向一的一方的主键。多对多 建立第三张中间表,中间表至少包含两个外键,分别关联两方主键。一对一 在任意一方加入外键,关联另外一方的主键,并且设…

【算法 - 动态规划】找零钱问题Ⅰ

在前面的动态规划系列文章中,关于如何对递归进行分析的四种基本模型都介绍完了,再来回顾一下: 从左到右模型 :arr[index ...] 从 index 之前的不用考虑,只考虑后面的该如何选择 。范围尝试模型 :思考 [L ,…

[面试]我们常说的负载均衡是什么东西?

什么是负载均衡 如果用户量很多, 服务器的流量也随之增大, 此时出现两个问题, 软件性能下降 容易出现单点故障 为了解决这些问题, 引入了集群化架构, 也就是把一个软件同时部署在多个服务器上 集群化架构出现的问题 架构改变后又出现了两个问题 如何将请求均匀的发送到多…