超凡学车面试题

2021-05-18 08:56发布

1、NormalMap 也就是法线贴图和Mesh结构中存储的法线有什么区别,Mesh如果有法线数据那么为什么还需要法线贴图?法线贴图中的法线存储的一般是哪个坐标空间下的值?为什么?


答:

      法线贴图是跟灯光交互,模拟出凹凸效果,mesh结构中储存的法线主要是模型本身的信息,用来标记正反面和光滑程度


      法线数据不控制凹凸,法线贴图控制凹凸,所以需要法线贴图


      法线贴图中的法线储存一般是Z轴的值,因为法线贴图是控制凹凸效果的





2、一个由起点和终点构成的线段,还有另外一个在移动的点,怎么判断这个移动的点处于线段左侧还是右侧,或者是正好落在线上。写Unity代码实现,需要发过来工程。


答:

      使用叉乘,详情请看工程




3、Unity批处理分为静态批处理和动态批处理。请问为什么不统一用一种批处理。

静态批处理本质上做了什么?在Unity资源目录创建一个材质,再从其复制出来一个,分别赋给场景中的一个简易球模型和方块模型。这两个物体勾为静态。运行,问两个物体是否被静态批处理了?


答:

      因为动态批处理有很多限制条件,所以才有了静态批处理比如:如果着色器使用顶点位置、法线和UV值三种属性,就只能批处理300个顶点以下的物体

      动态批处理:unity会自动完成,不需要我们进行操作,而且物体是可以移动的,但是动态批处理有许多限制条件。对于足够小的mesh,动态批处理通过将他们的顶点整合到一个批次中进行绘制

      静态批处理:通过将不会移动的静态物体合并到更大的mesh中,以提升渲染速度,物体不可移动,但是限制条件很少。

      

      本质上都是把几何体合并,用于将多个对象的网格数据合并到一起,并在单一指令中渲染他们,而不是单独准备和回执每个几何体


      这两个物体没有静态批处理,因为被“批处理”的2个物体的网格模型需要使用相同材质的目的,在于其纹理是相同的,这样才可以实现同时渲染的目的。因而保证材质相同,是为了保证被渲染的纹理相同。

      因此,为了将2个纹理不同的材质合二为一,我们就需要将纹理打包成图集。就是将2个纹理合成一个纹理。这样就可以只用一个材质来代替之前的2个材质了。





4、汽车灯光假如有以下几种:近光灯、远光灯、远近交替灯、示廓灯、左转灯、右转灯、雾灯、双闪灯。同时可以打多个灯光。请设计一个数据结构,以支持检测当前灯光组合是否打开正确?


答:

      1、使用OnGui中的EnumFlagsField,需要打开哪种灯就勾选上,然后用八位二进制的数判断是不是在预先定义的范围之中

      2、使用字符串,也是用八位0和1来纪录当前开启的灯光(0为关,1为开),之后判断是不是在预先定义的范围之中(远近交替灯需要提供接口)

      (例如:提示学院现在为雾天,表示就是00000010)

      





5、Unity的欧拉角类 Quaternion 中的四个分量x,y,z,w 分别代表什么含义,表示的是什么?


答:

四元数是4*4的矩阵旋转,x,y,z 表示轴,w表示旋转的角度


x = sin(Y/2)sin(Z/2)cos(X/2)+cos(Y/2)cos(Z/2)sin(X/2)

y = sin(Y/2)cos(Z/2)cos(X/2)+cos(Y/2)sin(Z/2)sin(X/2)

z = cos(Y/2)sin(Z/2)cos(X/2)-sin(Y/2)cos(Z/2)sin(X/2)

w = cos(Y/2)cos(Z/2)cos(X/2)-sin(Y/2)sin(Z/2)sin(X/2)

q = ((x, y, z), w)





6、选做。


【根据代码,找出算法来源】 - 请用两个小时到一天时间证明出来。


