Unity中Shader的UV扭曲效果的实现

news2024/11/18 23:27:17

文章目录

  • 前言
  • 一、实现的思路
    • 1、在属性面板暴露一个 扭曲贴图的属性
    • 2、在片元结构体中,新增一个float2类型的变量,用于独立存储将用于扭曲的纹理的信息
    • 3、在顶点着色器中,根据需要使用TRANSFORM_TEX对Tilling 和 Offset 插值;以及根据需要使用_Time相乘实现流动效果
    • 4、在片元着色器中,使用fixed4变量来存储,对扭曲纹理的采样结果
    • 5、使用lerp(A,B,alpha)进行线性插值
    • 6、最后用 线性插值后的结果对 主纹理进行采样
  • 二、测试代码


前言

Unity中Shader的UV扭曲效果的实现


一、实现的思路

1、在属性面板暴露一个 扭曲贴图的属性

2、在片元结构体中,新增一个float2类型的变量,用于独立存储将用于扭曲的纹理的信息

3、在顶点着色器中,根据需要使用TRANSFORM_TEX对Tilling 和 Offset 插值;以及根据需要使用_Time相乘实现流动效果

4、在片元着色器中,使用fixed4变量来存储,对扭曲纹理的采样结果

fixed4 distortTex = tex2D(_DistortTex,i.uv2);

5、使用lerp(A,B,alpha)进行线性插值

float2 distort = lerp(i.uv.xy,distortTex,_Distort);

6、最后用 线性插值后的结果对 主纹理进行采样

fixed4 col = tex2D(_MainTex, distort);


二、测试代码


Shader "MyShader/P0_9_7"
{
    Properties
    
    {
        [Header(RenderingMode)]
        //暴露两个属性,分别对应 源混合类型 和 目标混合类型
        //源混合类型
        [Enum(UnityEngine.Rendering.BlendMode)]_SrcBlend("Src Blend",int) = 0
        //目标混合类型
        [Enum(UnityEngine.Rendering.BlendMode)]_DstBlend("DstBlend",int) = 0
        //暴露属性来控制 剔除哪里
        [Enum(UnityEngine.Rendering.CullMode)]_Cull("Cull",int) = 1

        [Header(Base)]
        //用来控制颜色混合
        _Color("Color",COLOR) = (1,1,1,1)
        //用来控制亮度
        _Intensity("Intensity",Range(-4,4)) = 1
        //主纹理
        _MainTex ("Texture", 2D) = "white" {}
        //控制 X 轴的移动速度
        _MainUVSpeedX("MainUVSpeed X",float) = 0
        //控制 Y 轴的移动速度
        _MainUVSpeedY("MainUVSpeed Y",float) = 0
        
        [Header(Mask)]
        //流动贴图
        _MaskTex("MaskTex",2D) = "white"{}
        //流动贴图 X 轴上的移动速度
        _MaskUVSpeedX("MaskUVSpeed X",float) = 0
        //流动贴图 Y 轴上的移动速度
        _MaskUVSpeedY("MaskUVSpeed Y",float) = 0

        [Header(Distort)]
        _DistortTex("DistortTex",2D) = "white"{}
        _Distort("Distort",Range(0,1)) = 0
        _DistortUVSpeedX("DistortUVSpeed X",float) = 0
        _DistortUVSpeedY("DistortUVSpeed Y",float) = 0

    }
    SubShader
    {
        Tags{"Queue" = "Transparent"}

        //混合
        Blend [_SrcBlend][_DstBlend]
        
        Cull [_Cull]

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            
            sampler2D _MainTex;float4 _MainTex_ST;
            
            fixed4 _Color;
            half _Intensity;
            float _MainUVSpeedX,_MainUVSpeedY;

            sampler2D _MaskTex;float4 _MaskTex_ST;
            float _MaskUVSpeedX,_MaskUVSpeedY;

            sampler2D _DistortTex;float4 _DistortTex_ST;
            float _Distort;
            float _DistortUVSpeedX,_DistortUVSpeedY;
            struct appdata
            {
                //为了节省空间,使用 把两个 float2 合并为一个 float4
                float4 vertex : POSITION;
                float4 uv : TEXCOORD0;
            };

            struct v2f
            {
                float4 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
                //这个存储纹理扭曲的信息
                float2 uv2 : TEXCOORD1;
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                //这个保存主纹理的信息
                o.uv.xy = TRANSFORM_TEX(v.uv, _MainTex) + float2(_MainUVSpeedX,_MainUVSpeedY) * _Time.y;
                //这个保存遮罩贴图的信息 (为了也实现流动,和 上面使用一样的方法)
                o.uv.zw = TRANSFORM_TEX(v.uv,_MaskTex) + float2(_MaskUVSpeedX,_MainUVSpeedY) * _Time.y;
                //这个保存纹理扭曲的贴图信息
                o.uv2 = TRANSFORM_TEX(v.uv,_DistortTex) + float2(_DistortUVSpeedX,_DistortUVSpeedY) * _Time.y;

                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                //先对扭曲纹理进行采样
                fixed4 distortTex = tex2D(_DistortTex,i.uv2);
                //使用lerp (A,B,alpha)函数进行线性插值
                float2 distort = lerp(i.uv.xy,distortTex,_Distort);
                //再用采样后的结果,给主要纹理采样,实现扭曲效果
                fixed4 col = tex2D(_MainTex, distort);
                //一般使用 * 来颜色混合
                col *= _Color * _Intensity;

                //对遮罩贴图进行纹理采样
                fixed4 maskTex = tex2D(_MaskTex,i.uv.zw);
              
                //最后 返回 遮罩 和 原结果相乘的结果
                return col * maskTex;
            }
            ENDCG
        }
    }
}

