UnityShader顶点动画实现Mage-Fiers漂移效果

2023-11-10 05:20

本文主要是介绍UnityShader顶点动画实现Mage-Fiers漂移效果,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

我们需要实现一个模型上所有顶点都随机漂移的效果。开始的时候用的Mage-fiers实现的,需要加载对应的脚本库。感觉代码累赘,所以这里用shader实现了一个相应的效果。静态图如下:  

   

     这张效果图有两部分组成,由带有色彩的底图(百度所得)和上面的不规则模型组成,我们要做的就是通过shader使模型顶点漂移起来,让我们开始吧。


//声明一个shader,这个shader为着顶点光照,因为我们只需要看到模型的透明轮廓,不需要进行细腻的着片元计

//同时这个效果的轮廓受光照的方向影响。

Shader "Demon/SwingAni" {

    //属性定义就不解释了
    Properties {
        _Diffuse("漫反射颜色", Color) = (1.0, 1.0, 1.0, 1.0)
        _Speed("动画速度(xyz)和Z方向振幅(w)", Vector) = (1.0, 1.0, 1.0, 1.0)
    }
    SubShader {

        //这是一个透明的shader,所以Queue和RenderType都是Transparent,不会受到投影器影响所以Ignore掉。

//这个shader有顶点动画,所以关闭Unity的Batching功能,不关闭动画效果可能受到影响。
    Tags { "Queue" = "Transparent" "RenderType" = "Transparent" "IgnoreProjector" = "True" "DisableBatching" = "True"}
        Pass {
            Tags{"LightMode" = "ForwardBase" }

            //根据透明度_Diffuse.a进行混合,下面等于(源颜色*a)+(目标颜色即缓冲区*(1-a))
            Blend SrcAlpha OneMinusSrcAlpha 

            //只渲染正面,在OpenGL中为顶点按逆时针光栅化图元的面,DX相反。

            Cull Back

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata {

                //这里系统用POSITION语义填充模型空间的顶点信息
                float4 vertex : POSITION;

//这里系统用NORMAL语义填充模型空间的法线信息
                float3 normal : NORMAL;
            };

            struct v2f {

//这里存储了顶点处理之后裁剪空间的坐标信息,是shader中必须计算的。指的是System Value Position
                float4 pos : SV_POSITION;

                //这里存储了着顶点光照的插值颜色
                float4 color : TEXCOORD0;
            };
            //属性对应的变量声明,只有声明之后属性才能用
            fixed4 _Diffuse;
            float4 _Speed;


    //着顶点计算,这里的漂移算法是根据时间的正玄波移动,但是只有时间参数会发现所有的顶点都会有相同的

    //偏移,所以这里根据模型空间的原点计算了一个距离dis作为sin的偏移值,这样看起来就是随机漂移的效果了

            v2f vert(appdata v) {
                v2f o;
                float3 offset = float3 (0,0,0);//模型空间原点
                float dis = distance(v.vertex.xyz, offset);//计算幅度偏移量
                offset.x = sin(_Time.y * _Speed.x + dis);//根据_Speed.x控制x轴速度
                offset.y = sin(_Time.y * _Speed.y + dis);//根据_Speed.y控制y轴速度

//根据_Speed.z控制z轴速度。同时_Speed.w 控制Z方向上的偏移距离大小
                offset.z = _Speed.w * sin(_Time.y * _Speed.z + dis);
                v.vertex.xyz += offset;

//变换到裁剪空间,所有顶点着色都需要此步的计算
                o.pos = mul(UNITY_MATRIX_MVP, v.vertex);

//这里用unity的宏计算世界空间法线方向,也可以用模型空间到世界空间的逆转置矩阵乘以模型空间法线方

//向获得,即normalize(mul(v.normal,(float3x3)unity_WorldToObject)); 
                float3 normalDir = normalize(UnityObjectToWorldNormal(v.normal));   

                //等同于先计算世界坐标系顶点信息worldPos,第一个平行光世界位置减worldPos再归一化获得       
                float3 lightDir = normalize(WorldSpaceLightDir (v.vertex));

//由lambert定律得知,光照强度和法线方向与光照方向的点积结果正相关。结果(-1,1)之间,强制舍弃

//负数部分极为lambert光照模型,通过下面等式把结果映射到(0,1)即为halflambert光照模型。

//lamber是符合物理的的光照算法,但halflambert的效果要好于lambert更符合计算机视觉需求

                fixed halflambert = dot(normalDir, lightDir) * 0.5 + 0.5;

//这里通过属性颜色和光照计算最终的颜色。需要光照的原因是效果中有阴暗面的区分,

//也会根据光照方向不同而改变。如果没有光照,这个凹凸不平的透明模型和一个透明的平面没有区别。
                fixed3 diffuse =  _Diffuse.rgb * halflambert;

              //通过属性_Diffuse.a控制透明度,把颜色传给片元着色器
                o.color = fixed4(diffuse, _Diffuse.a);
                return o;
            }

            //着片元计算,这里输出顶点中计算好的颜色即可
            fixed4 frag(v2f i) : SV_Target {
              return  i.color;   
            }
            ENDCG
        }
    }

    //当上面shader不管用时的备用着色器
    FallBack "Transparent/VertexLit"
}

