案例精选: 3D涂鸦
很多3D休闲益智类游戏经常的一个玩法就是涂鸦,用户通过操作把颜色涂上去。我们还见过有些游戏,在雪地里面行走过后,留下了脚印,这些都可以用今天的的技术原理来解决,先来看下今天的效果:
(3D涂鸦,踏雪脚印)
要实现这个效果,其实不难,主要做好下面的几个方面。接下来我们一起分析一下。
1: 3D涂鸦实现原理与思路
写代码思路很重要,把思路搞明白了,才知道如何去做。涂鸦就是要实时的改变纹理贴图的颜色,把触摸过的位置对应的纹理的颜色特定的颜色。涂鸦的时候,我们首先能获取的触摸坐标(屏幕坐标), 获取触摸坐标以后,接下来就要计算出来我们触摸坐标对应的模型上的3D模型坐标点。接下来我们要把这个模型坐标点对应的纹理坐标算出来。通过3D模型坐标,我们可以找出这个模型点所在的三角形的面,就可以知道这个三角形的面的3个顶点的模型坐标, 法线数据,纹理坐标等。我们通过插值就可以计算出来触摸对应的3D模型点的uv坐标。uv坐标确认后,根据纹理的大小,我们就能确认要涂鸦的纹理的位置。最后,我们以这个位置为中心,把涂上的颜色或贴图数据写入到纹理内存里面。把思路总结一下:
step1: 将触摸坐标转成对应的模型的3D坐标;
step2: 通过模型的3D坐标,计算出来这个点对应的UV坐标;
step3: 将uv坐标+纹理,得到纹理中的像素坐标,根据像素坐标来改变颜色。
2: 如何通过触摸获取模型坐标点
这个思路很简单,一般使用物理引擎的射线检测,从摄像机到屏幕触摸位置,发射一条射线,如果这个射线撞到了物体的表面的哪个点,那么就得到了碰撞点的世界坐标,世界坐标有了以后,再把世界坐标通过坐标系转换,转换到本地坐标系中。这样我们就获得了触摸点锁对应的模型坐标。
3: 3D模型坐标转为纹理UV坐标
这个过程是整个计算里面最复杂的,首先我们要根据3D模型坐标点,计算出来这个模型点所在的三角形的面。这样我们就能获得这个面对应的3个顶点的顶点数据(坐标,纹理,法线等)。接下来我们要结合当前游戏摄像机,对这个面的3个顶点进行投影变化,得到投影坐标,然后根据3个顶点的UV坐标,结合插值算法,计算出当前模型点对应的UV坐标。UV坐标出来以后,我们就可以结合纹理对象的大小,找到纹理中对应的像素颜色,纹理的Width*U 就是纹理的x坐标, 纹理的Height*V就是纹理的y坐标,那么我们触摸的中心点,对应纹理中的像素就是(x, y)。
4: 涂鸦颜色到目标纹理
我们做涂鸦的时候,肯定不能是一个像素,一般我们得处理是以这个像素为中心,以一个合适的半径,来做一个圆,把圆范围内的都涂成我们的目标颜色。如何涂一个圆呢?算法其实很简单,假设半径为R,那么我们遍历以(x, y)为中心的上下左右[-R, R]的范围的每个点, 如果x^2 + y^2 <= R,我们就把这个点涂上颜色,否者我们就跳过。如果我们是要涂上一个小贴图,比如行走在雪地中的脚印,我们就从(x -R, y -R)这个点开始,把脚印的纹理数据copy到目标纹理对象,这样这个脚印就贴图上去了。
(3D涂鸦,踏雪脚印)
好了,整个涂鸦的技术流程就给大家分析清楚了,还不懂的小伙伴可以看看Blake老师讲解的这个视频教程 3d涂鸦