使用的纹理:
在这里插入图片描述

效果:

请添加图片描述

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

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

相关文章

使用QT操作Excel 表格的常用方法

VBA 简介 Microsoft Office软件通常使用VBA来扩展Windows的应用程序功能,Visual Basic for Applications(VBA)是一种Visual Basic的一种宏语言。 在VBA的参考手册中就可以看到具体函数、属性的用法,Qt操作Excel主要通过 QAxObj…

Redis 缓存预热+缓存雪崩+缓存击穿+缓存穿透

面试题: 缓存预热、雪萌、穿透、击穿分别是什么?你遇到过那几个情况?缓存预热你是怎么做的?如何造免或者减少缓存雪崩?穿透和击穿有什么区别?他两是一个意思还是载然不同?穿适和击穿你有什么解…

【每日一题】1041. 困于环中的机器人

1041. 困于环中的机器人 - 力扣(LeetCode) 在无限的平面上,机器人最初位于 (0, 0) 处,面朝北方。注意: 北方向 是y轴的正方向。南方向 是y轴的负方向。东方向 是x轴的正方向。西方向 是x轴的负方向。 机器人可以接受下列三条指令之…

入门力扣自学笔记277 C++ (题目编号:42)(动态规划)

42. 接雨水 题目: 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 示例 1: 输入:height [0,1,0,2,1,0,1,3,2,1,2,1] 输出:6 解释:上面是由数组…

时序预测 | MATLAB实现CNN-BiLSTM卷积双向长短期记忆神经网络时间序列预测(风电功率预测)

时序预测 | MATLAB实现CNN-BiLSTM卷积双向长短期记忆神经网络时间序列预测(风电功率预测) 目录 时序预测 | MATLAB实现CNN-BiLSTM卷积双向长短期记忆神经网络时间序列预测(风电功率预测)预测效果基本介绍程序设计参考资料 预测效果…

小白学go基础03-了解Go项目的项目结构

我们先来看看第一个Go项目——Go语言自身——的项目结构是什么样的。Go项目的项目结构自1.0版本发布以来一直十分稳定,直到现在Go项目的顶层结构基本没有大的改变。 截至Go项目commit 1e3ffb0c(2019.5.14),Go1.0 项目结构如下&am…

js+vue,前端关于页面滚动让头部菜单淡入淡出实现原理

今天遇到个需求:我这里借用小米商城的详情页做个比喻吧。 刚开始其商品详情页是这样的: 当滚动到一定高度时,是这样的: 可以看到当滚动到轮播图底下的时候,详情页的菜单完全显现出来。 以下上代码: HTML…

uniApp webview 中调用底座蓝牙打印功能异常

背景: 使用uniApp, 安卓底座 webView 方式开发; 调用方式采用H5 向 底座发送消息, 底座判断消息类型, 然后连接打印机进行打印; 内容通过指令集方式传递给打印机; 过程当中发现部分标签可以正常打印, 但又有部分不行,打印机没反应, 也没有报错; 原因分析: 对比标签内容…

医院安全(不良)事件上报系统源码 不良事件报告平台源码 前后端分离,支持二开

