顶点动画的注意事项

UE 顶点动画工具 (VAT) 导入模型需要勾选全精度UV。 阅读详情

1、为什么批处理会影响顶点动画

Unity中默认有静态批处理和动态批处理,批处理的主要作用是合并多个对象,将他们作为一个DrawCall进行处理,之所以批处理会对顶点动画带来影响,是因为不同的对象会拥有不同的变换矩阵(位置、旋转、缩放),而批处理后他们的变换矩阵会进行统一处理

举例:
物体A: 位于世界空间位置(0, 0, 0),无旋转。
物体B: 位于世界空间位置(5, 0, 0),无旋转。
他们是两个独立的对象,拥有不同的变换矩阵

  • 不进行批处理时:每个对象的变换矩阵会单独传递给Shader,顶点的模型空间位置会根据各自的变换进行正确计算
  • 进行批处理时:启用批处理后,Unity会将对象A和对象B合并为一个Draw Call,并使用一个统一的变换矩阵,比如在静态批处理中,Unity会将对象A和对象B的顶点合并为一个网格,并使用统一的变换进行渲染

批处理后顶点位置是混合的,Shader中无法区分不同对象的模型空间位置,可能带来的问题有:

  • 顶点动画失效:假设你希望顶点在模型空间的x方向上进行sin波动动画。如果对象A和对象B的模型空间位置被混合,波动动画会变得不可预测
  • 变换混淆:对象A和对象B有不同的变换矩阵。如果批处理后使用统一的变换矩阵,Shader无法区分每个顶点属于哪个对象,导致所有顶点的动画效果混淆。

总结

批处理会让对象失去独立性,相当于将多个对象之间独立的模型空间坐标系合并为一个坐标系
从而影响顶点的相对位置和变换矩阵等信息,导致顶点动画结果异常,因此我们通过渲染标签来关闭批处理

关闭批处理带来的问题

关闭批处理带来的最直接问题就是导致DrawCall的提升,DrawCall的提升可能会带来性能问题。

如果DrawCall的增加并没有带来性能问题,那我们可以通过关闭批处理来解决顶点动画问题
如果带来了性能问题,并且必须优化带有顶点动画的Shader,应该如何解决呢?

开启批处理后怎么获取正确的顶点数据

开启批处理后,顶点颜色来存储每个顶点的位置信息或相对位置信息
我们在C#代码中获取模型网格顶点数据,将数据存储到网格的颜色属性中,然后在Shader中通过颜色属性获取顶点信息

MeshFilter meshFilter = GetComponent<MeshFilter>();
if (meshFilter != null)
{
    Mesh mesh = meshFilter.mesh;
    Vector3[] vertices = mesh.vertices;
    Color[] colors = new Color[vertices.Length];

    for (int i = 0; i < vertices.Length; i++)
    {
        // 将模型空间位置存储在顶点颜色中
        colors[i] = new Color(vertices[i].x, vertices[i].y, vertices[i].z, 1);
    }

    mesh.colors = colors;
}

在Shader中直接在appdata_full结构体中点出颜色成员既可以利用它获取到顶点信息

和顶点颜色方案类似,只是把相关信息存储到uv通道中而已,但是一般在存储两个值时使用

2、顶点动画物体投射阴影

我们可以为有顶点动画的物体 使用 LightMode(灯光模式) 为 ShadowCaster(阴影投射) 的 Pass(渲染通道),这样它便能投射阴影
但是如果我们直接使用内置的这种Pass(默认Shader中的,通过FallBack寻找到的)投射的阴影会是不正确的,因为默认Pass当中并不会使用新的顶点位置来投射,而是按照模型原来的顶点位置来计算阴影

为了让顶点动画物体投射正确的阴影, 我们需要自定义一个LightMode(灯光模式) 为 ShadowCaster(阴影投射) 的 Pass(渲染通道), 在顶点着色器函数中进行顶点相关的计算

