庄懂的TA笔记(十七)<特效:屏幕UV + 屏幕扰动>

news2025/1/12 13:11:45

庄懂的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。

重点:屏幕UV 位置,畸变修正,纹理大小锁定。

取屏幕空间UV位置,取xyz三个轴,

如何理解Vive空间呢?Vive空间相当于以摄像机平面为基准的空间,XY轴对应UVZ轴对应深度

但是,正常我们将 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滚动:

这里就控制Tilingoffset 流动起来,

ScreenTex_ST. X Y 对应 TilingX Y ;

ScreenTex_ST. Z W 对应 offsetZ 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;       // 顶点位置 OS
                float2 uv : TEXCOORD0;          // UV信息
            };
            // 输出结构
            struct VertexOutput {
                float4 pos : SV_POSITION;       // 顶点位置 CS
                float2 uv : TEXCOORD0;          // UV信息
                float2 screenUV : TEXCOORD1;    // 屏幕UV
            };
            // 输入结构>>>顶点Shader>>>输出结构
            VertexOutput vert (VertexInput v) {
                VertexOutput o = (VertexOutput)0;
                    o.pos = UnityObjectToClipPos(v.vertex);     // 顶点位置 OS>CS
                    o.uv = v.uv;                                // UV信息
                    float3 posVS = UnityObjectToViewPos(v.vertex).xyz;                  // 顶点位置 OS>VS
                    float originDist = UnityObjectToViewPos(float3(0.0, 0.0, 0.0)).z;   // 原点位置 OS>VS
                    o.screenUV = posVS.xy / posVS.z;            // VS空间畸变校正
                    o.screenUV *= originDist;                   // 纹理大小按距离锁定
                    o.screenUV = o.screenUV * _ScreenTex_ST.xy - frac(_Time.x * _ScreenTex_ST.zw);  // 启用屏幕纹理ST
                return 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 Pass
        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 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>CS
                    o.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);
                // 扰动背景纹理采样UV
                i.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、作业:

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

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

相关文章

UNIX环境高级编程——线程控制

12.1 引言 本章讲解控制线程行为方面的详细内容&#xff0c;介绍线程属性和同步原语属性。 12.2 线程限制 12.3 线程属性 线程属性对象用pthread_attr_t结构表示&#xff0c;可以用这个结构修改线程默认属性&#xff0c;并把这些属性与创建的线程联系起来。 #include <p…

腾讯C++二面,全程2小时追问基础!

今天给大家分享星球一位同学腾讯面经&#xff0c;主要摘取了部分一二面经&#xff0c;然后部分问题我做了补充说明~ 星球原文&#xff1a;https://t.zsxq.com/0eO4O13HV&#xff0c;已获授权 一面 1、C11有哪些新特性&#xff0c;有哪些新关键字 2、C中结构体占多少字节&…

51单片机——I2C-EEPROM实验,小白讲解,相互学习

I2C介绍 I2C&#xff08;Inter&#xff0d;Integrated Circuit&#xff09;总线是由 PHILIPS 公司开发的两线式 串行总线&#xff0c;用于连接微控制器及其外围设备。是微电子通信控制领域广泛采用的 一种总线标准。它是同步通信的一种特殊形式&#xff0c;具有接口线少&#x…

【逆向工程核心原理:SEH】

SEH SEH是Windows操作系统提供的异常处理机制&#xff0c;在程序源代码中使用__ try、 __except、__finally关键字来具体实现。主要用在反调试中。 注&#xff1a; SEH与C中的try. catch 异常处理具有不同结构。从时间上看&#xff0c;与C的try、catch异常处理相比&#xff0…

uni-app--》uView组件库:提升您的uni-app开发体验

&#x1f3cd;️作者简介&#xff1a;大家好&#xff0c;我是亦世凡华、渴望知识储备自己的一名在校大学生 &#x1f6f5;个人主页&#xff1a;亦世凡华、 &#x1f6fa;系列专栏&#xff1a;uni-app &#x1f6b2;座右铭&#xff1a;人生亦可燃烧&#xff0c;亦可腐败&#xf…

MMDet3d样本均衡

MMDet3d样本均衡 文章目录 MMDet3d样本均衡CBGSDataset训练时数据是200帧&#xff0c;后面处理时&#xff0c;dataloader中数据变成了460帧&#xff0c;怎么均衡的&#xff1f;思考抽帧数计算某个类别帧数为0 Reference欢迎关注公众号【三戒纪元】 CBGSDataset **CBGS &#x…

UE虚幻引擎,Unity3D,Blender区别和联系

1. 官网手册 UnityUEBlenderUnity 用户手册 (2019.4 LTS) - Unity 手册虚幻引擎5.2文档 | 虚幻引擎5.2文档 (unrealengine.com)Blender 3.5 Reference Manual — Blender Manual 2. Unity, UnrealEngine, Blender的区别 Blender 是一款免费的开源软件&#xff0c;是一个开源…

Godot引擎 4.0 文档 - 循序渐进教程 - 脚本语言