有一高度图文件,即将被应用于一地形网格中,地形网格精度可能大于高度图分辨率。因此需要进行数值平滑。(不懂高度图与地形的可以理解为图片放大算法)


其中: MapSize为原始高度图宽度或高度的值 -1 (正整数,长宽一样)。代码中的Heightmap为程序已经从原始高度图中读取到的高度图二维数组数值(Short类型)。如:

public short[,] Heightmap;


根据以下代码,请找到GetSmoothElevation中算法来源,并推导出算法中几个系数0.25、1/12,1/36的来源。

/*

逐点获取地形网格高度,读取高度图文件,返回平滑后的值,赋给地形的网格点高度

参数x,y为地形逐网格坐标除以长,宽归一化后的坐标,取值范围 0-1。

*/

public double GetElevation (double x, double y)

{

        double cx = x * MapSize;

        double cy = y * MapSize;

        int ix = (int)cx;

        int iy = (int)cy;

        double ox = cx - ix;

        double oy = cy - iy;


return GetSmoothElevation(ox - 1, ox - 2, ox + 1, oy - 1, oy - 2, oy + 1, 

ix, iy, ox, ix + 1, oy, iy + 1, ox * oy, ix - 1, iy - 1, ix + 2, iy + 2);

}

/*读取原始高度图(二维数组)的值*/

short H(int x, int y)

{

        if (x < 0) x = 0;

        else if (x > MapSize) x = MapSize;

        if (y < 0) y = 0;

        else if (y > MapSize) y = MapSize;

        short v = Heightmap[x, y];

        return v;

}

/*获取平滑高度值*/

double GetSmoothElevation(double xs1, double xs2, double xp1, double ys1, double ys2, double yp1, int ix, int iy, double ox, int ixp1, double oy, int iyp1, double oxy, int ixs1, int iys1, int ixp2, int iyp2)

{

            double result = xs1 * xs2 * xp1 * ys1 * ys2 * yp1 * 0.25 * H (ix, iy);

            result -= ox * xp1 * xs2 * ys1 * ys2 * yp1 * 0.25 * H (ixp1, iy);

            result -= oy * xs1 * xs2 * xp1 * yp1 * ys2 * 0.25 * H (ix, iyp1);

            result += oxy * xp1 * xs2 * yp1 * ys2 * 0.25 * H (ixp1, iyp1);

            result -= ox * xs1 * xs2 * ys1 * ys2 * yp1 / 12.0 * H (ixs1, iy);

            result -= oy * xs1 * xs2 * xp1 * ys1 * ys2 / 12.0 * H (ix, iys1);

            result += oxy * xs1 * xs2 * yp1 * ys2 / 12.0 * H (ixs1, iyp1);

            result += oxy * xp1 * xs2 * ys1 * ys2 / 12.0 * H (ixp1, iys1);

            result += ox * xs1 * xp1 * ys1 * ys2 * yp1 / 12.0 * H (ixp2, iy);

            result += oy * xs1 * xs2 * xp1 * ys1 * yp1 / 12.0 * H (ix, iyp2);

            result += oxy * xs1 * xs2 * ys1 * ys2 / 36.0 * H (ixs1, iys1);

            result -= oxy * xs1 * xp1 * yp1 * ys2 / 12.0 * H (ixp2, iyp1);

            result -= oxy * xp1 * xs2 * ys1 * yp1 / 12.0 * H (ixp1, iyp2);

            result -= oxy * xs1 * xp1 * ys1 * ys2 / 36.0 * H (ixp2, iys1);

            result -= oxy * xs1 * xs2 * ys1 * yp1 / 36.0 * H (ixs1, iyp2);

            result += oxy * xs1 * xp1 * ys1 * yp1 / 36.0 * H (ixp2, iyp2);

            return result;

 }


答:

      这个是图像插值算法,从网上搜集到的资料有:双线性插值,最近邻插值法,双立方插值算法,双三次插值,经过对比发现非常像双立方插值算法的简易版本