【ylg速成教程】在Unity中制作♿说的道理和栗子头♿

前言

大家好啊,我是狗猥,今天来点大家想看的东西。

说的道理和栗子头是吉吉王国答辩文化中不可磨灭的两颗璀璨明珠,它是用视频编辑软件Vegas中的Tiny Planet效果制作的。

DJGun出过一个视频讲解了实现原理,但细节部分几乎没有。

视频是这个:DJGun教你制作栗子头和说的道理

于是我在摸鱼的时候研究搞定了,把原理和实现过程分享给大家,祝大家早日成为ylg,像文老爷子一样把答辩拉得到处都是。

本项目使用Unity 2021.3.13f1制作,完整工程请移步GitHub:https://github.com/RenChiyu/UnityChestnutHead

转载请注明出处:https://www.cnblogs.com/GuyaWeiren/p/17204417.html

(这种一拖四的文章除了机器人应该没人会转吧)

原理

一. 平面图片变成球面

视频中是将图片贴在球上,所以要把图片的平面mesh转化成球面mesh。转换过程使用球的参数方程:

{x1=sin(ϕ)×cos(θ)y1=sin(ϕ)×sin(θ)z1=cos(ϕ)

其中θ=u×2πϕ=v×πuv即每个顶点的uv。

二. 投影的公式推导

通过视频我们能知道,说的道理是将球投影到平面所形成的。

其过程是,从球的极点开始,向球面任意点发射一条射线,射线与赤道平面所相交的点就是投影点。

这里以二维的圆来作为范例(三维的做起来麻烦,偷个懒):

极点为P0,圆上的任意点P1,与x轴交点为P。可以看到球面每个点和x轴的交点都是一一对应的。并且,我们可以用公式来描述这个映射。

首先需要知道射线的方程。三维空间中过点P0(x0,y0,z0)和点P1(x1,y1,z1)的直线可用两点式表示:

xx0x1x0=yy0y1y0=zz0z1z0

由于射线从球的极点发出,有P0(0,r,0)。其中r为球的半径。将球视作单位球,即r=1

并且,当该直线和赤道平面(即XOZ平面)相交时y=0。一并带入上式化简得到:

{x=x1y11z=z1y11

如上,我们就得到了射线和平面交点的坐标P(x,0,z)

三. 栗子头的变换

栗子头是保持极点和赤道平面不变,只旋转球体本身,旋转到特定角度时投影的结果。

如上图的gif,想象鼠标拖动P1的过程并不是P1在圆上移动,而是拖动圆让它绕原点旋转。

Unity实现

这里可以在C#层实现,也可以用Shader。我选择了Shader。所有的变换都可以放在顶点着色器中。

由于直接设置transform的旋转会导致整个模型发生旋转,为了保持极点和赤道平面不变,需要在顶点着色器中进行旋转变换。

在C#层使用Matrix4x4.TRS(Vector3 pos, Quaternion q, Vector3 s)即可构建变换矩阵。

v2f vert (appdata v)
{
v2f o;
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
// 平面变换为球
float theta = v.uv.x * UNITY_TWO_PI;
float phi = v.uv.y * UNITY_PI;
float x1 = sin(phi) * cos(theta);
float y1 = sin(phi) * sin(theta);
float z1 = cos(phi);
// 应用旋转矩阵
float4 p = mul(_TRSMatrix, float4(x1, y1, z1, v.vertex.w));
x1 = p.x;
y1 = p.y;
z1 = p.z;
// 计算出投影后的坐标
p.x = -x1 / (y1 - 1);
p.y = 0;
p.z = -z1 / (y1 - 1);
o.vertex = UnityObjectToClipPos(p);
return o;
}

上述代码中_TRSMatrix即为C#层传入的变换矩阵。

Unity自带的Plane mesh的格子是10*10的,数量不够生成的图会有明显的扭曲。这里我用了一个自己生成的很密的mesh。

然后建立材质,贴上电棍的图片,通过调整xyz的旋转,就能得到♿说的道理或栗子头♿:

当然,你也可以用自己喜欢的图片进行创作。

后记

各位学到了没有?来!

(瞳子姐对不住了)

很惭愧,就做了一点微小的工作,谢谢大家。

posted @   GuyaWeiren  阅读(1507)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示