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

Unity中Shader抓取屏幕并实现扭曲效果(优化)

文章目录

  • 前言
  • 一、在之前顶点着色器的输入中,放弃了使用结构体传入,而是直接从应用程序阶段传入参数,这样写的话,对于程序来说,不方便扩张,所以需要对其进行修改
    • 实现
      • 1、定义结构体用于传入顶点坐标系
      • 2、因为UnityObjectToClipPos是从本地空间转换到裁剪空间,但是没有进行透视除法,所以需要对其进行透视除法,用转化后的结果的 xyz / w 就可以进行透视除法
      • 3、因为屏幕坐标的原点一般在左上角(DirectX) 或 左下角(OpenGL) (我的是DirectX平台,所以在左上角。),会造成显示的位置,和我们需要的位置不同,所以需要对其进行计算平移缩放处理
  • 二、改用Unity内置提供的方法(平台间互通)
  • 三、最后加上扭曲


前言

对上一篇中实现的shader进行优化


一、在之前顶点着色器的输入中,放弃了使用结构体传入,而是直接从应用程序阶段传入参数,这样写的话,对于程序来说,不方便扩张,所以需要对其进行修改

实现

1、定义结构体用于传入顶点坐标系

struct appdata
{
float4 vertex : POSITION;
//从应用程序阶段的输入,多加一个uv,用于对扭曲纹理的采样
float2 uv : TEXCOORD;
};

2、因为UnityObjectToClipPos是从本地空间转换到裁剪空间,但是没有进行透视除法,所以需要对其进行透视除法,用转化后的结果的 xyz / w 就可以进行透视除法

v2f vert (appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv,_DistortTex) + _Distort.xy * _Time.y;
//把本地空间转化到其次裁剪空间后的结果,进行透视除法后, 传给 screenUV
o.screenUV.xyz = o.pos.xyz / o.pos.w;
return o;
}


3、因为屏幕坐标的原点一般在左上角(DirectX) 或 左下角(OpenGL) (我的是DirectX平台,所以在左上角。),会造成显示的位置,和我们需要的位置不同,所以需要对其进行计算平移缩放处理

在这里插入图片描述

DirectX平台:fixed2 uv = fixed2(i.screenUV.x * 0.5,i.screenUV.y * -0.5) + 0.5;
OpenGL平台:fixed2 uv = i.screenUV * 0.5 + 0.5;

改到顶点着色器中计算

DirectX平台:
o.screenUV.x = o.screenUV.x * 0.5 + 0.5;
o.screenUV.y = o.screenUV.y * -0.5 + 0.5;
OpenGL平台:
o.screenUV.x = o.screenUV * 0.5 + 0.5;

在这里插入图片描述

但是这样是插值计算的会有误差瑕疵,所以还是改在片元着色器中计算

DirectX平台:
fixed2 uv = i.screenUV.xy / i.screenUV.w;
uv.x = uv.x * 0.5 +0.5;
uv.y = uv.y * -0.5 + 0.5;


二、改用Unity内置提供的方法(平台间互通)

ComputeScreenPos(float4 pos)
pos为裁剪空间下的坐标位置,返回的是某个投影点下的屏幕坐标位置
由于这个函数返回的坐标值并未除以齐次坐标,所以如果直接使用函数的返回值的话,需要使用:tex2Dproj(_ScreenTexture, uv.xyw);
也可以自己处理其次坐标,使用:tex2D(_ScreenTexture, uv.xy / uv.w);

在顶点着色器:o.screenUV = ComputeScreenPos(o.pos);
在片元着色器:fixed4 grabTex = tex2Dproj(_GrabTex,i.screenUV);


三、最后加上扭曲

