【Shader特效6】膨胀效果顶点着色器的实现

膨胀效果顶点着色器的实现

说在开始:

最近使用顶点着色器开发了一个膨胀效果的例子,在这里进行总结一些算法和开发过程。

作者:尹豆(憨豆酒),联系我yindou97@163.com,熟悉图形学,图像处理领域,本章代码: https://github.com/douysu/computer-graphics-notes

参考内容:
  • 《OpenGL ES 3.X 游戏开发 下卷》

运行效果

这里写图片描述
这里写图片描述
第一幅图片为人头膨胀的效果,第二幅图为炸弹炸开的效果。此效果可以应用于加热膨胀,游戏膨胀死亡等效果。

基本原理

其基本原理很简单。
只是将物体的顶点沿着法向量的方向移动一定距离后就产生了这种效果。
注意:
人头沿着顶点法向量的方向移动了一段距离,炸弹是沿着面法向量移动了一段距离。

代码部分

#version 400
#extension GL_ARB_separate_shader_objects : enable //开启separate_shader_objects
#extension GL_ARB_shading_language_420pack : enable //开启shading_language_420pack
layout (push_constant) uniform constantVals { //推送常量块
    mat4 mvp; //总变换矩阵
} myConstantVals;
layout (std140,set = 0, binding = 0) uniform bufferVals { //一致块
    float uFatFactor; //吹气膨胀系数
} myBufferVals;
layout (location = 0) in vec3 pos; //输入的顶点位置
layout (location = 1) in vec2 inTexCoor; //输入的纹理坐标
layout (location = 2) in vec3 inNormal; //输入的顶点法向量
layout (location = 0) out vec2 outTexCoor; //输出到片元着色器的纹理坐标
out gl_PerVertex { //输出接口块
    vec4 gl_Position; //内建变量gl_Position
};
void main() {
    outTexCoor = inTexCoor; //输出到片元着色器的纹理坐标
    gl_Position = myConstantVals.mvp* vec4(pos+inNormal*myBufferVals.uFatFactor,1.0); //根据吹气膨胀系数计算顶点最终位置  
}

代码部分最重要的就是最后一行沿着法向量的方向移动一段距离的代码了。

最后:

本人的知识有限,如果本节内容有错误和不合理之处,还请朋友们多多指出,我会虚心接受每一个建议。

### 如何在 Unity 中创建生长动画特效 #### 使用 Animator 组件实现基础动画控制 为了实现场景中物体的生长动画,可以利用 `Animator` 控制器配合特定的状态机来管理不同阶段的变化过程。例如,在烟花绽放的过程中可以通过设置触发器改变其形态。 ```csharp using UnityEngine; public class GrowthAnimator : MonoBehaviour { private Animator animator; void Start() { // 初始化获取Animator组件实例 animator = GetComponent<Animator>(); // 可选:自动播放生长动画 Invoke("StartGrowth", 2f); } void StartGrowth(){ // 触发"Grow"事件使模型逐渐变大或其他形式的成长表现 animator.SetTrigger("Grow"); } } ``` 上述脚本展示了如何定义一个名为 `GrowthAnimator` 的类并关联到目标 GameObject 上[^1]。当调用 `SetTrigger("Grow")` 方法时会激活预设于 Animator Controller 内部对应名称的动作序列。 #### 利用 DoTween 插件制作平滑过渡效果 对于更加复杂的生长变化,比如文字或UI元素从小至大的渐变显示,则推荐借助第三方库如 DOTween 来简化开发流程。它允许开发者轻松指定起始与结束属性值以及持续时间等参数完成自定义曲线运动路径的设计。 ```csharp using DG.Tweening; using UnityEngine.UI; using UnityEngine; public class TextGrowAnimation : MonoBehaviour{ public float duration = 0.8f; private RectTransform rectTransform; void Awake(){ rectTransform = GetComponent<RectTransform>(); } void OnEnable(){ // 设置初始大小较小的比例因子 Vector3 startScale = new Vector3(0, 0, 1); // 完全展开后的最终比例 Vector3 endScale = Vector3.one * 1.5f; // 执行缩放动画 rectTransform.DOScale(endScale ,duration).SetEase(Ease.OutBack); } } ``` 此段代码片段说明了怎样运用 DOtween 对 UI 文字控件执行从无到有的放大显现操作[^2]。这里采用了非线性的缓动函数 (`OutBack`) 让整个过程看起来更为自然流畅。 #### 结合 Shader 技术增强视觉体验 如果追求更高层次的艺术表达力,还可以考虑引入着色器技术来自定义材质属性随时间演化的规律。这不仅限于尺寸上的增减,还包括颜色、透明度乃至纹理细节等方面的变化模拟植物萌芽或是晶体结晶的过程。 ```glsl Shader "Custom/GrowingMaterial" { Properties { _MainTex ("Texture", 2D) = "white" {} _Progress ("Growth Progress", Range(0., 1.)) = 0. } SubShader { Tags {"Queue"="Transparent"} Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag struct appdata_t { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 pos : SV_POSITION; }; sampler2D _MainTex; half _Progress; v2f vert (appdata_t v) { v2f o; // 根据进度调整顶点位置 o.pos = mul(UNITY_MATRIX_MVP, v.vertex * lerp(0.1, 1., _Progress)); o.uv = v.uv; return o; } fixed4 frag(v2f i) : COLOR { fixed4 col = tex2D(_MainTex, i.uv); clip(col.a - _Progress); // 渐显处理 return col; } ENDCG } } } ``` 这段 GLSL 风格的 HLSL 编写的着色程序实现了基于单个浮点数 `_Progress` 参数驱动的对象局部膨胀变形及半透明化的效果[^3]。通过不断更新该变量即可达到连续动态演变的目的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值