练习项目(一):顶点动画

概述

之前是使用OpenGL练习图形学项目的,现在要转向在Unity 3d中练习图像学项目。由此,才有了这一系列的项目。本篇将从比较简单的顶点动画说起,开启图形学的篇章。

原理

主要的原理,就是在顶点着色器中,对顶点进行各种偏移。这种偏移,可以根据自己的需要,在模型空间、世界空间、裁剪空间等空间中进行。

1、压扁效果

开放两个属性,TopY和BottomY,代表物体的上部和底部(世界空间中的数值)。再开放一个滑动属性用来控制顶点运动的幅度。

以TopY为基准,先计算出每个顶点的世界坐标,然后对顶点的Y坐标进行归一化处理。

            float GetNormalizeDist(float worldY)
            {
                float range = _TopY - _BottomY;
                float distance = _TopY - worldY;
                
                return saturate(distance / range);
            }

然后使用Control滑动属性控制相应的顶点进行位移。(在模型空间移动,之后再转到裁剪空间。)

                float3 positionWS = TransformObjectToWorld(input.positionOS.xyz);
                float normalizeDist = GetNormalizeDist(positionWS.y);
                
                float3 localNegativeY = TransformWorldToObjectDir(float3(0, -1, 0));
                float value = saturate(_Control - normalizeDist);
                input.positionOS.xyz += localNegativeY * value;
                
                output.vertex = TransformObjectToHClip(input.positionOS.xyz);

代码

2、被门吸收

与上面的压扁效果的原理类似,只是移动的方向变了,同时还要将顶点的世界坐标传递给片元着色器。

                float3 positionWS = TransformObjectToWorld(input.positionOS.xyz);
                float normalizeDist = GetNormalizeDist(positionWS.y);
                
                float3 localNegativeY = TransformWorldToObjectDir(float3(0, 1, 0));
                float value = saturate(_Control - normalizeDist);
                input.positionOS.xyz += localNegativeY * value;
                
                output.positionWS = TransformObjectToWorld(input.positionOS.xyz);

还要做一些特殊处理,对超过“门”的部分进行 C l i p Clip Clip操作,这是通过比较顶点的世界坐标的 Y Y Y值和 T o p Y TopY TopY来判断的。

clip(_TopY - input.positionWS.y);

代码

3、黑洞吸收

与上面的原理类似,只是顶点的移动方向不再是上面的 Y Y Y轴,而是朝向某个“黑洞”点。这里需要开放“黑洞”位置的属性接口。同时,也需要传递顶点的世界坐标给片元着色器。

                float3 positionWS = TransformObjectToWorld(input.positionOS.xyz);
                float normalizeDist = GetNormalizeDist(positionWS.x);
                
                float3 toBlackHole = TransformWorldToObjectDir(_BlackHolePos.xyz - positionWS.xyz);
                float value = saturate(_Control - normalizeDist);
                input.positionOS.xyz += toBlackHole * value;
                
                output.positionWS = TransformObjectToWorld(input.positionOS.xyz);

在片元着色器中,比较顶点的 X X X坐标和“黑洞”的 X X X坐标,进行 C l i p Clip Clip操作。

clip(_BlackHolePos.x - input.positionWS.x);

代码

4、残影

这里的实现原理是,一个 P a s s Pass Pass用来渲染本体,另一个 P a s s Pass Pass用来渲染残影。这里有一点需要注意,渲染本体的 P a s s Pass Pass L i g h t M o d e LightMode LightMode U n i v e r s a l F o r w a r d UniversalForward UniversalForward,要想让渲染残影的 P a s s Pass Pass也能正常渲染,需要设置该 P a s s Pass Pass L i g h t M o d e LightMode LightMode S R P D e f a u l t U n l i t SRPDefaultUnlit SRPDefaultUnlit

残影主要有两个实现点,一个是偏离本位,一个是残影自身的抖动。

首先是残影偏离本位,向特定方向整体偏移残影即可。

input.positionOS += _Offset * cos(_Time.y * _ShakeSpeed) * _ShakeDir * _Control;

接着是残影的抖动。这里的做法是先把顶点坐标的 X X X放大 10 10 10倍,再向下取整,然后求取对于 2 2 2的余数,对奇数部分的顶点进行偏移。

                float yOffset = 0.5 * (floor(input.positionOS.x * 10) % 2);
                
                input.positionOS += _ShakeLevel * yOffset * sin(_Time.y * _ShakeSpeed) * _ShakeDir * _Control;

在这里插入图片描述

代码

5、折纸

这里的原理是,对顶点以折叠处为中心进行旋转。同时要注意的是,为了同时渲染纸张的正面和背面,需要两个 P a s s Pass Pass,每个 P a s s Pass Pass都要设置正确的 C u l l Cull Cull模式。

这里是主要的重新计算折叠后的顶点位置的过程。

                float angle = _FoldAngle;
                float r = _FoldPos - input.positionOS.x;

                #if ENABLE_DOUBLE
                    if (r < 0) {
                        angle = 360 - _FoldAngle;
                    }
                #else
                    if (r < 0) {
                        angle = 180;
                    }
                #endif

                input.positionOS.x = _FoldPos + r * cos(angle * PI / 180);
                input.positionOS.y  = r * sin(angle * PI / 180);

                output.vertex = TransformObjectToHClip(input.positionOS.xyz);

代码

注意事项

上面的这几个小项目,只是练习用的,在真正用到项目中的时候,可能会有一些问题。在《 U n i t y S h a d e r 入 门 精 要 Unity Shader入门精要 UnityShader》一书的 11.3 顶 点 动 画 11.3 顶点动画 11.3一节中,提到了一些注意事项。一个问题是批处理对顶点动画的影响;一个是对有顶点动画的物体添加阴影的问题。这里不再展开,有需要的可以在书中找到答案。

参考

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值