Shader "ShaderProj/8/2DWater_Shadow"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Color ("Color", Color) = (1,1,1,1)
        // 波动的幅度、频率、波长的倒数
        _WaveAmplitude("WaveAmplitude", Float) = 1
        _WaveFrequency("WaveFrequency", Float) = 1
        _InvWaveLength("InvWaveLength", Float) = 1

        // 纹理变化速度
        _Speed("Speed", Float) = 1
    }
    SubShader
    {
        //透明Shader相关渲染标签 + 关闭批处理标签
        Tags { "RenderType"="Tranparent" "Queue"="Transparent" "IgnoreProjector" = "True" "DisableBatching" ="True"}

        Pass
        {
            ZWrite Off
            Blend SrcAlpha OneMinusSrcAlpha

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
            float4 _Color;
            float _WaveAmplitude;
            float _WaveFrequency;
            float _InvWaveLength;
            float _Speed;

            v2f vert (appdata_base v)
            {
                v2f o;
                // 模型空间下的偏移位置
                float4 offset;
                // 在模型空间的 x 轴进行偏移
                offset.x = sin(_Time.y * _WaveFrequency + v.vertex.z * _InvWaveLength) * _WaveAmplitude;
                offset.yzw = float3(0, 0, 0);
                o.vertex = UnityObjectToClipPos(v.vertex + offset);
                o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);

                o.uv += float2(0, _Time.y * _Speed);

                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 color = tex2D(_MainTex, i.uv);
                color.rgb *= _Color.rgb;
                return color;
            }
            ENDCG
        }

        Pass{
            Tags{"LightMode" = "ShadowCaster"}
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_shadowcaster
            #include "UnityCG.cginc"

            struct v2f{
                V2F_SHADOW_CASTER;
            };

            float _WaveAmplitude;
            float _WaveFrequency;
            float _InvWaveLength;

            v2f vert(appdata_base v)
            {
                v2f data;
                float4 offset;
                offset.x = sin(_Time.y * _WaveFrequency + v.vertex.z * _InvWaveLength) * _WaveAmplitude;
                offset.yzw = float3(0,0,0);
                v.vertex = v.vertex + offset;

                TRANSFER_SHADOW_CASTER_NORMALOFFSET(data);
                return data;
            }

            float4 frag(v2f i):SV_Target
            {
                SHADOW_CASTER_FRAGMENT(i);
            }

            ENDCG
        }
    }
}

WEBGL保姆级教程(十):WebGL高级图形技术之动画效果实现 WebGL动画实现指南:核心原理与实战案例 本文系统讲解了WebGL动画的实现技术,主要包括:1)动画核心原理:通过渲染循环(requestAnimationFrame)连续更新模型状态实现动态效果;2)五大动画类型:变换动画、顶点动画、骨骼动画、粒子动画和状态动画;3)关键技术:时间控制(deltaTime)、插值计算(lerp/slerp)和矩阵变换;4)实战案例:包含立方体复合变换、平面波浪顶点动画和Three.js骨骼动画的实现代码。文章还提供了性能优化建议,如减少绘制调用、使用实例化渲染等,帮助开 阅读详情

相关推荐

Unity_Shader中级篇_11_Unity Shader入门精要

第十一章 让画面动起来 没有动画的画面往往让人觉得很无趣。在本章中,我们将学习如何向Unity Shader中引入时间变量,以实现各种动画效果。在11.1节中,我们首先会介绍Unity Shader内置的时间变量,在随后的章节中我们会使用这些时间变量来实现动画。11.2节会介绍两种常见的纹理动画,即序列帧动画和背景循环滚动动画。在11.3节,我们会学习使用顶点动画来实现流动的河流、广告牌等动画效...

wy小骑士 1631

UnityShader入门精要——顶点动画