医院安全(不良)事件上报系统源码 系统定义: 规范医院安全(不良)事件的主动报告,增强风险防范意识,及时发现医院不良事件和安全隐患,将获取的医院安全信息进行分析反馈,…

“金融级”数字底座:从时代的“源启”,到“源启”的时代

今年初《数字中国建设整体布局规划》正式发布,这代表着数字中国建设迈向了实质的落地阶段,其背后的驱动就是遍及各行各业的数字化转型。 千姿百态、复杂多样的应用场景,可以看作是遍布数字中国的“点”;千行百业、各种类型的行业…

阿里云2核4G服务器5M带宽5年费用价格明细表

阿里云2核4G服务器5M带宽可以选择轻量应用服务器或云服务器ECS,轻量2核4G4M带宽服务器297元一年,2核4G云服务器ECS可以选择计算型c7、c6或通用算力型u1实例等,买5年可以享受3折优惠,阿腾云分享阿里云服务器2核4G5M带宽五年费用表&…

【系统编程】线程池以及API接口简介

(꒪ꇴ꒪ ),Hello我是祐言QAQ我的博客主页:C/C语言,数据结构,Linux基础,ARM开发板,网络编程等领域UP🌍快上🚘,一起学习,让我们成为一个强大的攻城狮&#xff0…

非比较排序——计数排序

本章gitee代码:计数排序 文章目录 🍇0. 前言🍈1. 思路🍉2. 代码实现🍊3. 优势与缺陷🍋4. 其他的非比较排序🫴桶排序🫴基数排序 🍇0. 前言 传统的排序方法通常需要逐个比…

嵌入式Linux开发实操(十五):nand flash接口开发(2)

通用NAND驱动程序支持几乎所有基于NAND的芯片,并将它们连接到Linux内核的内存技术设备(MTD)子系统。这个接口走的是nand的并口,可以在shell的/dev中看到设备,比如/mtd0、/mtd0ro…,mtdblock0、mtdblock1… sysfs在设备层次结构中提供了几个视角。设备必须挂在某条总线bus…

Linux相关指令(下)

cat指令 查看目标文件的内容 常用选项&#xff1a; -b 对非空输出行编号 -n 对输出的所有行编号 -s 不输出多行空行 一个重要思想&#xff1a;linux下一切皆文件&#xff0c;如显示器文件&#xff0c;键盘文件 cat默认从键盘中读取数据再打印 退出可以ctrlc 输入重定向<…

CSP 202305-2 矩阵运算

样例输入 3 2 1 2 3 4 5 6 10 10 -20 -20 30 30 6 5 4 3 2 1 4 0 -5 样例输出 480 240 0 0 -2200 -1100 答题 注意数值范围用int已经不行了&#xff0c;必须要用long long 而且矩阵运算涉及到三层循环&#xff0c;可以利用cache机制减少取值时间&#xff0c;先将右矩阵转置…

Unity2D实现左右移动的敌人角色

文章目录 环境与角色创建敌人角色 敌人脚本检测前方是否有地面获取检测点检测地面 完整代码运行结果其他文章 环境与角色 创建敌人角色 简单起见&#xff0c;突出脚本的内容&#xff0c;我们就只创建一个圆形用来当做当前的敌人角色。 为分清左右&#xff0c;我们再为敌人角色…

时序预测 | MATLAB实现TCN-BiLSTM时间卷积双向长短期记忆神经网络时间序列预测

时序预测 | MATLAB实现TCN-BiLSTM时间卷积双向长短期记忆神经网络时间序列预测 目录 时序预测 | MATLAB实现TCN-BiLSTM时间卷积双向长短期记忆神经网络时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 1.MATLAB实现TCN-BiLSTM时间卷积双向长短期记忆神…

APACHE NIFI 删除组件报错

报错信息&#xff1a; Node 192.168.93.206:8443 is unable to fulfill this request due to: Controller Service 0e733621-f4ad-139e-8a25-8ad317eb6453 cannot be deleted because it is not disabled 步骤1&#xff1a;进入报错的流程里面&#xff0c;我的是到报错的Proce…

Arduino驱动LX1972传感器(光照传感器篇)

LX1972环境光(可见光)传感器,对可见光照度的反应特性与人眼的特性类似,可以模拟人对环境光线的强度的判断,从而方便做出与人友好互动的应用,可应用于照明控制、屏幕背光控制等。 1、传感器特性 传感器技术指标如下: 工作温度: -40~80C照度范围: 1 – 800Lux输出信号:…