本文为Google Translate英译中结果&#xff0c;DrGraph在此基础上加了一些校正。英文原版页面&#xff1a; Scripting languages — Godot Engine (stable) documentation in English 脚本语言 本课将概述 Godot 中可用的脚本语言。您将了解每个选项的优缺点。在下一部分中&…

CentOS7搭建伪分布式Hadoop(全过程2023)

##具体操作目录## 1.配置静态ip2.关闭防火墙3.修改主机名为 *master* &#xff0c;并重启虚拟机vi /etc/hostname 4.修改主机名与ip映射5.设置SSH免密登录6.安装配置java环境----------------------正式Hadoop配置1.移动安装包到合适位置2.解压安装包并重命名3.配置环境变量4.修…

know it and do it

overview&#xff1a; 在一盘盘有立即反馈的系统中&#xff0c;可以更直观的看到知道一个道理和能自然的用出来之间的鸿沟有多大。 这个就是日积月累的训练的意义了。 一夜回到解放前 继续金铲铲的游玩回味&#xff0c;之前一段时间忙于工作就放下了&#xff0c;后来新的版本…

20230521 AI 一周大事件汇总

&#x1f680; ChatGPT 上线联网和插件功能 OpenAI宣布将在这周推出联网和插件功能&#xff0c;位于Alpha和Beta通道的ChatGPT Plus用户都可使用70多个上线的插件。 更新意味着ChatGPT将利用最新的信息和资讯为使用者提供服务。 上线的ChatGPT插件种类涵盖了行程安排助理、代…

拿捏大厂面试官的高质量自动化测试工程师简历--看完必有所获

一、前言&#xff1a;简历&#xff08;职场敲门砖&#xff09; 作为软件测试的垂直领域深耕者&#xff0c;面试或者被面试都是常有的事&#xff0c;可是不管是啥&#xff0c;总和简历有着理不清的关系&#xff0c;面试官要通过简历了解面试者的基本信息、过往经历等&#xff0c…

阿里p10手敲python +pytest +yaml + Allure 实现接口自动化框架

以前弄过好多接口自动化框架的东西&#xff0c;比如httprunner2.0版本实现的接口自动化框架&#xff0c;还有httprunner3.X实现的接口自动化框架&#xff0c;这些都是开源的&#xff0c;实现起来比较简单。 以及使用pythonunittestddtyaml等工具实现的接口自动化框架等。 今天…

【腾讯云 Finops Crane 集训营】安装使用及EHPA弹性演示

随着时间的推移&#xff0c;降本增效成为了企业界和组织中的一个新口号。在2023年&#xff0c;这个口号进一步获得了广泛的认可和重要性&#xff0c;成为了许多组织在业务运营中的关键目标。在2023年&#xff0c;许多组织开始将降本增效作为战略性目标&#xff0c;并将其融入到…

3.fabric二进制工具包介绍

(1)Fabric二进制工具包: Fabric二进制工具包:Fabric二进制工具包(Fabric Binary Distribution)是Hyperledger Fabric的核心组件,它包含了一系列可执行的二进制文件,用于搭建、管理和操作Fabric网络。该工具包提供了一套命令行工具,可以执行各种与Fabric网络相关的任务…

模板(初阶)

目录 一、泛型编程二、函数模板2.1 函数模板的概念2.2 函数模板的格式2.3 函数模板的原理2.4 函数模板的实例化2.5 模板参数的匹配原则 三、类模板3.1 类模板的定义格式3.2 类模板的实例化 一、泛型编程 如何实现一个通用的Swap函数 void Swap(int& x, int& y) {int …

chatgpt赋能Python-pythonapp自动化

Python App自动化&#xff1a;优化SEO的终极解决方案 随着互联网的发展&#xff0c;SEO&#xff08;搜索引擎优化&#xff09;变得日益重要。对于任何网站或应用程序开发人员来说&#xff0c;SEO应该是一个非常重要的考虑因素。为了帮助开发人员和企业提高其在线可见性&#x…

Squid代理服务器应用

在web架构中&#xff0c;用户一般进入负载均衡层&#xff0c;通过调度来访问web应用层&#xff0c;但是如果访问量太大&#xff0c;并发量较高&#xff0c;web应用层会吃不消&#xff0c;我们把静态资源、经常要访问的资源放入缓存&#xff0c;用户直接访问缓存层&#xff0c;加…

解析使用FPGA逻辑实现FIR滤波器的几种架构

有限脉冲响应(finite impulse response&#xff0c;FIR)数字滤波器 一、FIR数字滤波器理论介绍 FIR滤波器的实质就是输入序列与系统脉冲响应的卷积&#xff0c;即&#xff1a; 其中&#xff0c;N为滤波器的阶数&#xff0c;也即抽头数&#xff1b;x(n)为第n个输入序列&#xff…

人工智能轨道交通行业周刊-第45期(2023.5.15-5.21)

本期关键词&#xff1a;动车洗澡、热备列车、火车司机室、无缝线路、图像分割、自动标注 1 整理涉及公众号名单 1.1 行业类 RT轨道交通人民铁道世界轨道交通资讯网铁路信号技术交流北京铁路轨道交通网上榜铁路视点ITS World轨道交通联盟VSTR铁路与城市轨道交通RailMetro轨道…