当前位置: 首页 > news >正文

Unity中Shader抓取屏幕并实现扭曲效果

文章目录

  • 前言
  • 一、屏幕抓取,在上一篇文章已经写了
  • 二、实现抓取后的屏幕扭曲
    • 实现思路:
      • 1、屏幕扭曲要借助传入 UV 贴图进行扭曲
      • 2、传入贴图后在顶点着色器的输入参数处,传入一个 float2 uv : TEXCOORD,用于之后对扭曲贴图进行采样
      • 3、最后在片元着色器阶段使用lerp(screenUV,distortTex,_Distort);进行线性插值对扭曲程度进行控制
  • 三、在扭曲的效果上实现流动效果
    • 实现思路:
  • 四、为了节省性能,把_Distort 、_SpeedX 和 _SpeedY三个变量用一个四维变量存储


前言

Unity中Shader抓取屏幕并实现扭曲效果实现


一、屏幕抓取,在上一篇文章已经写了

二、实现抓取后的屏幕扭曲

实现思路:

1、屏幕扭曲要借助传入 UV 贴图进行扭曲

2、传入贴图后在顶点着色器的输入参数处,传入一个 float2 uv : TEXCOORD,用于之后对扭曲贴图进行采样

3、最后在片元着色器阶段使用lerp(screenUV,distortTex,_Distort);进行线性插值对扭曲程度进行控制

代码实现:

Shader "MyShader/P0_10_4"
{Properties{//实现扭曲,就需要传入贴图来实现扰度_DistortTex("DistortTex",2D) = "white"{}_Distort("Distort",Range(0,1)) = 0}SubShader{Tags{"Queue" = "Transparent"}//屏幕抓取需要单独使用一个Pass —— GrabPass{} 里面什么都不写,或者GrabPass{"_GrabTex"}GrabPass{"_GrabTex"}Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct v2f{float2 uv : TEXCOORD0;};//在使用抓取的屏幕前,需要像使用属性一样定义一下,_GrabTexture这个名字是Unity定义好的sampler2D _GrabTex;sampler2D _DistortTex;float4 _DistortTex_ST;fixed _Distort;//在顶点着色器的输入处,不用appdata,直接使用用到的参数,防止 SV_POSITION 重复定义v2f vert (float4 vertex : POSITION,//从应用程序阶段的输入,多加一个uv,用于对扭曲纹理的采样float2 uv : TEXCOORD,out float4 pos : SV_POSITION){v2f o;pos = UnityObjectToClipPos(vertex);o.uv = uv;return o;}fixed4 frag (v2f i,UNITY_VPOS_TYPE screenPos : VPOS) : SV_Target{fixed2 screenUV = screenPos.xy / _ScreenParams.xy;fixed4 distortTex = tex2D(_DistortTex,i.uv);//使用线性插值来控制UV的扭曲程度float2 uv = lerp(screenUV,distortTex,_Distort);//对抓取的屏幕进行采样fixed4 grabTex = tex2D(_GrabTex,uv);return grabTex;}ENDCG}}
}

三、在扭曲的效果上实现流动效果

实现思路:

在顶点着色器处,使用扭曲贴图的Tiling 及 offset 后与_Time相乘即可,流动速度,暴露两个float变量控制流速即可

代码实现:

Shader "MyShader/P0_10_4"
{Properties{//实现扭曲,就需要传入贴图来实现扰度_DistortTex("DistortTex",2D) = "white"{}_Distort("Distort",Range(0,1)) = 0_SpeedX("SpeedX",float) = 0_SpeedY("SpeedY",float) = 0}SubShader{Tags{"Queue" = "Transparent"}//屏幕抓取需要单独使用一个Pass —— GrabPass{} 里面什么都不写,或者GrabPass{"_GrabTex"}GrabPass{"_GrabTex"}//使用Cull off 让两面都有扭曲Cull OffPass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct v2f{float2 uv : TEXCOORD0;};//在使用抓取的屏幕前,需要像使用属性一样定义一下,_GrabTexture这个名字是Unity定义好的sampler2D _GrabTex;sampler2D _DistortTex;float4 _DistortTex_ST;fixed _Distort;float _SpeedX,_SpeedY;//在顶点着色器的输入处,不用appdata,直接使用用到的参数,防止 SV_POSITION 重复定义v2f vert (float4 vertex : POSITION,//从应用程序阶段的输入,多加一个uv,用于对扭曲纹理的采样float2 uv : TEXCOORD,out float4 pos : SV_POSITION){v2f o;pos = UnityObjectToClipPos(vertex);o.uv = TRANSFORM_TEX(uv,_DistortTex) + float2(_SpeedX,_SpeedY) * _Time.y;return o;}fixed4 frag (v2f i,UNITY_VPOS_TYPE screenPos : VPOS) : SV_Target{fixed2 screenUV = screenPos.xy / _ScreenParams.xy;fixed4 distortTex = tex2D(_DistortTex,i.uv);//使用线性插值来控制UV的扭曲程度float2 uv = lerp(screenUV,distortTex,_Distort);//对抓取的屏幕进行采样fixed4 grabTex = tex2D(_GrabTex,uv);return grabTex;}ENDCG}}
}

效果:
请添加图片描述

四、为了节省性能,把_Distort 、_SpeedX 和 _SpeedY三个变量用一个四维变量存储

优化后:

Shader "MyShader/P0_10_4"
{Properties{//实现扭曲,就需要传入贴图来实现扰度_DistortTex("DistortTex",2D) = "white"{}_Distort("SpeedX(X) SpeedY(y) Distort(Z)",vector) = (0,0,0,0)}SubShader{Tags{"Queue" = "Transparent"}//屏幕抓取需要单独使用一个Pass —— GrabPass{} 里面什么都不写,或者GrabPass{"_GrabTex"}GrabPass{"_GrabTex"}//使用Cull off 让两面都有扭曲Cull OffPass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct v2f{float2 uv : TEXCOORD0;};//在使用抓取的屏幕前,需要像使用属性一样定义一下,_GrabTexture这个名字是Unity定义好的sampler2D _GrabTex;sampler2D _DistortTex;float4 _DistortTex_ST;float4 _Distort;//在顶点着色器的输入处,不用appdata,直接使用用到的参数,防止 SV_POSITION 重复定义v2f vert (float4 vertex : POSITION,//从应用程序阶段的输入,多加一个uv,用于对扭曲纹理的采样float2 uv : TEXCOORD,out float4 pos : SV_POSITION){v2f o;pos = UnityObjectToClipPos(vertex);o.uv = TRANSFORM_TEX(uv,_DistortTex) + _Distort.xy * _Time.y;return o;}fixed4 frag (v2f i,UNITY_VPOS_TYPE screenPos : VPOS) : SV_Target{fixed2 screenUV = screenPos.xy / _ScreenParams.xy;fixed4 distortTex = tex2D(_DistortTex,i.uv);//使用线性插值来控制UV的扭曲程度float2 uv = lerp(screenUV,distortTex,_Distort.z);//对抓取的屏幕进行采样fixed4 grabTex = tex2D(_GrabTex,uv);return grabTex;}ENDCG}}
}

相关文章:

Unity中Shader抓取屏幕并实现扭曲效果

文章目录 前言一、屏幕抓取,在上一篇文章已经写了二、实现抓取后的屏幕扭曲实现思路:1、屏幕扭曲要借助传入 UV 贴图进行扭曲2、传入贴图后在顶点着色器的输入参数处,传入一个 float2 uv : TEXCOORD,用于之后对扭曲贴图进行采样3、…...

深浅拷贝详解

深浅拷贝 经典真题 深拷贝和浅拷贝的区别?如何实现 深拷贝和浅拷贝概念 首先,我们需要明确深拷贝和浅拷贝的概念。 浅拷贝:只是拷贝了基本类型的数据,而引用类型数据,复制后也是会发生引用,我们把这种拷…...

@Scheduled 定时任务

Scheduled(cron"30 * * * * ?") 1.cron表达式格式: {秒数} {分钟} {小时} {日期} {月份} {星期} {年份(可为空)} 2.cron表达式各占位符解释: {秒数}{分钟} > 允许值范围: 0~59 ,不允许为空值,若值不合法,调度器将…...

丙烯酸共聚聚氯乙烯树脂

声明 本文是学习GB-T 42790-2023 丙烯酸共聚聚氯乙烯树脂. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本文件规定了丙烯酸共聚聚氯乙烯树脂的外观、物化性能等技术要求,描述了相应的采样、试验方 法、检验规则、标志、包装、…...

Navicat导入Excel数据顺序变了

项目场景: Navicat导入Excel数据 问题描述 从Excel表格中导入数据到数据库中。但是,在导入的过程中,我们常会发现数据顺序出现了问题,导致数据错位,给数据的处理带来了极大的麻烦。 原因分析: 这个问题的…...

uni-app的生命周期

uni-app的生命周期包括应用生命周期和页面生命周期。 应用生命周期涵盖了整个uni-app应用的启动、运行和销毁过程,主要包括以下几个生命周期函数: onLaunch:应用初始化时触发,只触发一次。onShow:应用启动或从后台进…...

Vulnhub实战-DC9

前言 本次的实验靶场是Vulnhub上面的DC-9,其中的渗透测试过程比较多,最终的目的是要找到其中的flag。 一、信息收集 对目标网络进行扫描 arp-scan -l 对目标进行端口扫描 nmap -sC -sV -oA dc-9 192.168.1.131 扫描出目标开放了22和80两个端口&a…...

软件设计模式系列之七——原型模式

1 模式的定义 原型模式(Prototype Pattern)是一种创建型设计模式,其主要目的是通过复制现有对象来创建新对象,而不是使用构造函数。原型模式将对象的创建委托给原型对象,通过克隆(复制)来生成新…...

PMP考试注意事项有哪些?

1. PMI明确规定:不允许考生使用自带文具,包括自带的笔、削笔刀、橡皮、笔袋、计算器和草稿纸等。 2. 本次考试考场内为每位考生配备2B铅笔、橡皮、计算器(若有需要)和草稿纸。如文具有缺损或考试过程中如需更换铅芯等,请向监考老师举手示意。…...

chartgpt+midjourney

chatGPT程序化生成故事 英文版脚本步骤 步骤一:在chatgpt中输入以下脚本,,标红为可变的文字,输入你想要的,目前是科幻,即科幻故事,你可以改为 fairy-tale,则写的是童话故事&#x…...

【SpringMVC】自定义注解

【SpringMVC】自定义注解 前言1. 什么是注解?2. 注解的用处3. 注解的原理1.1. Override1.2. SuppressWarnings 2. JDK元注解2.1. Retention2.2. Target2.3. Inherited2.4. Documented 3. 自定义注解3.1. 自定义注解的分类注解类 结语 自定义注解及其应用 前言 在J…...

【李沐深度学习笔记】数据操作实现

课程地址 数据操作实现p2 数据操作 首先导入PyTorch包(import torch),虽然叫PyTorch,但实际上要导入torch。 import torch张量 张量表示的是一个数值组成的数组,这个数组可以有很多个维度。 # 生成0-11的顺序序列构成的一维…...

【深度学习-注意力机制attention 在seq2seq中应用】

注意力机制 为什么需要注意力机制attention机制的架构总体设计一、attention本身实现评分函数 attention在网络模型的应用-Bahdanau 注意力加性注意力代码实现 为什么需要注意力机制 这是一个普通的seq2seq结构,用以实现机器对话,Encoder需要把一个输入的…...

详解混合类型文件(Polyglot文件)的应用生成与检测

1. 引入 混合类型文件(Polyglot文件),是指一个文件,既可以是合法的A类型,也可以是合法的B类型。 比如参考3中的文件,是一个html文件,可以用浏览器正常打开;它也是一个一个.jar文件&…...

QT之QTableView的简介

QT之QTableView的简介 QTableView 是 Qt 框架中的一个类,用于显示和编辑表格数据。它提供了一个灵活的模型/视图架构,允许用户以不同的方式显示和编辑数据。 以下是 QTableView 的一些常用函数及其用法: 1)QTableView(QWidget *pa…...

学习记忆——宫殿篇——记忆宫殿——记忆桩——知识讲解

类比 假设这些桩子好比不同的交通工具,每一种交通工具都可以助我们到达目的地,那举现在就根据你的时间以及现实情况,选择最合适自己的交通工具即可,重点在于你要熟悉每种交通工具的用途不区别。桩子也是如此,把所有的桩…...

Python lambda匿名函数

视频版教程 Python3零基础7天入门实战视频教程 前面我们所学的函数定义,都是有函数名的。 我们现在学的lambda函数是没有名称的,也就是匿名函数。 我们在只需要一次性使用的函数的时候,就可以用lambda匿名函数,简单方便快捷。 …...

成绩统计(蓝桥杯)

成绩统计 题目描述 小蓝给学生们组织了一场考试,卷面总分为 100 分,每个学生的得分都是一个 0 到 100 的整数。 如果得分至少是 60 分,则称为及格。如果得分至少为 85 分,则称为优秀。 请计算及格率和优秀率,用百分数…...

ETL与ELT理解

ETL ETL( Extract-Transform-Load),用来描述将数据从来源端经过抽取(Extract)、转换(Transform)、加载(Load)至目的端的过程。ETL模式适用于小数据量集。如果在转换过程…...

IntelliJ IDEA 2023 年下载、安装教程、好用插件推荐

文章目录 下载与安装IDEA常用插件推荐Alibaba Java Coding Guidelines(阿里巴巴Java开发规约)Key Promoter X(IDEA快捷键提示)Translation(翻译插件)Save Actions(优化保存插件)Codo…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

渲染学进阶内容——模型

最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

Frozen-Flask :将 Flask 应用“冻结”为静态文件

Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是&#xff1a;将一个 Flask Web 应用生成成纯静态 HTML 文件&#xff0c;从而可以部署到静态网站托管服务上&#xff0c;如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

QT: `long long` 类型转换为 `QString` 2025.6.5

在 Qt 中&#xff0c;将 long long 类型转换为 QString 可以通过以下两种常用方法实现&#xff1a; 方法 1&#xff1a;使用 QString::number() 直接调用 QString 的静态方法 number()&#xff0c;将数值转换为字符串&#xff1a; long long value 1234567890123456789LL; …...

算法岗面试经验分享-大模型篇

文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer &#xff08;1&#xff09;资源 论文&a…...

免费数学几何作图web平台

光锐软件免费数学工具&#xff0c;maths,数学制图&#xff0c;数学作图&#xff0c;几何作图&#xff0c;几何&#xff0c;AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...

NPOI操作EXCEL文件 ——CAD C# 二次开发

缺点:dll.版本容易加载错误。CAD加载插件时&#xff0c;没有加载所有类库。插件运行过程中用到某个类库&#xff0c;会从CAD的安装目录找&#xff0c;找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库&#xff0c;就用插件程序加载进…...

水泥厂自动化升级利器:Devicenet转Modbus rtu协议转换网关

在水泥厂的生产流程中&#xff0c;工业自动化网关起着至关重要的作用&#xff0c;尤其是JH-DVN-RTU疆鸿智能Devicenet转Modbus rtu协议转换网关&#xff0c;为水泥厂实现高效生产与精准控制提供了有力支持。 水泥厂设备众多&#xff0c;其中不少设备采用Devicenet协议。Devicen…...