庄懂的TA笔记(十七)<特效:屏幕UV + 屏幕扰动>
庄懂的TA笔记(十七)<特效:屏幕UV + 屏幕扰动>
大纲:
目录
庄懂的TA笔记(十七)<特效:屏幕UV + 屏幕扰动>
大纲:
正文:
一、屏幕UV:
二、屏幕扰动:
三、任务委托:
正文:

一、屏幕UV:

1、案例展示:


屏幕UV在过往案例使用中,出现了 镜头畸变,纹理大小不能锁定等问题,这节内容就把屏幕UV的使用全部讲完。
这个效果中是 没有边缘畸变的,到边缘是完完整整的平铺上去的。所以屏幕UV 的重点就在这两个部分。
畸变解决:
纹理大小锁定:
2、实现思路:
主图透贴纹理UV + 屏幕纹理UV流动 = 最终ScreenUV效果;
3、代码实现:

①、面板参数定义:
_MainTex : (RGB : 颜色 A : 透贴 ,2d)="gray"{}
_Opacity :("透明",range(0,1))=0.5
这里屏幕坐标纹的Tillng 和 offset是要用到的,所以需要追加_ST。
_ScreenTex : ("屏幕纹理" , 2d) = "black"{}

②、输出结构:
因为需要用到 主图UV 和 屏幕UV ,所以这里要定义出,uv,和 screenUV.
③、顶点shader输入输出:
float3 posVS = UnityObjectToViewPos(v.vertex).xyz; // 获取顶点位置到摄像机位置的xyz。
o.ScreenUV1 = posVS.xy;//赋值给屏幕UV 。
像素shader: (中间输出测试监测)
float3 var_ScreenTex = tex2D(_ScreenTex,i.ScreenUV1);
return float4(var_ScreenTex,1);
重点:屏幕UV 位置,畸变修正,纹理大小锁定。
取屏幕空间UV位置,取xyz三个轴,
如何理解Vive空间呢?Vive空间相当于以摄像机平面为基准的空间,XY轴对应UV,Z轴对应深度。
但是,正常我们将 XY轴向的UV采样后,会发现贴图在模型表面会有畸变,
如图:

解决方法: 也很简单,直接xy ➗ z 深度 就好了。
o.screenUV = posVS.xy / posVS.z; // VS空间畸变校正
但矫正过后,还会有一个问题,就是你的屏幕UV纹理,相对于你的屏幕Tiling大小是不随距离改变的,正常是模型纹理,会随距离,近大远小的,所以这里我们需要对屏幕UV纹理进行锁定。
如图;

解决方法:得到观察空间的距离,第一个就需要获得模型的原点.
UnityObjectToVivePos float3(0,0,0).z
声明一个orignDist存 模型原点,到 距离摄像机的距离。
float3 orignDist = UnityObjectToVivePos(float3(0,0,0)).z;
然后 在将 屏幕UV * 距离(模型到相机的距离) = 锁定后的屏幕UV.(锁定屏幕UV);
o.screenUV = posVS.xy / posVS.z; // VS空间畸变校正
o.screenUV *= originDist; // 纹理大小按距离锁定
o.screenUV * = orignDist; or o.screenUV = o.screenUV * orignDist(两种方式等价)
综上所属,主要问题就解决了。
如图:

④、屏幕UV滚动:
这里就控制Tiling和offset 流动起来,
ScreenTex_ST. X Y 对应 Tiling的 X Y ;
ScreenTex_ST. Z W 对应 offset的 Z W ;
o.screenUV = o.screenUV * _ScreenTex_ST.X Y - frac(_Time * _ScreenTex_ST.Z W);
(这里 的 + - 都可以用,主要是控制 流动方向的)
o.screenUV=o.screenUV*_ScreenTex_ST.xy - frac(_Time.x * _ScreenTex_ST.zw)启用屏幕纹理ST
如图:

⑤、像素shader:
采样 两张图,两个UV ,主贴图,屏幕空间贴图。
混合透明 = 主图var_MainTex.a * 不透明_Opacity * 屏幕贴图var_ScreenTex;
float3 FinalRGB = var_MainTex.rgb ;
float opacity = var_MainTex.a * _Opacity * var_ScreenTex;
return float4 (FinalRGB * opacity , opacity);
4、核心代码:

重要的就是这一段, (屏幕UV 矫正 和 锁定)
5、屏幕UV 代码示例:
Shader "AP01/L17/ScreenUV" {Properties {_MainTex ("RGB:颜色 A:透贴", 2d) = "gray"{}_Opacity ("透明度", range(0, 1)) = 0.5_ScreenTex ("屏幕纹理", 2d) = "black" {}}SubShader {Tags {"Queue"="Transparent" // 调整渲染顺序"RenderType"="Transparent" // 对应改为Cutout"ForceNoShadowCasting"="True" // 关闭阴影投射"IgnoreProjector"="True" // 不响应投射器}Pass {Name "FORWARD"Tags {"LightMode"="ForwardBase"}Blend One OneMinusSrcAlpha // 混合方式CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"#pragma multi_compile_fwdbase_fullshadows#pragma target 3.0// 输入参数uniform sampler2D _MainTex;uniform half _Opacity;uniform sampler2D _ScreenTex; uniform float4 _ScreenTex_ST;// 输入结构struct VertexInput {float4 vertex : POSITION; // 顶点位置 OSfloat2 uv : TEXCOORD0; // UV信息};// 输出结构struct VertexOutput {float4 pos : SV_POSITION; // 顶点位置 CSfloat2 uv : TEXCOORD0; // UV信息float2 screenUV : TEXCOORD1; // 屏幕UV};// 输入结构>>>顶点Shader>>>输出结构VertexOutput vert (VertexInput v) {VertexOutput o = (VertexOutput)0;o.pos = UnityObjectToClipPos(v.vertex); // 顶点位置 OS>CSo.uv = v.uv; // UV信息float3 posVS = UnityObjectToViewPos(v.vertex).xyz; // 顶点位置 OS>VSfloat originDist = UnityObjectToViewPos(float3(0.0, 0.0, 0.0)).z; // 原点位置 OS>VSo.screenUV = posVS.xy / posVS.z; // VS空间畸变校正o.screenUV *= originDist; // 纹理大小按距离锁定o.screenUV = o.screenUV * _ScreenTex_ST.xy - frac(_Time.x * _ScreenTex_ST.zw); // 启用屏幕纹理STreturn o;}// 输出结构>>>像素half4 frag(VertexOutput i) : COLOR {half4 var_MainTex = tex2D(_MainTex, i.uv); // 采样 基本纹理 RGB颜色 A透贴half var_ScreenTex = tex2D(_ScreenTex, i.screenUV).r; // 采样 屏幕纹理// FinalRGB 不透明度half3 finalRGB = var_MainTex.rgb;half opacity = var_MainTex.a * _Opacity * var_ScreenTex;// 返回值return half4(finalRGB * opacity, opacity);}ENDCG}}
} 二、屏幕扰动:

1、案例展示:


2、实现思路:
屏幕扰动(玻璃效果)
背景信息获取:
MainTex 红或蓝通道扭曲:
①、面板参数定义:
_MainTex ("RGB:颜色 A:透贴", 2d) = "gray"{}
_Opacity ("不透明度", range(0, 1)) = 0.5
_WarpMidVal ("扰动中间值", range(0, 1)) = 0.5
_WarpInt ("扰动强度", range(0, 5)) = 1
这里的中间值 扭曲度,因为我们用的是主图自带的通道中的信息,RGB中不同通道的像素可能偏亮,可能偏暗,会影响扭曲的强弱, 因为不像 法线的中间值是正常的0.5,偏移扭曲的正常的数值,所以这里声明了一个 用于矫正的 "扰动中间值"(_WarpMidVal)
②、追加GrabPass 获取扭曲背景_BGTex==背景纹理采样坐标(现成黑盒):
产生这张图:
获取背景纹理,他的含义为:渲染主体物前,将背景存成一张图,名字就叫 _BGTex.
实际上就是,扰动前,把背景图存起来,然后再用屏幕坐标UV把 背景图(_BGTex)贴回去。
GrabPass {
"_BGTex"
}
获取这张图:
uniform sampler2D _BGTex; // 拿到背景纹理
输出结构中 : (VertexOutput)
float4 grabPos : TEXCOORD1; // 背景纹理采样坐标(4维的)
顶点shader输入输出结构中 :
o.grabPos = ComputeGrabScreenPos(o.pos); // 背景纹理采样坐标
像素shader中采样:
half3 var_BGTex = tex2Dproj(_BGTex, i.grabPos).rgb;// 采样背景
③、像素shader下 采样和计算:
获取主贴图 通道信息作为源,来扭曲背景图(grabPos)采样坐标XY;
// 采样 基本纹理 RGB颜色 A透贴
half4 var_MainTex = tex2D(_MainTex, i.uv);
<这里用主图的B蓝通道,减去中间值,减去是什么意思呢,相当于有正有负,在乘强度(_WarpInt) 在乘 透明度(_Opacity),就得到透明的扰动效果>。
// 扰动背景纹理采样UV
i.grabPos.xy+=(var_MainTex.b - _WarpMidVal) * _WarpInt * _Opacity;
// 采样背景
half3 var_BGTex = tex2Dproj(_BGTex, i.grabPos).rgb;
用_Opacity控制 1 到 主图透明 的插值,并乘以 透明的背景信息,得到 带透贴的扰动主图。
// FinalRGB 不透明度
half3 finalRGB = lerp(1.0, var_MainTex.rgb, _Opacity) * var_BGTex;
half opacity = var_MainTex.a;
// 返回值
return half4(finalRGB * opacity, opacity);
3、代码实现:


4、核心代码

5、屏幕扰动 代码示例:
Shader "AP01/L17/ScreenWarp" {Properties {_MainTex ("RGB:颜色 A:透贴", 2d) = "gray"{}_Opacity ("不透明度", range(0, 1)) = 0.5_WarpMidVal ("扰动中间值", range(0, 1)) = 0.5_WarpInt ("扰动强度", range(0, 5)) = 1}SubShader {Tags {"Queue"="Transparent" // 调整渲染顺序"RenderType"="Transparent" // 对应改为Cutout"ForceNoShadowCasting"="True" // 关闭阴影投射"IgnoreProjector"="True" // 不响应投射器}// 获取背景纹理GrabPass {"_BGTex"}// Forward PassPass {Name "FORWARD"Tags {"LightMode"="ForwardBase"}Blend One OneMinusSrcAlpha // 混合方式CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"#pragma multi_compile_fwdbase_fullshadows#pragma target 3.0// 输入参数uniform sampler2D _MainTex;uniform half _Opacity;uniform half _WarpMidVal;uniform half _WarpInt;uniform sampler2D _BGTex; // 拿到背景纹理// 输入结构struct VertexInput {float4 vertex : POSITION; // 顶点位置 总是必要float2 uv : TEXCOORD0; // UV信息 采样贴图用};// 输出结构struct VertexOutput {float4 pos : SV_POSITION; // 顶点位置 总是必要float2 uv : TEXCOORD0; // UV信息 采样贴图用float4 grabPos : TEXCOORD1; // 背景纹理采样坐标};// 输入结构>>>顶点Shader>>>输出结构VertexOutput vert (VertexInput v) {VertexOutput o = (VertexOutput)0;o.pos = UnityObjectToClipPos( v.vertex); // 顶点位置 OS>CSo.uv = v.uv; // UV信息o.grabPos = ComputeGrabScreenPos(o.pos); // 背景纹理采样坐标return o;}// 输出结构>>>像素half4 frag(VertexOutput i) : COLOR {// 采样 基本纹理 RGB颜色 A透贴half4 var_MainTex = tex2D(_MainTex, i.uv);// 扰动背景纹理采样UVi.grabPos.xy += (var_MainTex.b - _WarpMidVal) * _WarpInt * _Opacity;// 采样背景half3 var_BGTex = tex2Dproj(_BGTex, i.grabPos).rgb;// FinalRGB 不透明度half3 finalRGB = lerp(1.0, var_MainTex.rgb, _Opacity) * var_BGTex;half opacity = var_MainTex.a;// 返回值return half4(finalRGB * opacity, opacity);}ENDCG}}
} 三、任务委托:

1、作业:

相关文章:
庄懂的TA笔记(十七)<特效:屏幕UV + 屏幕扰动>
庄懂的TA笔记(十七)<特效:屏幕UV 屏幕扰动> 大纲: 目录 庄懂的TA笔记(十七)<特效:屏幕UV 屏幕扰动> 大纲: 正文: 一…...
手写简易RPC框架
目录 简介 服务提供者 服务注册:注册中心 HttpServerHandler处理远程调用请求 consumer服务消费端 简介 RPC(Remote Procedure Call)——远程过程调用,它是一种通过网络从远程计算机程序上请求服务, 而不需要了解…...
基于孪生网络的目标跟踪
一、目标跟踪 目标跟踪是计算机视觉领域研究的一个热点问题,其利用视频或图像序列的上下文信息,对目标的外观和运动信息进行建模,从而对目标运动状态进行预测并标定目标的位置。具体而言,视觉目标(单目标)…...
苏州狮山广场能耗管理系统
摘要:随着社会生活水平的提高,经济的繁荣发展,人们对能源的需求逐渐增长,由此带来的能源危机日益严重。商场如何实时的了解、分析和控制商场的能源消耗已成为需要解决的迫在眉睫的难题。传统的能源消耗智能以月/季度/年为周期进行…...
Jupyter Notebook 10个提升体验的高级技巧
Jupyter 笔记本是数据科学家和分析师用于交互式计算、数据可视化和协作的工具。Jupyter 笔记本的基本功能大家都已经很熟悉了,但还有一些鲜为人知的技巧可以大大提高生产力和效率。在这篇文章中,我将介绍10个可以提升体验的高级技巧。 改变注释的颜色 颜…...
CF 751 --B. Divine Array
Black is gifted with a Divine array a consisting of n (1≤n≤2000) integers. Each position in a has an initial value. After shouting a curse over the array, it becomes angry and starts an unstoppable transformation. The transformation consists of infinite…...
Springcloud1--->Eureka注册中心
目录 Eureka原理Eureka入门案例编写EurekaServer将user-service注册到Eureka消费者从Eureka获取服务 Eureka详解基础架构高可用的Eureka Server失效剔除和自我保护 Eureka原理 Eureka:就是服务注册中心(可以是一个集群),对外暴露自…...
面试阿里、字节全都一面挂,被面试官说我的水平还不如应届生
测试员可以先在大厂镀金,以后去中小厂毫无压力,基本不会被卡,事实果真如此吗?但是在我身上却是给了我很大一巴掌... 所谓大厂镀金只是不卡简历而已,如果面试答得稀烂,人家根本不会要你。况且要不是大厂出来…...
JAVA开发(记一次删除完全相同pgSQL数据库记录只保留一条)
进行数据管理时,无效数据可能会对生产力和决策质量造成严重的影响。如何发现和处理无效数据变得愈发重要。一起来唠唠你会如何处理无效数据吧~ 方向一:介绍无效数据的概念 最近遇到了pg数据库表中的大量数据重复了,需要删除其中的一条。一条…...
音视频八股文(7)-- 音频aac adts三层结构
AAC介绍 AAC(Advanced Audio Coding)是一种现代的音频编码技术,用于数字音频的传输和存储领域。AAC是MPEG-2和MPEG-4标准中的一部分,可提供更高质量的音频数据,并且相比于MP3等旧有音频格式,AAC需要更少的…...
Docker代码环境打包进阶 - DockerHub分享镜像
1. Docker Hub介绍 Docker Hub是一个广泛使用的容器镜像注册中心,为开发人员提供了方便的平台来存储、共享和分发Docker容器镜像。它支持版本控制、访问控制和自动化构建,并提供了丰富的公共镜像库,方便开发人员快速获取和使用各种开源应用和…...
SQL进阶-having子句的力量
SQL进阶-having子句的力量 having子句是理解SQL面向集合这一本质的关键。 在以前的SQL标准里面,having子句必须和group by子句一起使用,但是按照现在的SQL标准,having子句是可以单独使用的 可以与case 表达式或者自连接等结合使用。表不是文件…...
Electron 如何创建模态窗口?
目录 前言一、模态窗口1.Web页面模态框2.Electron中的模态窗口3.区分父子窗口与模态窗口 二、实际案例使用总结 前言 模态框是一种常用的交互元素,无论是在 Web 网站、桌面应用还是移动 APP 中,都有其应用场景。模态框指的是一种弹出窗口,它…...
诺贝尔化学奖:酶分子“定向进化”
2018年,诺贝尔化学奖迎来了历史上第五位女性得主——加州理工学院的Frances H. Arnold教授,以表彰她在“酶的定向进化”这一领域的贡献。 1、“酶的定向进化”到底是什么? 这里有三个点,“酶”、“进化”还有“定向”:…...
Centos8下源码编译安装运行Primihub
参考文献 PrimiHub 本地编译启动How to install Bazel on CentOS 8 Linux or Redhat 8/7 编译启动步骤 由于历史原因,服务器是Centos8操作系统,所以源码编译异常的麻烦。特此记录如下。 采用源码编译方式可以在一步步的运行过程中对整个流程进行深刻…...
嘉兴桐乡考证培训-23年教资认定注意事项你知道吗?
又到了新的一年了,去年错过认定的同学们可以竖起耳朵啦~ 每年认定机会有两次,大部分省份一般上半年下半年各一次。 问:在校生可以认定么? 答:可以,但有年级限制:本科生大四最后一学期…...
oracle客户端的安装教程
文章目录 一、安装前的准备工作 1.1、百度网盘安装包的连接 1.2、百度网盘oracle11g软件包 二、oracle数据库客户端的安装与数据的准备 安装步骤 前言 本文主要讲解oracle客户端的安装与简单使用过程 一、安装前的准备工作 1.1、百度网盘安装包的连接 客户端的软件包 …...
python 文件操作 , 异常处理 , 模块和包
文件操作 1.写数据 # open(name, mode) # name:是要打开的目标文件名的字符串(可以包含文件所在的具体路径)。 # mode:设置打开文件的模式(访问模式):只读、写入、追加等。 #1.打开文件---通道建立--申请资源 # w 模式会清空之前的内…...
AIGC技术研究与应用 ---- 下一代人工智能:新范式!新生产力!(1-简介)
文章大纲 AI GC简介决策式/分析式AI(Discriminant/Analytical AI)和生成式AI (Generative AI)参考文献与学习路径模型进化券商研报陆奇演讲AI GC 《我,机器人》中所演绎的一样,主角曾与机器人展开了激烈的辩论,面对“机器人能写出交响乐吗?”“机器人能把画布变成美丽…...
Flask restful分页接口实现
1.先定义一个工作信息表: 指定一些相关的字段:工作名称、年限、级别等 class Work(db.Model):__tablename__ = workid = db.Column(db.Integer, primary_key=True)workName = db.Column(db.String(5),nullable=False)year = db.Column(db.String(20), nullable=False)level = …...
接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
NPOI Excel用OLE对象的形式插入文件附件以及插入图片
static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...
[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.
ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #:…...
安卓基础(Java 和 Gradle 版本)
1. 设置项目的 JDK 版本 方法1:通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分,设置 Gradle JDK 方法2:通过 Settings File → Settings... (或 CtrlAltS)…...
Python 高级应用10:在python 大型项目中 FastAPI 和 Django 的相互配合
无论是python,或者java 的大型项目中,都会涉及到 自身平台微服务之间的相互调用,以及和第三发平台的 接口对接,那在python 中是怎么实现的呢? 在 Python Web 开发中,FastAPI 和 Django 是两个重要但定位不…...