到此为止,我们就把这个关于顶点漂移的shader写完了,终于理解为什么都说打这么多字还是很不容易的。哈哈,不够效果还可以的^-^。


    可以优化的点,失去的是自由度,但效果差别不是很大,可根据需求修改。

                float3 offset = float3 (0,0,0);//模型空间原点
                float dis = distance(v.vertex.xyz, offset);//计算幅度偏移量

dis= sin(_Time.y * _Speed.x + dis)
                offset.x = dis;
                offset.y = dis;

//根据_Speed.w 控制Z方向上的偏移距离大小
                offset.z = _Speed.w * dis;


最后上一张渣图,效果影响不堪入目。。。


这篇关于UnityShader顶点动画实现Mage-Fiers漂移效果的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Spring Boot 实现 IP 限流的原理、实践与利弊解析

《SpringBoot实现IP限流的原理、实践与利弊解析》在SpringBoot中实现IP限流是一种简单而有效的方式来保障系统的稳定性和可用性,本文给大家介绍SpringBoot实现IP限... 目录一、引言二、IP 限流原理2.1 令牌桶算法2.2 漏桶算法三、使用场景3.1 防止恶意攻击3.2 控制资源

springboot下载接口限速功能实现

《springboot下载接口限速功能实现》通过Redis统计并发数动态调整每个用户带宽,核心逻辑为每秒读取并发送限定数据量,防止单用户占用过多资源,确保整体下载均衡且高效,本文给大家介绍spring... 目录 一、整体目标 二、涉及的主要类/方法✅ 三、核心流程图解(简化) 四、关键代码详解1️⃣ 设置

Nginx 配置跨域的实现及常见问题解决

《Nginx配置跨域的实现及常见问题解决》本文主要介绍了Nginx配置跨域的实现及常见问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来... 目录1. 跨域1.1 同源策略1.2 跨域资源共享(CORS)2. Nginx 配置跨域的场景2.1

Python中提取文件名扩展名的多种方法实现

《Python中提取文件名扩展名的多种方法实现》在Python编程中,经常会遇到需要从文件名中提取扩展名的场景,Python提供了多种方法来实现这一功能,不同方法适用于不同的场景和需求,包括os.pa... 目录技术背景实现步骤方法一:使用os.path.splitext方法二:使用pathlib模块方法三

CSS实现元素撑满剩余空间的五种方法

《CSS实现元素撑满剩余空间的五种方法》在日常开发中,我们经常需要让某个元素占据容器的剩余空间,本文将介绍5种不同的方法来实现这个需求,并分析各种方法的优缺点,感兴趣的朋友一起看看吧... css实现元素撑满剩余空间的5种方法 在日常开发中,我们经常需要让某个元素占据容器的剩余空间。这是一个常见的布局需求

HTML5 getUserMedia API网页录音实现指南示例小结

《HTML5getUserMediaAPI网页录音实现指南示例小结》本教程将指导你如何利用这一API,结合WebAudioAPI,实现网页录音功能,从获取音频流到处理和保存录音,整个过程将逐步... 目录1. html5 getUserMedia API简介1.1 API概念与历史1.2 功能与优势1.3

Java实现删除文件中的指定内容

《Java实现删除文件中的指定内容》在日常开发中,经常需要对文本文件进行批量处理,其中,删除文件中指定内容是最常见的需求之一,下面我们就来看看如何使用java实现删除文件中的指定内容吧... 目录1. 项目背景详细介绍2. 项目需求详细介绍2.1 功能需求2.2 非功能需求3. 相关技术详细介绍3.1 Ja

使用Python和OpenCV库实现实时颜色识别系统

《使用Python和OpenCV库实现实时颜色识别系统》:本文主要介绍使用Python和OpenCV库实现的实时颜色识别系统,这个系统能够通过摄像头捕捉视频流,并在视频中指定区域内识别主要颜色(红... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间详解

PostgreSQL中MVCC 机制的实现

《PostgreSQL中MVCC机制的实现》本文主要介绍了PostgreSQL中MVCC机制的实现,通过多版本数据存储、快照隔离和事务ID管理实现高并发读写,具有一定的参考价值,感兴趣的可以了解一下... 目录一 MVCC 基本原理python1.1 MVCC 核心概念1.2 与传统锁机制对比二 Postg

SpringBoot整合Flowable实现工作流的详细流程

《SpringBoot整合Flowable实现工作流的详细流程》Flowable是一个使用Java编写的轻量级业务流程引擎,Flowable流程引擎可用于部署BPMN2.0流程定义,创建这些流程定义的... 目录1、流程引擎介绍2、创建项目3、画流程图4、开发接口4.1 Java 类梳理4.2 查看流程图4