流动的河流 Shader "Unity Shaders Book/Chapter 11/Water" { Properties { _MainTex ("Main Tex", 2D) = "white" {} //河流纹理 _Color ("Color Tint", Color) = (1, 1, 1, 1) //整体颜色 _Magnitude ("Distortion Magnitude", Float) = 1 //水流波动幅度 _Frequency ("Dist

weixin_51327051的博客 2428

Unity Shader 之 简单顶点(vertex)动画的效果实现

Unity Shader 之 简单顶点(vertex)动画的效果实现 目录 Unity Shader 之 简单顶点(vertex)动画的效果实现 一、简单介绍 二、实现原理 三、注意事项 四、效果预览 五、实现步骤 六、代码 一、简单介绍 Shader Language的发展方向是设计出在便携性方面可以和C++、Java等相比的高级语言,“赋予程序员灵活而方便...

仙魁XAN 2826

UnityShader 顶点动画

顶点动画是在顶点着色器中对顶点先进行偏移,然后做MVP变化,来模拟动画效果。 Shader "Custom/WaterMat" { Properties { _MainTex ("Texture", 2D) = "white" {} _WaveSpeed("WaveSpeed", float) = 1 _WaveScale("WaveScale", float) = 10 } SubShader ...

awsl_tsl的博客 724

Unity shader实现顶点动画波动效果

主要为大家详细介绍了Unity shader实现顶点动画波动效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

告别以太网瓶颈:手把手教你为AI训练集群搭建InfiniBand网络(以NVIDIA DGX A100/H100为例)

本文详细指导如何为AI训练集群搭建InfiniBand网络,解决以太网瓶颈问题,特别针对NVIDIA DGX A100/H100系统。通过硬件选型、网络架构设计和性能调优,显著提升多机多卡训练效率,适用于大规模模型训练场景。

weixin_30336061的博客 311

Shader学习的基础知识(十八)顶点动画

当为顶点做动画的时候就需要关闭批处理,因为批处理会合并所有相关的模型,而这些模型会失去各自的模型空间。下面的例子中因为需要对顶点进行操作,所以要关闭批处理。 ...

盖子的博客 717

【eNSP 华为模拟器】单臂路由实战:从原理到配置全解析

本文详细解析了单臂路由技术,通过华为eNSP模拟器从原理到配置进行实战教学。文章阐述了单臂路由如何利用路由器单物理接口创建多个子接口,实现不同VLAN间通信,并提供了完整的操作步骤、配置命令及排错方法,帮助网络工程师掌握这一经典网络技术。

698

UnityShader基础(六)——动画效果

Unity提供了一些内置变量用于做动画效果,比如_Time变量等,其中_Time.y代表从游戏开始到现在的正常时间。

SliverAsh_的博客 2673

基于Simulink的输入-输出线性化精确转矩控制

本文详细介绍了基于Simulink的永磁同步电机(PMSM)输入-输出线性化(IOL)精确转矩控制方法。针对传统解耦控制在非线性转矩特性下的局限性,通过建立PMSM非线性状态空间模型,设计IOL控制器将系统转化为线性输入-输出映射。文章包含系统原理推导、Simulink建模步骤、参数整定方法和仿真结果分析,验证了IOL在高动态、宽速域工况下的优越性能(转矩误差降低90%)。最后提出了工程实现要点和扩展应用方向,为开发高精度电机驱动系统提供了实用指导。

xiaoheshang_123的博客 304

环保 HJ212协议解析

由于是做环保相关的,有时需要对212协议进行拆包和解包。HJ212协议是一种字符串协议,数据传输通讯包主要由包头、数据段长度、数据段、CRC校验、包尾组成,其中“数据段”内容包括请求编码、系统编码、命令编码、密码、设备唯一标识、总包数、包号、指令参数。请求编码为请求的时间戳,系统编码ST统一规定为22,命令编码CN为该数据包的时间类型,访问密码、设备唯一标识在对接时由平台提供,指令参数为数据内容。通讯协议的数据结构如图4所示。 图4 通讯协议的数据结构 6.1.1通讯包结构组成 名称 类型 长度

ccf19881030的专栏 2万+

shader入门精要读书笔记27 顶点动画的阴影效果

一、定点动画的一些注意事项 上节说的取消批处理"DisableBatching"="True",是因为我们需要操作模型空间的信息,如果进行批处理,那么会合并模型以至于我们丢失模型的模型空间。所以之后如果要在顶点着色器中操作相关模型空间时,需要记得考虑是否需要关闭批处理。 取消批处理会增加Draw Call,带来一定的性能下降,所以我们需要尽可能地避免使用模型空间下的一些绝对位置来进行计算。 广告牌...

Chgmaker的博客 389

ABB机器人与S7-1200PLC实现位置坐标数据发送和接收的具体方法

ABB机器人与S7-1200PLC实现位置坐标数据发送和接收的具体方法

Robot_PLC_HMI_Automation 2917

MAX修改器动画导入UNITY工具包

MAX修改器动画导入UNITY工具包 去发现同类优质开源项目:https://gitcode.com/ 本工具包专为解决UNITY引擎无法直接识别3DMAX修改器动画的问题而设计。通过使用此工具包,您可以轻松地将3DMAX中通过修改器记录的动画转换为顶点动画,使其能够在UNITY引擎中正常播放。 功能特点 转换修改器动画:将3DMAX中记录的修改器动画转换为UNITY可识别的顶点动画。 无缝导入...

gitblog_06755的博客 691

【学习系列】SAP RAP 22:Excel文件上传和读取(非扩展&扩展方式)

本文介绍了在RAP中实现Excel文件上传处理的三种方法:1) 使用@Semantics.largeObject注解实现简单上传下载,但限制在ObjectPage页面使用;2) 通过自定义action弹窗实现上传功能,但存在无法自动刷新列表等限制;3) 结合CustomUIExtension实现更灵活的完整功能,但需要UI5开发技能。文章详细说明了每种方法的实现步骤,包括数据库表设计、注解配置、前端界面开发和后端处理逻辑,并比较了各自的优缺点。最后通过一个处理不同币种数据的示例,展示了如何实现业务处理逻辑。

