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

2023-10-08 04:40

本文主要是介绍庄懂的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轴对应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;       // 顶点位置 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 + 屏幕扰动>的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/162756

相关文章

基于Python开发Windows屏幕控制工具

《基于Python开发Windows屏幕控制工具》在数字化办公时代,屏幕管理已成为提升工作效率和保护眼睛健康的重要环节,本文将分享一个基于Python和PySide6开发的Windows屏幕控制工具,... 目录概述功能亮点界面展示实现步骤详解1. 环境准备2. 亮度控制模块3. 息屏功能实现4. 息屏时间

Python UV安装、升级、卸载详细步骤记录

《PythonUV安装、升级、卸载详细步骤记录》:本文主要介绍PythonUV安装、升级、卸载的详细步骤,uv是Astral推出的下一代Python包与项目管理器,主打单一可执行文件、极致性能... 目录安装检查升级设置自动补全卸载UV 命令总结 官方文档详见:https://docs.astral.sh/

Python中使用uv创建环境及原理举例详解

《Python中使用uv创建环境及原理举例详解》uv是Astral团队开发的高性能Python工具,整合包管理、虚拟环境、Python版本控制等功能,:本文主要介绍Python中使用uv创建环境及... 目录一、uv工具简介核心特点:二、安装uv1. 通过pip安装2. 通过脚本安装验证安装:配置镜像源(可

使用Python开发一个现代化屏幕取色器

《使用Python开发一个现代化屏幕取色器》在UI设计、网页开发等场景中,颜色拾取是高频需求,:本文主要介绍如何使用Python开发一个现代化屏幕取色器,有需要的小伙伴可以参考一下... 目录一、项目概述二、核心功能解析2.1 实时颜色追踪2.2 智能颜色显示三、效果展示四、实现步骤详解4.1 环境配置4.

使用Python实现获取屏幕像素颜色值

《使用Python实现获取屏幕像素颜色值》这篇文章主要为大家详细介绍了如何使用Python实现获取屏幕像素颜色值,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 一、一个小工具,按住F10键,颜色值会跟着显示。完整代码import tkinter as tkimport pyau

macOS Sequoia 15.5 发布: 改进邮件和屏幕使用时间功能

《macOSSequoia15.5发布:改进邮件和屏幕使用时间功能》经过常规Beta测试后,新的macOSSequoia15.5现已公开发布,但重要的新功能将被保留到WWDC和... MACOS Sequoia 15.5 正式发布!本次更新为 Mac 用户带来了一系列功能强化、错误修复和安全性提升,进一步增

Android实现两台手机屏幕共享和远程控制功能

《Android实现两台手机屏幕共享和远程控制功能》在远程协助、在线教学、技术支持等多种场景下,实时获得另一部移动设备的屏幕画面,并对其进行操作,具有极高的应用价值,本项目旨在实现两台Android手... 目录一、项目概述二、相关知识2.1 MediaProjection API2.2 Socket 网络

python uv包管理小结

《pythonuv包管理小结》uv是一个高性能的Python包管理工具,它不仅能够高效地处理包管理和依赖解析,还提供了对Python版本管理的支持,本文主要介绍了pythonuv包管理小结,具有一... 目录安装 uv使用 uv 管理 python 版本安装指定版本的 Python查看已安装的 Python

利用Python快速搭建Markdown笔记发布系统

《利用Python快速搭建Markdown笔记发布系统》这篇文章主要为大家详细介绍了使用Python生态的成熟工具,在30分钟内搭建一个支持Markdown渲染、分类标签、全文搜索的私有化知识发布系统... 目录引言:为什么要自建知识博客一、技术选型:极简主义开发栈二、系统架构设计三、核心代码实现(分步解析

使用Python实现一键隐藏屏幕并锁定输入

《使用Python实现一键隐藏屏幕并锁定输入》本文主要介绍了使用Python编写一个一键隐藏屏幕并锁定输入的黑科技程序,能够在指定热键触发后立即遮挡屏幕,并禁止一切键盘鼠标输入,这样就再也不用担心自己... 目录1. 概述2. 功能亮点3.代码实现4.使用方法5. 展示效果6. 代码优化与拓展7. 总结1.