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

news2024/12/22 14:26:03

文章目录

  • 前言
  • 一、搭建预备场景
    • 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 Back
            Blend One Zero
            ZTest LEqual
            ZWrite On
          
            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/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 One
        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)
            
            CBUFFER_END

            
            TEXTURE2D(_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.coloradmin.cn/o/1466133.html

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

相关文章

【Java】类与对象(实验二)

目录 一、实验目的 二、实验内容 三、实验小结 一、实验目的 掌握类的定义与对象的创建。理解构造方法和this关键字的用法。掌握对象对于属性及方法的引用。 二、实验内容 1、编写一个Java程序&#xff0c;定义一个表示学生的类Student&#xff0c;该类包括: (1)这个类的…

C++力扣题目300--最长递增子序列 674--最长连续递增序列 718--最长重复子数组

300.最长递增子序列 力扣题目链接(opens new window) 给你一个整数数组 nums &#xff0c;找到其中最长严格递增子序列的长度。 子序列是由数组派生而来的序列&#xff0c;删除&#xff08;或不删除&#xff09;数组中的元素而不改变其余元素的顺序。例如&#xff0c;[3,6,2…

深入理解flinksql执行流程,calcite与catalog相关概念,扩展解析器实现语法的扩展

深入理解Flink Sql执行流程 1 Flink SQL 解析引擎1.1SQL解析器1.2Calcite处理流程1.2.1 SQL 解析阶段&#xff08;SQL–>SqlNode&#xff09;1.2.2 SqlNode 验证&#xff08;SqlNode–>SqlNode&#xff09;1.2.3 语义分析&#xff08;SqlNode–>RelNode/RexNode&#…

R的seurat和python的scanpy对比学习

现在的单细胞分析&#xff0c;往往避免不了scanpy的使用&#xff0c;我们可以通过对比seurat来学习scanpy 今天的格式怎么都改不了。。。手机阅读有点费劲&#xff0c;&#xff0c;推荐电脑阅读。 单细胞数据分析概览 单细胞分析&#xff0c;总流程 python教程 seurat教程 se…

ubuntu20配置protobuf 2.5.0

python安装protobuf包 sudo pip2 install protobuf2.5.0github克隆获取安装包 wget https://github.com/protocolbuffers/protobuf/releases/download/v2.5.0/protobuf-2.5.0.tar.gz解压并进入该目录 tar -zxvf Protobuf-2.5.0.tar.gz cd protobuf-2.5.0配置安装环境 sudo …

HTB pwn Dragon Army

逆向分析 程序使用了alloca函数扩大了栈区 此处可以泄露libc的地址 程序主要功能在下面 while ( 1 ){while ( 1 ){fflush(stdin);fflush(_bss_start);fprintf(_bss_start, "\n%sDragons: [%d/%d]%s\n\n", "\x1B[1;34m", v5, 13LL, "\x1B[1;37m"…

【洛谷题解】B2118 验证子串

题目链接&#xff1a;验证子串 - 洛谷 题目难度&#xff1a;入门 涉及知识点&#xff1a;STL函数 题意&#xff1a; 分析&#xff1a;用一个STL内置的find函数 AC代码&#xff1a; #include<bits/stdc.h> /*find用法&#xff1a;string s1&#xff0c;s2;int as1.f…

crmeb多门店商城系统二次开发 增加车辆车牌搜索功能、车辆公里数

1、增加的数据库 ALTER TABLE eb_store_order ADD cart_number VARCHAR(255) NOT NULL DEFAULT COMMENT 车牌 AFTER erp_order_id, ADD curmileage VARCHAR(255) NOT NULL DEFAULT COMMENT 当前里程 AFTER cart_number; ALTER TABLE eb_store_cart ADD cart_number VARCHAR(…

容器_Docker ( 04 )

容器_Docker ( 03 ) 解密云原生 - 集群概述 kubernetes概述 kubernetes起源 如果想要将docker应用于具体的业务实现 , 是存在困难的 – 编排, 管理和调度等各个方面 , 都不容易.于是 , 人们迫切需要一套管理系统 , 对docker及容器进行更高级更灵活的管理 , 于是kubernetes出…

Kotlin filterIsInstance filterNotNull forEach

Kotlin filterIsInstance filterNotNull forEach fun main(args: Array<String>) {val i1 MyItem(1, 1)val i2: MyItem? nullval i3: Int 3val i4 "4"val i5 nullval i6 MyItem(6, 6)val list mutableListOf<Any?>(i1, i2, i3, i4, i5, i6)lis…

蓝牙耳机哪个品牌质量好?2024超高性能机型比拼推荐

​无线耳机已经成为现代生活中的必备数码产品&#xff0c;尤其在感受到无线带来的自由后&#xff0c;很难再适应有线耳机的束缚。因此&#xff0c;耳机市场竞争激烈&#xff0c;各种类型和外观的耳机层出不穷。在此&#xff0c;我为大家总结了五款使用体验很不错的蓝牙耳机&…

静态时序分析:SDC约束命令set_driving_cell详解

相关阅读 静态时序分析https://blog.csdn.net/weixin_45791458/category_12567571.html?spm1001.2014.3001.5482 在上文中&#xff0c;我们不建议使用set_drive命令而是使用set_driving_cell命令&#xff0c;这是一个描述输入端口驱动能力更精确的方法。因为大多数情况下&…

黑马头条-day10

文章目录 app端文章搜索1、文章搜索1.1 ElasticSearch环境搭建1.2 索引库创建①需求分析②ES导入数据场景分析③创建索引和映射 1.3 索引数据同步①app文章历史数据导入ES②文章实时数据导入ES 1.4 文章搜索多条件复合查询①关键词搜索②搜索接口定义 2、搜索历史记录2.1 需求说…

免费的代理IP能用吗?

随着大家对代理IP的认知逐步加深&#xff0c;不可避免地&#xff0c;免费代理IP安全性和潜在风险也越来越关注&#xff0c;今天我们就来一探究竟&#xff0c;这到底是怎么一回事。 首先&#xff0c;我们得了解一下代理IP。 代理IP是指作为中介的服务器&#xff0c;它能够代理用…

java.lang.IllegalStateException: Promise already completed.

spark submit 提交作业的时候提示Promise already complete 完整日志如下 File "/data5/hadoop/yarn/local/usercache/processuser/appcache/application_1706192609294_136972/container_e41_1706192609294_136972_02_000001/py4j-0.10.6-src.zip/py4j/protocol.py"…

修改单据转换规则后保存报错提示

文章目录 修改单据转换规则后保存报错提示 修改单据转换规则后保存报错提示

软考系分之多媒体分类、声音、图像

文章目录 1、概要2、 媒体分类3、声音4、图像5、总结 1、概要 本篇重点介绍多媒体技术&#xff0c;包括多媒体分类、声音、图像。 2、 媒体分类 媒体主要分为5类&#xff0c;感觉媒体、表现媒体、表示媒体、传输媒体和存储媒体。感觉媒体&#xff0c;就是直接作用于人感官的媒…

android input命令支持多指触摸成果展示-千里马framework实战开发

hi input命令扩展提示部分 generic_x86_64:/ # input -h Error: Unknown command: -h Usage: input [<source>] <command> [<arg>...]The source…

体验LobeChat搭建私人聊天应用

LobeChat是什么 LobeChat 是开源的高性能聊天机器人框架&#xff0c;支持语音合成、多模态、可扩展的&#xff08;Function Call&#xff09;插件系统。支持一键免费部署私人 ChatGPT/LLM 网页应用程序。 地址&#xff1a;https://github.com/lobehub/lobe-chat 为什么要用Lobe…

如何快速导出vercel project中的环境变量

我在vercel中集成了某些插件或者链接了数据库&#xff0c;要如何快速的导出这些环境变量呢&#xff1f; 具体方法如下&#xff1a; npm i -g vercelvercel linkvercel env pull .env.local首先是安装vercel然后登录vercel 最后拉取环境变量到.env.local