DeveloperMrMeng的博客 623

YOLOv26全流程实战手册:从yaml配置拆解到训练推理参数调优(附虚拟环境搭建)

以“车辆、行人、小型物体”3类数据集为例,修改# 1. 修改类别数nc: 3# 2. 调整锚框(适配小目标)anchors:- [12,16, 16,24, 33,23] # 增加小锚框# 3. 轻量化调整(边缘部署)depth_multiple: 0.25 # 降低深度系数width_multiple: 0.20 # 降低宽度系数# 其余Backbone/Head结构不变yaml配置:核心是调整nc(类别数)、(轻量化)、anchors(适配目标尺度);虚拟环境。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 879

unity3d中水草海草摇动效果顶点动画材质

因为最近要尝试在untiy3d做写实海底的效果 为了让画面更加逼真,海底植物必不可少 然而海底的海藻海草之类需要加上动画就比较麻烦了 一般的骨骼动画加起来比较麻烦,而且效果比较单调,消耗也很大 更不用说动力学解算了,通常时间长,而且烘焙成顶点动画往往比较困难,而且无法很好循环 使用shader的uv动画或者序列帧动画又不适合写实场景 用unity3d自带风力的话更像是陆地上的植物,没有很好表现水下效果 所以这里使用了shader顶点动画来模拟海草在海底的波动

shenmifangke的专栏 1万+

基于matlab的阈值分割的车牌定位识别系统

车牌自动识别模块是现代社会智能交通系统(ITS)的重要组成部分,是图像处理和模式识别技术研究的热点,具有非常广泛的应用。车牌识别主要包括以下三个主要步骤:车牌区域定位、车牌字符分割、车牌字符识别。本案例通过对采集的车牌图像进行灰度变换、边缘检测、腐蚀及平滑等过程进行车牌图像预处理,并由此得到一种基于车牌颜色纹理特征的车牌定位方法,最终实现了车牌区域定位。车牌字符分割是为了方便后续对车牌字符进行匹配,从而对车牌进行识别。