Shader "MyShader/P0_10_5"
{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 appdata{float4 vertex : POSITION;//从应用程序阶段的输入,多加一个uv,用于对扭曲纹理的采样float2 uv : TEXCOORD;};struct v2f{float2 uv : TEXCOORD0;float4 pos : SV_POSITION;float4 screenUV:TEXCOORD1;};//在使用抓取的屏幕前,需要像使用属性一样定义一下,_GrabTexture这个名字是Unity定义好的sampler2D _GrabTex;sampler2D _DistortTex;float4 _DistortTex_ST;float4 _Distort;v2f vert (appdata v){v2f o;o.pos = UnityObjectToClipPos(v.vertex);o.uv = TRANSFORM_TEX(v.uv,_DistortTex) + _Distort.xy * _Time.y;//pos为裁剪空间下的坐标位置,返回的是某个投影点下的屏幕坐标位置o.screenUV = ComputeScreenPos(o.pos);return o;}fixed4 frag (v2f i) : SV_Target{//DirectX平台:/*fixed2 uv = i.screenUV.xy / i.screenUV.w;uv.x = uv.x * 0.5  +0.5;uv.y = uv.y * -0.5 + 0.5;*/fixed4 distortTex = tex2D(_DistortTex,i.uv);//使用线性插值来控制UV的扭曲程度float2 uv = lerp(i.screenUV.xy/i.screenUV.w,distortTex,_Distort.z);//对抓取的屏幕进行采样fixed4 grabTex = tex2D(_GrabTex,uv);return grabTex;}ENDCG}}
}

效果:
请添加图片描述

相关文章:

Unity中Shader抓取屏幕并实现扭曲效果(优化)

文章目录 前言一、在之前顶点着色器的输入中,放弃了使用结构体传入,而是直接从应用程序阶段传入参数,这样写的话,对于程序来说,不方便扩张,所以需要对其进行修改实现1、定义结构体用于传入顶点坐标系2、因为…...

肖sir__设计测试用例方法之_(白盒测试)

白盒测试技术 一、定义: 白盒测试也叫透明盒测试,检查程序内部结构及路径一是否符合规格说明,二是否符合其代码规范。 因此,也叫结构测试或者逻辑驱动测试。 二、白盒测试常见方法: a、语句覆盖; b、判断覆…...

GoT:用大语言模型解决复杂的问题

GoT:用大语言模型解决复杂的问题 摘要介绍背景和符号表示语言模型和上下文学习Input-Output(IO)Chain of thought(CoT)Multiple CoTTree of thoughts(ToT) GoT框架推理过程思维变换聚合变换&…...

nginx服务和uwsgi服务如何设置开机自启动

上次学到了在云服务器下如何部署Django项目,用到了nginx服务和uwsgi服务,需要手工启动这2个服务的命令。 现在考虑如何设置开机自启动,为什么要这样考虑?因为服务器万一出问题,意外重启了,那我们部署的Dja…...

算法-分治算法

文章来源: https://blog.csdn.net/weixin_45630258/article/details/126425400 欢迎各位大佬指点、三连 一、分治 1、定义:分治,也就是分而治之。 它的一般步骤是: ① 将原问题分解成若干个规模较小的子问题(子问题…...

react 实现监听逻辑

需求: 在一个页面下有多个子tab在某些tab 下,或者父节点的数据更新的时候,其他子tab 或者父节点也要同步更新 进程: 正常情况下会把所有用到的数据都移动到父节点,修改行为也都放在父节点但如果这样的话父节点的数据…...

vue项目一个页面包含多个时间选择器的处理方案

描述:vue项目中如果在一个页面使用多个时间选择器组件时,不同的时间选择器需要分别分开工作 解决方案一 原本是想直接每一个时间选择器都安排一套相对独立的维生系统,但是到后面发现繁琐至极,而且报错,果断放弃&#…...

机器学习入门教学——决策树

1、简介 决策树算法是一种归纳分类算法,它通过对训练集的学习,挖掘出有用的规则,用于对新数据进行预测。决策树算法属于监督学习方法。决策树归纳的基本算法是贪心算法,自顶向下来构建决策树。 贪心算法:在每一步选择…...

文献阅读:Chain-of-Thought Prompting Elicits Reasoning in Large Language Models

文献阅读:Chain-of-Thought Prompting Elicits Reasoning in Large Language Models 1. 文章简介2. 具体方法3. 实验结果 1. 数学推理 1. 实验设计2. 实验结果3. 消解实验4. 鲁棒性考察 2. 常识推理 1. 实验设计2. 实验结果 3. 符号推理 1. 实验设计2. 实验结果 4.…...

从零开发一款ChatGPT VSCode插件

‍本文作者是360奇舞团开发工程师 引言 OpenAI发布了ChatGPT,就像是给平静许久的互联网湖面上扔了一颗重磅炸弹,刹那间所有人都在追捧学习它。究其原因,它其实是一款真正意义上的人工智能对话机器人。它使用了深度学习技术,通过大…...

go基础09-Go语言的字符串类型

字符串类型是现代编程语言中最常使用的数据类型之一。在Go语言的先祖之一C语言当中,字符串类型并没有被显式定义,而是以字符串字面值常量或以’\0’结尾的字符类型(char)数组来呈现的: #define GOAUTHERS "Rober…...

【C++模拟实现】手撕AVL树

【C模拟实现】手撕AVL树 目录 【C模拟实现】手撕AVL树AVL树的介绍(百度百科)AVL树insert函数的实现代码验证是否为AVL树AVL树模拟实现的要点易忘点AVL树的旋转思路 作者:爱写代码的刚子 时间:2023.9.10 前言:本篇博客将…...

如何重置 docker中的mariadb的root

停止 Mariadb 容器&#xff1a;运行以下命令停止正在运行的 Mariadb 容器&#xff1a; docker stop <container_name>将 <container_name> 替换为你的 Mariadb 容器的名称或容器ID。 删除 Mariadb 容器&#xff1a;运行以下命令删除已停止的 Mariadb 容器&#x…...

设计模式系列-原型模式

一、上篇回顾 上篇创建者模式中&#xff0c;我们主要讲述了创建者的几类实现方案&#xff0c;和创建者模式的应用的场景和特点&#xff0c;创建者模式适合创建复杂的对象&#xff0c;并且这些对象的每 个组成部分的详细创建步骤可以是动态的变化的&#xff0c;但是每个对象的组…...

家用电脑可以用做服务器吗

家用电脑的结构与服务器的结构是相同的&#xff0c;家用电脑是可以用来搭建服务器使用。但使用家用电脑做服务器在稳定性会比服务器差很多 1.家用电脑没有公网IP&#xff0c;网络运营商分配的IP重启路由之后是会变化&#xff0c;不固定。服务器运行是需要有固定IP让人连接访问。…...

CRM软件管理系统的基本功能

CRM管理系统是企业运营的重要工具&#xff0c;它可以帮助企业管理客户关系&#xff0c;提升销售效率&#xff0c;大幅提高客户转化率&#xff0c;实现业绩增长。那么&#xff0c;CRM管理系统一般包含哪些功能呢&#xff1f;下面我们就来说说。 1、销售自动化 销售自动化顾名思…...

手机喊话应用实现思路

手机要是动一下&#xff0c;就喊话“摇摇零线&#xff0c;摇摇零线”&#xff0c;是不是比较酷&#xff0c; 这里实现一下手机翻转一下&#xff0c;播放声音的效果&#xff0c; 通过sensor识别到手机的运动状况&#xff0c;然后播放音频&#xff0c; public class MainActivi…...

【ARM CoreLink 系列 3 -- CCI-550 控制器介绍 】

文章目录 CCI FamilyCCI-550 简介CCI-550 功能CCI-550 Interfaces Snoop filter 使用背景CCI-550 Snoop filter 上篇文章&#xff1a;ARM CoreLink 系列 2 – CCI-400 控制器简介 CCI Family CCI-550 简介 Arm CoreLink CCI-550 Cache Coherent Interconnect 扩展了 CoreLink…...

最长递增子序列 -- 动规

300. 最长递增子序列 注意「⼦序列」和「⼦串」的区别&#xff0c;⼦串⼀定是连续的&#xff0c;⽽⼦序列不⼀定是连续的。 class LengthOfLIS:"""300. 最长递增子序列https://leetcode.cn/problems/longest-increasing-subsequence/description/""&q…...

linux 进程管理命令

进程管理命令 查看进程命令 ps命令 显示系统上运行的进程列表 # 查看系统中所有正在运行的系统ps aux# 获取占用内存资源最多的10个进程&#xff0c;可以使用如下命令组合&#xff1a;ps aux|head -1;ps aux|grep -v PID|sort -rn -k 4|head# 获取占用CPU资源最多的10个进程&am…...

【网络】每天掌握一个Linux命令 - iftop

在Linux系统中&#xff0c;iftop是网络管理的得力助手&#xff0c;能实时监控网络流量、连接情况等&#xff0c;帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?

大家好&#xff0c;欢迎来到《云原生核心技术》系列的第七篇&#xff01; 在上一篇&#xff0c;我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在&#xff0c;我们就像一个拥有了一块崭新数字土地的农场主&#xff0c;是时…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

问题描述&#xff1a;iview使用table 中type: "index",分页之后 &#xff0c;索引还是从1开始&#xff0c;试过绑定后台返回数据的id, 这种方法可行&#xff0c;就是后台返回数据的每个页面id都不完全是按照从1开始的升序&#xff0c;因此百度了下&#xff0c;找到了…...

React Native在HarmonyOS 5.0阅读类应用开发中的实践

一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强&#xff0c;React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 &#xff08;1&#xff09;使用React Native…...

家政维修平台实战20:权限设计

目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系&#xff0c;主要是分成几个表&#xff0c;用户表我们是记录用户的基础信息&#xff0c;包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题&#xff0c;不同的角色&#xf…...

高防服务器能够抵御哪些网络攻击呢?

高防服务器作为一种有着高度防御能力的服务器&#xff0c;可以帮助网站应对分布式拒绝服务攻击&#xff0c;有效识别和清理一些恶意的网络流量&#xff0c;为用户提供安全且稳定的网络环境&#xff0c;那么&#xff0c;高防服务器一般都可以抵御哪些网络攻击呢&#xff1f;下面…...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元&#xff08;GRU&#xff09;长短期记忆神经网络&#xff08;LSTM&#xff09…...

Go 语言并发编程基础:无缓冲与有缓冲通道

在上一章节中&#xff0c;我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道&#xff0c;它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好&#xff0…...

排序算法总结(C++)

目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指&#xff1a;同样大小的样本 **&#xff08;同样大小的数据&#xff09;**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能

1. 开发环境准备 ​​安装DevEco Studio 3.1​​&#xff1a; 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK ​​项目配置​​&#xff1a; // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...