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

2024-02-24 20:52

本文主要是介绍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"
}

这篇关于Unity中URP实现水体效果(水的深度)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/743349

相关文章

分布式锁在Spring Boot应用中的实现过程

《分布式锁在SpringBoot应用中的实现过程》文章介绍在SpringBoot中通过自定义Lock注解、LockAspect切面和RedisLockUtils工具类实现分布式锁,确保多实例并发操作... 目录Lock注解LockASPect切面RedisLockUtils工具类总结在现代微服务架构中,分布

Java使用Thumbnailator库实现图片处理与压缩功能

《Java使用Thumbnailator库实现图片处理与压缩功能》Thumbnailator是高性能Java图像处理库,支持缩放、旋转、水印添加、裁剪及格式转换,提供易用API和性能优化,适合Web应... 目录1. 图片处理库Thumbnailator介绍2. 基本和指定大小图片缩放功能2.1 图片缩放的

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

深度解析Spring Security 中的 SecurityFilterChain核心功能

《深度解析SpringSecurity中的SecurityFilterChain核心功能》SecurityFilterChain通过组件化配置、类型安全路径匹配、多链协同三大特性,重构了Spri... 目录Spring Security 中的SecurityFilterChain深度解析一、Security

Redis客户端连接机制的实现方案

《Redis客户端连接机制的实现方案》本文主要介绍了Redis客户端连接机制的实现方案,包括事件驱动模型、非阻塞I/O处理、连接池应用及配置优化,具有一定的参考价值,感兴趣的可以了解一下... 目录1. Redis连接模型概述2. 连接建立过程详解2.1 连php接初始化流程2.2 关键配置参数3. 最大连

Python实现网格交易策略的过程

《Python实现网格交易策略的过程》本文讲解Python网格交易策略,利用ccxt获取加密货币数据及backtrader回测,通过设定网格节点,低买高卖获利,适合震荡行情,下面跟我一起看看我们的第一... 网格交易是一种经典的量化交易策略,其核心思想是在价格上下预设多个“网格”,当价格触发特定网格时执行买

python设置环境变量路径实现过程

《python设置环境变量路径实现过程》本文介绍设置Python路径的多种方法:临时设置(Windows用`set`,Linux/macOS用`export`)、永久设置(系统属性或shell配置文件... 目录设置python路径的方法临时设置环境变量(适用于当前会话)永久设置环境变量(Windows系统

深度解析Nginx日志分析与499状态码问题解决

《深度解析Nginx日志分析与499状态码问题解决》在Web服务器运维和性能优化过程中,Nginx日志是排查问题的重要依据,本文将围绕Nginx日志分析、499状态码的成因、排查方法及解决方案展开讨论... 目录前言1. Nginx日志基础1.1 Nginx日志存放位置1.2 Nginx日志格式2. 499

Python对接支付宝支付之使用AliPay实现的详细操作指南

《Python对接支付宝支付之使用AliPay实现的详细操作指南》支付宝没有提供PythonSDK,但是强大的github就有提供python-alipay-sdk,封装里很多复杂操作,使用这个我们就... 目录一、引言二、准备工作2.1 支付宝开放平台入驻与应用创建2.2 密钥生成与配置2.3 安装ali

Spring Security 单点登录与自动登录机制的实现原理

《SpringSecurity单点登录与自动登录机制的实现原理》本文探讨SpringSecurity实现单点登录(SSO)与自动登录机制,涵盖JWT跨系统认证、RememberMe持久化Token... 目录一、核心概念解析1.1 单点登录(SSO)1.2 自动登录(Remember Me)二、代码分析三、