UnityURP 扭曲屏幕效果实现

UnityURP 扭曲屏幕效果实现

  • 前言
  • 项目
    • 下载URPGrabPass
    • 空间扭曲着色器实现
    • 添加可视化控制
    • 创建材质球并设置
    • 补充
      • 粒子使用步骤
      • CustomData映射
      • 移动设备优化
  • 鸣谢

前言

在Unity的Universal Render Pipeline (URP) 中,传统的GrabPass功能被移除,借助URPGrabPass工具可以实现。

扭曲屏幕效果

项目

下载URPGrabPass

下载地址:https://github.com/Haruma-K/URPGrabPass
下载完成后解压放入工程

URPGrabPass通过ScriptableRendererFeature机制,在渲染管线中插入自定义的Pass来捕获屏幕颜色纹理。
插件提供两种渲染时机:

  • AfterOpaques: 在不透明物体渲染后捕获
  • AfterTransparents: 在透明物体渲染后捕获

插件自动将捕获的屏幕纹理以_GrabbedTexture的名称传递给着色器,只需在着色器中声明即可使用:

sampler2D _GrabbedTexture;

记得在渲染管线中添加RendererFeature
渲染管线中添加RendererFeature

空间扭曲着色器实现

Shader "Demo/SpatialFracture"
{Properties{_DisplacementTex("Displacement Texture", 2D) = "gray" {}_FractureIntensity("Fracture Intensity", Range(0.0, 2.0)) = 0.5_DistortionStrength("Distortion Strength", Range(0.0, 1.0)) = 0.3_FractureScale("Fracture Scale", Range(0.1, 5.0)) = 1.0_TimeSpeed("Time Speed", Range(0.0, 5.0)) = 1.0_RefractiveIndex("Refractive Index", Range(0.0, 1.0)) = 0.67[Toggle] _DebugDisplacement("Debug Displacement", Float) = 0[Toggle] _UseCustomData("Use Custom Data", Float) = 0}SubShader{Tags{"RenderType" = "Transparent" "RenderPipeline" = "UniversalRenderPipeline""Queue" = "Transparent"}Pass{Tags{"LightMode" = "UseColorTexture"}HLSLPROGRAM#pragma vertex vert#pragma fragment frag#pragma shader_feature _DEBUGDISPLACEMENT_ON#pragma shader_feature _USECUSTOMDATA_ON#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"struct Attributes{float4 positionOS : POSITION;float2 uv : TEXCOORD0;half3 normal : NORMAL;#ifdef _USECUSTOMDATA_ONfloat4 customData : TEXCOORD1;#endif};struct Varyings{float4 positionHCS : SV_POSITION;float2 uv : TEXCOORD0;half2 samplingViewportPos : TEXCOORD1;float3 worldPos : TEXCOORD2;#ifdef _USECUSTOMDATA_ONfloat4 customData : TEXCOORD3;#endif};sampler2D _GrabbedTexture;sampler2D _DisplacementTex;float4 _DisplacementTex_ST;float _FractureIntensity;float _DistortionStrength;float _FractureScale;float _TimeSpeed;float _RefractiveIndex;Varyings vert(Attributes IN){Varyings OUT;OUT.positionHCS = TransformObjectToHClip(IN.positionOS);OUT.uv = TRANSFORM_TEX(IN.uv, _DisplacementTex);OUT.worldPos = TransformObjectToWorld(IN.positionOS);// Calculate base screen positionfloat4 screenPos = ComputeScreenPos(OUT.positionHCS);OUT.samplingViewportPos = screenPos.xy / screenPos.w;#ifdef _USECUSTOMDATA_ONOUT.customData = IN.customData;#endifreturn OUT;}half4 frag(Varyings IN) : SV_Target{float2 uv = IN.uv;float time = _Time.y * _TimeSpeed;// Get parameters from CustomData or use defaults#ifdef _USECUSTOMDATA_ONfloat fractureIntensity = IN.customData.x;float distortionStrength = IN.customData.y;float fractureScale = IN.customData.z;float refractiveIndex = IN.customData.w;#elsefloat fractureIntensity = _FractureIntensity;float distortionStrength = _DistortionStrength;float fractureScale = _FractureScale;float refractiveIndex = _RefractiveIndex;#endif// Sample displacement texture with animationfloat2 animatedUV = uv * fractureScale + float2(time * 0.1, time * 0.05);float4 displacement = tex2D(_DisplacementTex, animatedUV);#ifdef _DEBUGDISPLACEMENT_ONreturn half4(displacement.rgb, 1.0);#endif// Convert displacement to offsetfloat2 totalDisplacement = (displacement.rg - 0.5) * fractureIntensity * distortionStrength;// Apply refractive distortion based on displacementfloat3 viewDir = normalize(IN.worldPos - _WorldSpaceCameraPos.xyz);float displacementIntensity = length(displacement.rg - 0.5);float2 refractiveOffset = viewDir.xy * refractiveIndex * displacementIntensity * 0.05;// Combine distortionsfloat2 finalUV = IN.samplingViewportPos + totalDisplacement + refractiveOffset;// Sample the grabbed texture with distorted coordinateshalf4 grabbedColor = tex2D(_GrabbedTexture, finalUV);return grabbedColor;}ENDHLSL}}
}

添加可视化控制

搭配可视化操作更佳

using UnityEngine;public class SpatialFractureShaderHelper : MonoBehaviour
{[Header("Shader Control")]public Material targetMaterial;[Header("Debug Options 调试模式,只展示置换贴图")]public bool debugDisplacement = false;[Header("使用ParticleSystem传入CustomData")]public bool useCustomData = false;[Header("Manual Parameter Control")][Range(0f, 2f)]public float fractureIntensity = 0.5f;[Range(0f, 1f)]public float distortionStrength = 0.3f;[Range(0.1f, 5f)]public float fractureScale = 1f;[Range(0f, 1f)]public float refractiveIndex = 0.67f;void Update(){if (targetMaterial == null) return;// 设置关键字SetKeyword("_DEBUGDISPLACEMENT_ON", debugDisplacement);SetKeyword("_USECUSTOMDATA_ON", useCustomData);// 如果不使用CustomData,则设置材质参数if (!useCustomData){targetMaterial.SetFloat("_FractureIntensity", fractureIntensity);targetMaterial.SetFloat("_DistortionStrength", distortionStrength);targetMaterial.SetFloat("_FractureScale", fractureScale);targetMaterial.SetFloat("_RefractiveIndex", refractiveIndex);}}void SetKeyword(string keyword, bool enabled){if (enabled)targetMaterial.EnableKeyword(keyword);elsetargetMaterial.DisableKeyword(keyword);}
}

创建材质球并设置

材质球设置

补充

粒子使用步骤

  1. 在粒子系统中启用"Custom Vertex Streams"
  2. 添加"Custom1.xyzw"到vertex streams列表
  3. 在CustomData模块中设置参数值
  4. 在材质上启用"Use Custom Data"选项

CustomData映射

  • Custom1.x → 破裂强度 (Fracture Intensity)
  • Custom1.y → 扭曲强度 (Distortion Strength)
  • Custom1.z → 破裂缩放 (Fracture Scale)
  • Custom1.w → 折射指数 (Refractive Index)

移动设备优化

#ifdef _MOBILEOPTIMIZATION_ON
// 简化版:直接使用位移作为折射偏移
half2 refractiveOffset = (displacement.rg - 0.5h) * refractiveIndex * 0.05h;
#else
// 完整版:基于视角方向的真实折射
half3 viewDir = normalize(IN.worldPos - _WorldSpaceCameraPos.xyz);
half displacementIntensity = length(displacement.rg - 0.5h);
half2 refractiveOffset = viewDir.xy * refractiveIndex * displacementIntensity * 0.05h;
#endif

鸣谢

URPGrabPass
Claude Code

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

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

相关文章

(三)软件架构设计

2024年博主考软考高级系统架构师没通过,于是决定集中精力认真学习系统架构的每一个环节,并在2025年软考中取得了不错的成绩,虽然做信息安全的考架构师很难,但找对方法,问题就不大! 本文主要是博主在学习过程…

切记使用mt19937构造随机数

在做 Kazaee CodeForces - 1746F 这个问题的时候,最初的时候使用了ran(),然后一直WA,遂改成mt19937,顺利通过本道题。 mt19937 Rand(time(0)); 调用随机数时候,使用: Rand() & 1 注意看&#xff0…

基于N32G45x+RTT驱动框架的定时器外部计数

时钟选择 高级控制定时器的内部时钟:CK_INT: 两种外部时钟模式: 外部输入引脚 外部触发输入 ETR 内部触发输入(ITRx):一个定时器用作另一个定时器的预分频器 外部时钟原理 通过配置 TIMx_SMCTRL.SMSEL=111 选择该模式。 计数器可以配置为在所选输入的时钟上升沿或下降沿 …

[特殊字符] Ubuntu 下 MySQL 离线部署教学(含手动步骤与一键脚本)

适用于 Ubuntu 20.04 / 22.04 无网络环境部署 MySQL。 建议初学者先按手动方式部署一遍理解原理,再使用自动化脚本完成批量部署。📁 一、准备工作 ✅ 1. 虚拟机环境 系统:Ubuntu 22.04(或兼容版本)环境:无网…

系统一个小时多次Full GC,导致系统线程停止运行,影响系统的性能,可靠性

背景: 某一天系统出现了请求超时,然后通过日志查看,程序执行到某一个位置,直接停下来来了,或者说所有的线程的执行都停下来了。而且是该时间段,请求处理变慢。排查相关的服务,并没有出现死锁&am…

使用OMV+NextCloud搭建私有云

原文地址:使用OMVNextCloud搭建私有云 – 无敌牛 欢迎参观我的网站:无敌牛 – 技术/著作/典籍/分享等 OpenMediaVault(简称OMV)是一款基于Debian的开源网络存储(NAS)操作系统,提供Web管理界面&…

Codeforces Round 1008 (Div. 2)

A. Final Verdict 题目大意 给你一个数组a,每次把他拆分为等长的k个子序列,然后用子序列的平均数替换掉这个子序列,问最后能不能让数组只剩下一个数字x 解题思路 无论怎么划分,最后的总值是不变的,所以只需要看总和…

python转移安装目录到D盘

迁移python安装路径第一步:移动目录第二步:修改环境变量之前没有设置之前设置过第一步:移动目录 源路径: C:\Users\Emma.ZRF\AppData\Local\Programs\Python\Python38 原环境变量 C:\Users\Emma.ZRF\AppData\Local\Programs\Pyth…

C#垃圾回收机制:原理与实践

C#垃圾回收机制:原理与实践 一、垃圾回收:C#内存管理的“幕后功臣”​ 二、GC的核心引擎:基于代的优化策略 三、Demo展示 1. 简单对象的垃圾回收示例 2. 基于代的回收示例 四、常用方法 五、推荐使用的场景 六、注意事项 管住手:避免滥用 GC.Collect() 析构函数:保持轻量 …

基于SpringBoot+MyBatis+MySQL+VUE实现的名城小区物业管理系统(附源码+数据库+毕业论文+开题报告+部署教程+配套软件)

摘要 当下,正处于信息化的时代,许多行业顺应时代的变化,结合使用计算机技术向数字化、信息化建设迈进。以前相关行业对于物业信息的管理和控制,采用人工登记的方式保存相关数据,这种以人力为主的管理模式已然落后。本人…

3DXML 转换为 UG 的技术指南及迪威模型网在线转换推荐

一、3DXML 转换为 UG 的必要性 (一)软件功能利用需求 3DXML 格式由达索系统开发,主要用于在其相关产品(如 CATIA、SOLIDWORKS 和 3DEXPERIENCE 等)中进行 3D 数据交换与轻量化可视化。它虽然能够很好地在达索生态内实…

无人机光伏巡检缺陷检出率↑32%:陌讯多模态融合算法实战解析

原创声明本文为原创技术解析,引用来源标注 “陌讯技术白皮书”,禁止未经授权的转载与改编。摘要在无人机光伏巡检场景中,边缘计算优化与复杂场景鲁棒性是提升检测效率的核心挑战。本文解析陌讯多模态融合算法在光伏板热斑、隐裂等缺陷检测中的…

仓库管理系统-15-前端之管理员管理和用户管理

文章目录 1 后台查询用户列表 1.1 null和空字符串的检查 1.2 UserController.java 2 管理员管理 2.1 传递参数roleId=1 2.2 admin/AdminManage.vue 3 用户管理 3.1 传递参数roleId=2 3.2 user/UserManage.vue 管理员管理和用户管理,与之前的Main.vue的内容基本一致,无非是管理…

个人笔记UDP

UDP消息发送发送端​ import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; ​ //不需要连接服务器 public class UdpClientDemo01 {public static void main(String[] args) throws Exception {/…

26届算法秋招_baidu笔试_算法编程题。

给定2个字符串str1、str2,计算把str1转变为str2的最小操作数。可执行的操作有:插入一个字符修改一个字符删除一个字符解题:这是一个经典的编辑距离问题,通常使用动态规划解决。定义dp[i][j]表示将str1的前i个字符转换为str2的前j个…

uniapp-vue3来实现一个金额千分位展示效果

前言:uniapp-vue3来实现一个金额千分位展示效果实现效果:实现目标:1、封装组件,组件内部要实现,input输入金额后,聚焦离开后,金额以千分位效果展示,聚焦后展示大写金额的弹框随时写的…

途游Android面试题及参考答案

对 Java 面向对象的理解是什么?多态的实现方法有哪些? Java 面向对象是一种编程思想,核心在于将现实世界中的事物抽象为 “对象”,每个对象由 “属性”(数据)和 “方法”(行为)组成,通过对象之间的交互完成功能。其核心特性包括封装、继承和多态: 封装是指将对象的属…

通过filezilla在局域网下实现高速传输数据

一. filezilla安装 1.1 linux安装 sudo apt update sudo apt install openssh-server1.2 windows安装 windows安装可以参考这篇文章 二. 使用方法 2.1 wifi下使用方法 直接查看想要连接的电脑的ip,其他的按照有线网络设置好了ip之后进行连接就行。 2.2 有线网…

python的易物小店交换系统

前端开发框架:vue.js 数据库 mysql 版本不限 后端语言框架支持: 1 java(SSM/springboot)-idea/eclipse 2.NodejsVue.js -vscode 3.python(flask/django)–pycharm/vscode 4.php(thinkphp/laravel)-hbuilderx 数据库工具:Navicat/SQLyog等都可以 在需求分…

[硬件电路-119]:模拟电路 - 信号处理电路 - 比较器,模拟电路中的“决策者”,模拟信号到数字电平逻辑信号的转化者...

前言:比较器的价值1、为何称比较器为“决策者”?逻辑判断的物理实现比较器通过硬件电路直接完成“大于/小于”的二元判断,无需软件干预。例如:在过压保护电路中,比较器实时监测输入电压 Vin​ 与参考电压 Vref​&#…