在职AI算法工程师,擅长计算机视觉,YOLO目标检测、分割等,擅长web、pyqt界面可视化,好内容持续更新中,来这里跟大家一起学习,共同进步 969

Shader 纹理动画和顶点动画

要实现动画,我们需要把时间添加到计算当中,让画面可以随着时间变化而变化。在Unity Shader提供了如下关于时间的内置变量以便于在shader中访问时间实现各种动态效果。

qq_35064654的博客 798

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Amplify Shader Editor(ASE)效果实现笔记(二)——顶点动画(原理向)

ASE使用心得

m0_54122551的博客 2394

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

(二十一)unity Shader——————shader中的动画效果:下篇(顶点动画)

顶点动画可以让我们的场景变得更加生动有趣。在游戏中,我们常常使用顶点动画来模拟飘动的旗帜,河流的效果。下面将学习两种常见的顶点动画应用:流动的河流以及广告牌技术,最后还给出一些顶点动画中的注意事项以及解决方法。 一、流动的河流 河流的模拟是顶点动画最常见的应用之一。原理通常是使用正弦函数等来模拟水流的波动效果。本节会展示如何模拟一个2D的河流效果。 1.声明属性: Propertie...

cgy56191948的博客 1328

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

shader 雪 顶点位移_练习项目(一):顶点动画

概述之前是使用OpenGL练习图形学项目的,现在要转向在Unity 3d中练习图像学项目。由此,才有了这一系列的项目。本篇将从比较简单的顶点动画说起,开启图形学的篇章。原理主要的原理,就是在顶点着色器中,对顶点进行各种偏移。这种偏移,可以根据自己的需要,在模型空间、世界空间、裁剪空间等空间中进行。1、压扁效果开放两个属性,TopY和BottomY,代表物体的上部和底部(世界空间中的数值)。再开放一...

weixin_35203943的博客 918

ShaderGraph节点解析(三十二):顶点 ID 节点(Vertex ID Node)详解

摘要:VertexID节点是UnityShaderGraph中的核心工具,通过获取网格顶点唯一索引实现精细化控制。该节点提供高效顶点级数据处理能力,支持程序化建模、动画效果和资源优化。技术层面,节点直接访问内置顶点ID变量,在顶点和片段阶段分别处理。典型应用包括:基于ID的正弦变形动画、顶点随机着色以及LOD切换优化。使用时需注意片段阶段精度问题,可与位置/噪声节点配合实现复杂效果。该节点为程序化建模提供算法基础,特别适合大规模网格的精细化控制和性能优化,在VR/动态网格领域具有扩展潜力。

分享知识,拥抱变化 1266

【UnityShader入门精要学习笔记】第十一章 Shader动画

动画效果的实现往往是通过把时间添加到一些变量的计算中,以便在时间变化时画面也随之变化。UnityShader中提供了一系列关于时间的内置变量来允许我们方便地在Unity中访问运行时间

milu_ELK的博客 1700

独立游戏优化:GPU骨骼蒙皮与VAT顶点动画实现解析

骨骼动画是3D游戏中角色动作的基础,CPU逐顶点蒙皮在同屏大量角色时成为性能瓶颈。GPU动画将蒙皮计算移至顶点着色器,通过实时骨骼矩阵或顶点动画纹理(VAT)方式,极大降低CPU负担,并更易实现GPU Instancing合批。在独立游戏割草、尸潮、ARPG刷怪等场景中,GPU动画是性价比极高的优化手段。文章从原理出发,对比两种主流实现路线,并附完整Unity代码与工程化建议,适合需要同屏大量角色的开发者参考。

weixin_27945229的博客 272

Unity性能优化_动画

在项目开发过程中,动画表现需要考虑到其实现的经济性与适合的应用场景。PS:粒子特效可以被视为动画表现的一种形式。但是由于其非线性的特点,不在这里展开描述。

一些开发技术备忘 212
上一篇: 顶点动画-广告牌
下一篇: 代码修改材质参数
Go_Accepted
博客等级 码龄10年 601粉丝 334原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值