1. 场景管理的数据结构:

总结,游戏开发最常用的空间数据结构是四叉/八叉树和BVH树,而BSP树基本上只能应用于编辑器上,k-d树则只能用在特殊问题应用场景。

2. 帧同步与状态同步:

https://gameinstitute.qq.com/community/detail/132935
https://gameinstitute.qq.com/community/detail/115782

3. 描述一下渲染管线?

渲染管线的主要功能是决定在给定虚拟相机、三维物体、光源、照明模式,以及纹理等诸多条件的情况下,生成或绘制一幅二维图像的过程。概念上可以将图形渲染管线分为三个阶段:应用程序阶段、几何阶段、光栅化阶段。


建议阅读《Unity Shader入门精要》P72-P85,深入了解渲染流水线中涉及的坐标变换。

参考《RTR3提炼总结》P6-P32,《Unity Shader入门精要》P6-P17。

4. 齐次坐标: 既能够用来明确区分向量和点,同时也更易用于进行仿射变换。

仿射变换是线性变换后进行平移变换(其实也是齐次空间的线性变换),使用齐次坐标使得仿射变换可以以统一的矩阵形式进行表示。

https://guangchun.wordpress.com/2011/10/12/affineandhomogeneous/
https://www.cnblogs.com/csyisong/archive/2008/12/09/1351372.html
https://zhuanlan.zhihu.com/p/73123357

5. 屏幕后处理?

将场景渲染到一个附加到帧缓冲对象上的颜色纹理中,之后将在一个横跨整个屏幕的四边形上绘制这个纹理。既然整个场景都被渲染到了一个纹理上,我们可以简单地通过修改纹理数据创建出一些非常有意思的效果。
https://learnopengl-cn.github.io/04%20Advanced%20OpenGL/05%20Framebuffers/

6. 延迟渲染?

可以将延迟渲染( Deferred Rendering)理解为先将所有物体都先绘制到屏幕空间的缓冲(即 Gbuffer, Geometric Buffer,几何缓冲区)中,再逐光源对该缓冲进行着色的过程,从而避免了因计算被深度测试丢弃的⽚元的着色而产⽣的不必要的开销。 也就是说延迟渲染基本思想是,先执行深度测试,再进行着色计算,将本来在物空间(三维空间)进行光照计算放到了像空间(二维空间)进行处理。
延迟渲染的优点:

  • 只渲染可见的像素,节省计算量。
  • 对后处理支持良好。
  • 在大量光源的场景优势尤其明显。

延迟渲染的缺点:

  • 内存开销较大。
  • 读写 G-buffer 的内存带宽用量是性能瓶颈。
  • 对半透明物体的渲染存在问题。在这点上需要结合正向渲染进行渲染。
  • 对多重采样抗锯齿(MultiSampling Anti-Aliasing, MSAA)的支持不友好,主要是因为内存开销和内存带宽需要太大。
  • 由于对像素点进行着色,无法针对每种物体使用自定义的着色器。

Gbuffer中保存的信息包括:顶点位置向量、漫反射颜色向量、法向量、镜面强度(Specular Intensity)浮点值、光源的位置和颜色向量、摄像机的位置向量等等。

另外可参考:
https://learnopengl-cn.github.io/05%20Advanced%20Lighting/08%20Deferred%20Shading/
https://zhuanlan.zhihu.com/p/102134614

7. 着色处理方法?

平滑着色(Flat shading)、高洛德着色(Gouraud shading)、冯氏着色(Phong shading)。
高洛德着色的缺点:

  • 着色后仍然可以看出一个个小平面的效果
  • 高洛德着色对于强高光反射的表面, 可能会产生失真(artifacts)。如果在多边形的中心有高光,而且这个高光没有扩散到该多边形的任何顶点,使用Gouraud着色法就不会渲染出任何效果;而如果正好是多边形的顶点上有高光,那么这个点上的高光是正确的,但插值会导致高光以很不自然的形式扩散到相邻的多边形上。
  • 另外注意 Phong Shading 和 Phong Lighting Model 的区别,前者是考虑如何在三个顶点中填充颜色,而后者表示的是物体被光照产生的效果。

参考《RTR3提炼总结》P38

8. 透明物体渲染?

要想让混合在多个物体上工作,我们需要最先绘制最远的物体,最后绘制最近的物体。普通不需要混合的物体仍然可以使用深度缓冲正常绘制,所以它们不需要排序。但我们仍要保证它们在绘制(排序的)透明物体之前已经绘制完毕了。当绘制一个有不透明和透明物体的场景的时候,大体的原则如下:

  • 先绘制所有不透明的物体。
  • 对所有透明的物体排序。
  • 按顺序绘制所有透明的物体。

https://learnopengl-cn.github.io/04%20Advanced%20OpenGL/03%20Blending/

9. Draw Call?

DrawCall很简单,就是CPU对图形绘制接口的调用,CPU通过调用图形库(directx/opengl)接口,命令GPU进行渲染操作。每一次绘制CPU都要调用DrawCall,而在调动DrawCall前,CPU还要进行很多准备工作:检测渲染状态、提交渲染所需要的数据、提交渲染所需要的状态。而GPU本身具有很强大的计算能力,可以很快就处理完渲染任务。当DrawCall过多,CPU就会很多额外开销用于准备工作,CPU本身负载,而这时GPU可能闲置了。
优化方法例如批处理(Batching):尽量把小的DrawCall合并到一个大的DrawCall中,这就是批处理的思想。使用批处理我们需要在CPU和RAM中合并网格,合并的条件至少是:同材质、同贴图、同shader,最好网格顶点格式也一致。
https://zhuanlan.zhihu.com/p/26077873?refer=c_83023344

10. 实例化?

实例化这项技术能够让我们使用一个渲染调用来绘制多个物体,来节省每次绘制物体时CPU -> GPU的通信,它只需要一次即可。如果想使用实例化渲染,我们只需要将glDrawArrays和glDrawElements的渲染调用分别改为glDrawArraysInstanced和glDrawElementsInstanced就可以了(注意实例化数组的使用)。
可以使用uniform数组传递每个实例的数据,但数量很大的时候就用不了了,uniform数组有大小限制。最好的做法是使用实例化数组。实例化数组(Instanced Array),它被定义为一个顶点属性(能够让我们储存更多的数据),仅在顶点着色器渲染一个新的实例时才会更新。通过调用glVertexAttribDivisor这个函数告诉OpenGL该什么时候更新顶点属性的内容至新一组数据。
https://learnopengl-cn.github.io/04%20Advanced%20OpenGL/10%20Instancing/

11. 边缘检测算子:Sobel算子、Canny算子等。

https://www.cnblogs.com/wj-1314/p/9800272.html

12. 提前深度测试及其失效的情况

现在大部分的GPU都提供一个叫做提前深度测试(Early Depth Testing)的硬件特性。提前深度测试允许深度测试在片段着色器之前运行。只要我们清楚一个片段永远不会是可见的(它在其他物体之后),我们就能提前丢弃这个片段。片段着色器通常开销都是很大的,所以我们应该尽可能避免运行它们。当使用提前深度测试时,片段着色器的一个限制是你不能写入片段的深度值。如果一个片段着色器对它的深度值进行了写入,提前深度测试是不可能的。OpenGL不能提前知道深度值。

提前深度测试失效的情况包括:

  • 开启Alpha Test:由于Alpha Test需要在像素着色器后面的Alpha Test阶段比较,所以无法在像素着色器之前就决定该像素是否被剔除。
  • 开启Alpha Blend:启用了Alpha混合的像素很多需要与frame buffer做混合,无法执行深度测试,也就无法利用Early-Z技术。
  • 开启Tex Kill:即在shader代码中有像素摒弃指令(DX的discard,OpenGL的clip)。
  • 关闭深度测试。Early-Z是建立在深度测试开启的条件下,如果关闭了深度测试,也就无法启用Early-Z技术。
  • 开启Multi-Sampling:多采样会影响周边像素,而Early-Z阶段无法得知周边像素是否被裁剪,故无法提前剔除。
  • 以及其它任何导致需要混合后面颜色的操作

参考 Learn OpenGL 和 GPU架构 核心问题笔记

13. 卡通着色(Toon Rendering/ Cel Rendering):卡通着色基本的三个要素

  • 锐利的阴影(Sharp shadows)
  • 少有或没有高亮的点(Little or no highlight)
  • 对物体轮廓进行描边(Outline around objects)

使用 2-tone 方法来表示光照效果和阴影区域。也称为硬着色方法(Hard Shading),可以通过将传统光照方程元素重新映射到不同的调色板上来实现。具体的着色方法,可以理解为在 Fragment shader 中测试每个像素漫反射 diffuse 中的 NdotL值,让漫反射形成一个阶梯函数,不同的 NdotL 区域对应不同的颜色。
参考《RTR3提炼总结》P166-P167

14. 描边算法:轮廓描边的渲染方法?

分为以下五种:

  • 基于视点方向的描边
  • 基于过程几何方法的描边
  • 基于图像处理的描边
  • 基于轮廓边缘检测的描边
  • 混和轮廓描边

参考《RTR3提炼总结》P167-P171
另外可参考:https://zhuanlan.zhihu.com/p/25939794
https://blog.csdn.net/candycat1992/article/details/45577749

15. 判断点是否在三角形内:

https://www.cnblogs.com/graphics/archive/2010/08/05/1793393.html

16.射线与球体相交检测?

联立光线方程和表面方程求解方程。

17. 如下图


若两个 AABB 在三个维度上的区间都重叠,则两者相交。
OBB 要使用最多 15 个分离轴去判断两者是否相交。

参考
AABB碰撞检测
OBB碰撞检测
Cocos2d-x教程-三维物体OBB碰撞检测算法

18. 漫反射方程1/π的由来?

19. 怎么光栅化一个三角形?

计算三角形的最小包围盒,判断包围盒中的每个像素是否位于三角形内,是的话则进行着色。

20. PBR知道吗?它的一些模型?比如高光模型这些?

PBR即基于物理的渲染。渲染方程(Render Equation)是用来模拟光的视觉效果最好的模型。而PBR的渲染方程是用以抽象地描述PBR光照计算过程的特化版本的渲染方程,被称为反射方程。

fr 就是双向反射分布函数(Bidirectional Reflectance Distribution Function, BRDF),它的作用是基于表面材质属性来对入射辐射度进行缩放或者加权。BRDF分为漫反射和镜面反射两个部分。


漫反射模型用的是朗伯BRDF模型:

其中c代表的是Albedo或表面颜色,类似漫反射表面纹理。

高光模型由3个函数(D,F,G)和一个标准化因子构成。

  • D (Normal Distribution Function,NDF):法线分布函数,估算在受到表面粗糙度的影响下,取向方向与中间向量一致的微平面的数量。这是用来估算微平面的主要函数。
  • F(Fresnel equation):菲涅尔方程,描述的是在不同的表面角下表面反射的光线所占的比率。
  • G(Geometry function):几何函数,描述了微平面自成阴影的属性。当一个平面相对比较粗糙的时候,平面表面上的微平面有可能挡住其他的微平面从而减少表面所反射的光线。

21. 知道什么是IBL吗?怎么生成cubemap?

基于图像的光照。反射方程中计算漫反射辐照度的部分可以预计算出一个新的cubemap,这个cubemap存储了用卷积(convolution)计算出的每个采样方向(或像素)ωo的漫反射积分结果。
卷积(convolution)是对数据集的每个入口应用一些计算,假设其它所有的入口都在这个数据集里。此处的数据集就是场景辐射或环境图。因此,对cubemap的每个采样方向,我们可以顾及在半球Ω的其它所有的采样方向。
为了卷积环境图,我们要解决每个输出ωo采样方向的积分,通过离散地采样大量的在半球Ω的方向ωi并取它们辐射的平均值。采样方向ωi 的半球是以点p为中心,以ωo为法平面的。

这个预计算为每个采样方向ωo存储了积分结果的cubemap,可被当成是预计算的在场景中所有的击中平行于ωo表面的非直接漫反射的光照之和。这种cubemap被称为辐照度图(Irradiance map)。

22. 深度测试在PC端和移动端的不同?在什么阶段做,光栅化前还是之后?

  • 第一个问题不懂,也查不到。
  • 深度测试是在片元着色器之后执行的,也就是光栅化之后。但现代GPU有提前深度测试技术,在光栅化之前。

23. SSAO的原理?

对于铺屏四边形上的每一个片段,我们都会根据周边深度值计算一个遮蔽因子。这个遮蔽因子之后会被用来减少或者抵消片段的环境光照分量。遮蔽因子是通过采集片段周围球型核心(Kernel)的多个深度样本,并和当前片段深度值对比而得到的。高于片段深度值样本的个数就是我们想要的遮蔽因子。

24. 头发怎么渲染?

参考知乎收藏,暂时未研究

25. 阴影的做法?

Shadow Mapping
参考阴影映射

26. 静态光照的烘培技术了解过吗?

参考 辐射度算法

27. 光线追踪为什么会出现噪点,怎么解决?

产生噪点主要有两个原因:

  • 积分过程中光线采样不足
  • 生成入射光线样本与真实光线的分布有偏差。

在光线追踪过程中,如果能精确的求解出渲染方程,算出每个点的反射颜色,那么渲染出的图片接近真实照片,不会出现噪点。在求解方程的过程中,对于每个点反射光线的颜色是自发光颜色+反射光颜色,对于自发光部分一般为一个常数值,而反射部分则是一个半球上的积分计算。对于理想镜面反射,光线的反射只在一个方向上有值,并不需要生成很多样本去做积分运算,可以做特殊处理,但是对于漫反射部分,如果要精确的计算出结果,则需在对入射到该点的半球面上的所有光线做积分运算,而直接求解该方程的积分比较困难,在实际光线追踪应用中则是使用蒙特卡罗的方式近似求解。而在积分过程中需要采样大量的光线样本才能让积分收敛接近真实值,如果采样不足或者生成的光线样本分布与真实光线的分布存在偏差就可能会出现噪点。

如何解决噪点问题呢?
噪点是因为采样引起的,因此我们可以改进采样来降低它,分为两种方法:

  • 其中改进采样最简单有效的解决办法是提高光线采样数量,对于路径追踪来说,就是提高每个像素点随机生成的光线路径数量。但是提高采样数量一方面会增加计算时间,另一方面采样数量与噪点收敛并不成线性比例,采样数量提高到一定程度后,噪点降低的幅度变化很小。
  • 另外一种改进采样的方法是重要性采样(Importance Sampling),由于均匀采样(Uniform Sampling)生成的光线样本在各个方向上概率都相同,并不会对灯光特殊对待。在实际应用中,如果能让随机生成的光线样本有极大的概率偏向灯光的方向也可以减少噪点。为了防止对灯光的过度采样,我们还需要对采样的结果用概率密度函数(pdf-probability density function​ )做权值调整。这种非均匀采样,再对采样结果用pdf加权调整的方式叫重要性采样。

除此之外,还有一种方法是对最终生成的图像做后期处理以实现降噪,即通过降噪算法,将极低采样的光线追踪结果重建出非常接近用大量采样渲染得到的收敛后的图像。

28. 静态阴影和动态阴影怎么混合?

???

29. 光线追踪的抗锯齿怎么解决的?

增大采样率

30. 怎么渲染镜子里面的物体?

方法一:

  • 先把除了镜子外的其他物体渲染到后台缓冲区。
  • 清理模板缓冲区,整体置为零。
  • 仅将镜面渲染到模板缓冲区中。将模板测试设置为每次都成功,并且在通过测试时用1来替换模板缓冲区元素。如果深度测试失败,则模板缓冲区对应的像素保持不变。
  • 将镜子前的物体的镜像渲染到后台缓冲区及模板缓冲区中。
  • 运用透明混合技术把镜面渲染到后台缓冲区中。

方法二:

  • 把摄像机位置按镜子表面平面进行反射变换
  • 从反射的视点渲染场景至一张纹理
  • 最后把该纹理再渲染至该反射性表面上。

31. 如何求正交矩阵的逆?

正交矩阵的转置矩阵和逆矩阵相等

32. 做纹理映射的时候为什么要做透视矫正?以及如何做透视校正?

三角形面上的正确插值不是线性的,这是由于在投影平面上的相同步长随着三角形面与相机之间的距离增加而在三角形面上产生了更大的步长。图形处理器必须采用非线性插值的方法来计算纹理坐标映射,以避免纹理映射图的扭曲变形。
透视插值的公式:

33. 对顶点的法线和位置进行变换的时候有没有区别?可不可以用同一个矩阵?什么时候可以用同一个矩阵?

一般情况下,对位置进行变换的矩阵M,若要同时进行法向量变换,需要用M的逆转置矩阵。然而,当M不包含非统一缩放或者切变的时候,可以直接用M进行法向量变换。

34. 欧拉角、四元数、矩阵描述旋转的优缺点?介绍一下四元数的插值。

35. 如何判定圆形和线段是否相交?(要求用线性代数的方法)

???

36.msaa发生在什么阶段?延迟渲染为什么对msaa支持不好?

光栅化阶段。主要原因是带宽消耗太大。参考延迟渲染与MSAA的那些事

37.检测点是否在扇形之内

面试题:检测点是否在扇形之内

38. 解析顶点变换中mat4中每个元素在相应阶段的作用(左上角mat3、第四列、第四行)

MVP矩阵

39.给定平面上三个点构成三角形,然后随机获取三角形内某个点

我觉得应该是用拒绝采样的方法,先随机生成一个三角形包围盒内的点,判断在不在三角形内,在的话就保留;否则丢弃并继续生成直到求得一个在三角形内的点。

40.mipmap和LOD

LOD:当模型离摄像机(可以是人物摄像机或其他摄像机)很远时,然后根据距离的远近使用不同模型级别,远的时候就选择低级别的模型,近的时候选择高细节模型,这样就可以减少模型上面的顶点和面片数量从而提高性能。
mipmap:mipmap针对的是纹理贴图,大白话就是,一个模型身上会有贴图,当我们对这个贴图使用了MipMap技术之后,那么在游戏运行中这个模型的贴图会根据摄像机距离模型的远近而调整不同的不同质量的贴图显示。判断模型表面距离摄像机远近的原理是利用ddx和ddy函数计算UV的偏导数,根据UV变化快慢来决定mipmap级别的。参考 渲染的本质:纹理采样时如何确定正确的mipmap level

41.屏幕后处理如何实现高斯模糊

将场景渲染到一个附加到帧缓冲对象上的颜色纹理中,在像素着色器中对这张纹理进行后处理(高斯模糊),之后将在一个横跨整个屏幕的四边形上绘制这个纹理。

42.向量法求异面直线的距离

异面直线的距离

43.介绍一下你知道的光照模型

Blinn-Phong:
Ambient:

Diffuse:

Specular:

其中p是反光度。

PBR参考第20条总结

44.渲染管线中的剔除包括哪些?三维游戏场景中如何用CPU进行初步剔除不在摄像机范围内的游戏对象?

渲染管线中的剔除包括:

  • 视锥剔除(软件)
  • 基于Portal的剔除(软件)
  • Clipping&Backface Culling(硬件)

判断一个物体是否位于视锥棱台内。在实践中,由于模型往往是比较复杂的,很难精确计算它和视锥体的交集,因此一般是用轴对齐包围盒(AABB),有向包围盒(OBB)或者包围球(BSphere)代替模型本身进行相交计算。
对于复杂场景来说,线性数组的遍历方式往往不够高效,这时候也可以将场景以层次结构组织起来进行剔除(譬如QuadTree,Octree等)。
(可用BVH树。除了层次包围体,其他的空间数据结构同样也可以用于视锥裁剪,包括上文提到的八叉树和BSP树。但是当渲染动态场景时,这些方法便会显得不够灵活,不如层次包围体。)
参考 剔除:从软件到硬件
游戏开发中的渲染加速算法总结

45. 纹理映射的算法有哪些?讲一下双线性插值算法。

  • 最近点采样
  • 线性纹理过滤
  • 各向异性纹理过滤
  • 等等



利用比例t,颜色值u0,u1插值出红色点的颜色值:

46. 碰撞检测的算法

  • 分离轴定理
  • GJK算法

47. 透视变换后,为什么每个分量要除以w?

透视投影为了实现近大远小的效果,需要把坐标除深度。一般光栅化渲染管道会用齐次坐标,因此在投影矩阵里加入了这个运算,最后把齐次坐标转换回欧氏坐标(做除法)。
参考 透视除法

48. 如何避免万向节死锁?

使用四元数表示旋转?

49.背面剔除和遮挡剔除分别在渲染管线哪个阶段?

背面剔除:在图元装配阶段结束之后,根据用户指定的手向,把面向摄像机或者背对摄像机(一般是背对摄像机)的三角形剔除,剔除后的三角形就不会再进入到Pixel Shader和Rasteriaztion的流程里。

遮挡剔除:深度测试/提前深度测试的时候。

50.如何判断两个矩形相交?

相当于第17条的二维情况:
若两个 AABB 在两个维度上的区间都重叠,则两者相交。
OBB 要使用最多 8 个分离轴去判断两者是否相交。

参考
AABB碰撞检测
OBB碰撞检测
Cocos2d-x教程-三维物体OBB碰撞检测算法

51.介绍一下蒙特卡洛方法和积分的估计函数的有偏性和一致性的概念。

蒙特卡洛积分:

一般在工程实践中,面对的函数千变万化,我们很难直接计算得出某个函数的积分的解析解。为了求解函数积分的数值解,蒙特卡洛法是一种强大的积分方法。它的推导过程如下:
假设我们想去求得函数g的积分,首先根据大数定理,任意给定一个实数函数f和随机变量x~p(x),可以得到:

令g=fp,代换上式可得:

它的期望值为:

也就是说,当N取的足够大时,结果将无限逼近解析积分。
综上所述,蒙特卡洛方法是一种可以近似计算任意函数积分的数值方法。它的计算分为以下步骤:
1.对一个满足某种概率分布的随机数进行抽样
2.使用该抽样计算g(x)/p(x)的值,作为样本
3.最后对所有的样本累加求平均

用蒙特卡洛积分法求积分涉及到两个问题:1.如何对一个任意分布函数进行抽样; 2.如何减少方差
第一个问题的解决方法:逆变换算法和取舍算法
第二个问题的解决方法:重要性采样

  • 有偏性:估计量为INI_NIN​,则 B(IN)=E(IN)−IB(I_N)=E(I_N)-IB(IN​)=E(IN​)−I称为偏差。若偏差为0,则改估计是无偏估计,否则是有偏估计。蒙特卡洛估计是无偏估计。
  • 一致性:当采样数量NNN达到无穷大时,估计量INI_NIN​收敛到III的概率为1,则该估计具有一致性。

理论上我们比较青睐无偏估计,它使整个估计过程中随机量的分布都以真实值为中心,结果永远是正确的。但无偏估计不应该引入更大的方差,否则我们需要更大的代价去消除由于方差导致的错误(例如噪点)。

参考《全局光照技术》第4章

52.介绍一下MSAA的原理

MSAA即多重采样反走样(multisample antialiasing)。技术原理:

53.知道Alpha Blend和Alpha Test吗?

  • Alpha test是指在fragment shader 里通过判断alpha是否满足一定的条件从而来决定是否discard该fragment,不满足条件的fragment就被discard,不能通过alpha test。
  • Alpha blend是指通过alpha通道来混合两个或多个物体的颜色,通常用来渲染半透明的物体,如透过玻璃窗看风景。Alpha blend会打开GL_BLEND,然后通过blend相关的OpenGL ES API来控制blend的方式,从而实现将color buffer中的颜色与当前渲染的fragment颜色混合!

54.PBR的金属度和粗糙度的区别是什么?比如说粗糙度一样,金属度分别为0和1,他们的表现有什么区别?

光与物体表面进行交互分为两种方式:光泽反射和漫反射。对于非金属材质,光泽反射的RGB分量是一样的,即它不会改变入射光的颜色,仅改变其亮度,因此光泽反射反映的是光源本身,几乎与物体表面的真实颜色无关。而漫反射部分指的是光折射进物体内部,在物体内部经历一定的散射后重新从表面散射回原介质中。所以我们说的物体表面“真实颜色”其实是一个反射率,它表明在其他光照在表面进行漫反射时,在每个方向上的反射率是多少。

PBR有4个材质参数,介绍如下:

  • Base Color:物体在白色光照下表面的真实颜色。
  • Roughness:材质的粗糙度。越粗糙,入射光越向更多方向反射,物体表面越来越接近Base Color的颜色。越光滑,物体表面越多地反射周围的环境。Roughness为0形成镜面反射。
  • Metallic:纯净的物体,要么该参数为0,要么为1。金属会将折射进物体表面的光全部吸收,从而使金属材质将不会有光从表面内部再散射出来,因此金属材质没有漫反射部分。
  • Specular:入射光垂直于表面时菲涅尔反射率的值,用在Schlick近似计算菲涅尔反射比中。

以上摘自《全局光照技术》

根据光照中metallic的用途,我的看法如下:金属度会影响Specular的值,金属的Specular更大,也就是反射率更大。所以粗糙度相同时,比如粗糙度为0,那么金属更能看清楚周围环境,当然此时非金属也能看到周围环境,因为粗糙度为0。

55.HDR里面的tonemapping简单介绍一下。为什么要用tonemapping,不用的话有什么问题?

HDR渲染和其很相似,我们允许用更大范围的颜色值渲染从而获取大范围的黑暗与明亮的场景细节,最后将所有HDR值转换成在[0.0, 1.0]范围的LDR(Low Dynamic Range,低动态范围)。转换HDR值到LDR值得过程叫做色调映射(Tone Mapping)。
在实时渲染中,HDR不仅允许我们超过LDR的范围[0.0, 1.0]与保留更多的细节,同时还让我们能够根据光源的真实强度指定它的强度。比如太阳有比闪光灯之类的东西更高的强度,那么我们为什么不这样子设置呢?(比如说设置一个10.0的漫亮度) 这允许我们用更现实的光照参数恰当地配置一个场景的光照,而这在LDR渲染中是不能实现的,因为他们会被上限约束在1.0。因为显示器只能显示在0.0到1.0范围之内的颜色,我们肯定要做一些转换从而使得当前的HDR颜色值符合显示器的范围。

56.Shader里面如何计算ddx和ddy,描述一下这两个函数的原理

在光栅化的时刻,GPUs会在同一时刻并行运行很多Fragment Shader,但是并不是一个pixel一个pixel去执行的,而是将其组织在2x2的一组pixels分块中,去并行执行。而偏导数就正好是计算的这一块像素中的变化率。从上图可以看出来ddx 就是右边的像素块的值减去左边像素块的值,而ddy就是下面像素块的值减去上面像素块的值。其中的x,y代表的是屏幕坐标。

参考 Unity shader 中ddx/ddy偏导数的原理和简单应用

57.射线与球体相交检测

  • 参数方程法
  • 优化法

参考 射线与球的相交测试

58.光照计算为什么必须在线性空间中进行?伽马校正怎么做?

  • 光照计算必须在线性空间中进行的原因:shader中计算光照的时候,光照公式都默认是在线性空间中进行的。(这是我的看法)
  • 对于在非线性空间中的贴图,需要将其值做一个反 Gamma 校正(即 Gamma 次方),得到一个线性的值,再用于 Shader的计算。但是对于本身已经是线性空间的贴图,比如某些 HDR 光照图、法线贴图、高度凹凸贴图或者任何非颜色值的贴图,则都不要使用反Gamma 校正。对于非线性空间的贴图,尽可能存为 sRBG 格式,对于校正效率更高、更省事,还能得到正确的反锯齿效果。
  • 最终输出的值在用于显示之前,需要做一个 Gamma 校正(即 1/gamma 次方)。使用 sRBG 格式的FrameBuffer,则可以自动地在硬件级别做这个处理,而且可以有正确的 Blending 值。

参考 论线性颜色空间的重要性

59.屏幕上的像素点反算出世界空间中的坐标的计算方法

假如我们在后处理shader中能够拿到一个像素的归一化坐标即NDC坐标(包括深度),并且得知裁剪空间中点的齐次坐标的w分量,那就可以一步一步反推出世界坐标:先将NDC坐标乘以w转换到裁剪空间,再乘以投影矩阵的逆转换回相机空间,最后再乘以世界坐标系到相机坐标系的转换矩阵的逆——也就是相机坐标系到世界坐标系的转换矩阵,就反推出了世界坐标。
不过实际在Unity的后处理shader中,我们往往只能拿到像素的归一化坐标,拿不到w。因此我们要用另外的办法。一般我们在后处理shader中,能拿到的是裁剪空间的坐标x,y,z,屏幕的高宽,以及相机的near,far和FieldofView(FOV)。有了这些信息,我们就有办法将屏幕坐标直接变换到相机空间的坐标,而无需得知w和投影矩阵的逆。
参考 在Unity的后处理shader中通过屏幕像素坐标和深度贴图反推世界坐标

图形学/OpenGL/3D数学/Unity相关推荐

  1. 关于计算机图形学的3d数学

    三维坐标系(3D Coordinate System) 三维坐标是把二维的平面坐标推广到三维空间中,在三维坐标中,点(x,y,z)的齐次坐标为(nx,ny,nz,n),其中n为任意不为0的数,规范化的 ...

  2. Unity 3D数学\图形学基础-游戏开发(向量)

    Unity 3D数学\图形学基础-游戏开发(向量) 向量运算的几何意义 标量与向量的计算 向量的模长 标准化向量 normalize 0向量 向量与向量的加减法 两点间距离公式(向量间距离) 点积,点 ...

  3. 计算机图形学——OpenGL学习系列之绘制3D下的小桌子

    计算机图形学--OpenGL学习系列之绘制3D下的小桌子 做的一个小练习,主要用到了几何变换还有gl自带的一个绘制立方体的函数,顺便体会一下glPush和glPop的用法.另外,从2D到3D,开心到飞 ...

  4. A Crash Course in 3D Graphics Math(令人吐血的3D图形学里的数学)

    周一到周五,每天一篇,北京时间早上7点准时更新~ First, we do not pretend here that we will cover everything that is importa ...

  5. 3D数学-裁剪空间与透视投影矩阵的推导

    3D数学-裁剪空间与透视投影矩阵的推导 透视投影矩阵的变换本质,是将视锥体变换到裁剪空间中 视锥体的具有六个面,近裁剪面,远裁剪面,左裁剪面,右裁剪面,上裁剪面,下裁剪面 所有超出视锥体的都会被舍弃, ...

  6. 3D数学读书笔记——笛卡尔坐标系统

    本系列文章由birdlove1987编写,转载请注明出处. 文章链接: http://blog.csdn.net/zhurui_idea/article/details/24601215 1.3D数学 ...

  7. 《3D数学基础》提炼总结(一)3D数学和笛卡尔坐标系

    写在前面,想学好图形学,数学是必不可少的,市面上想找一本书既包括数学知识又与图形学和编程连续紧密的,这本书算是名气较大的,再加上很多语言比较通俗幽默,读起来不那么想睡觉,所以就是它啦(#^.^#).当 ...

  8. Unity3D for VR 学习(6): 再次温故知新-3D数学

    一年前,系统学习过3D数学,并记录了一篇博客<C#程序员整理的Unity 3D笔记(十):Unity3D的位移.旋转的3D数学模型>. 一年后,再次温习之. 坐标系:Unity3D使用左手 ...

  9. OpenGL: 3D坐标到屏幕坐标的转换逻辑(gluProject的实现)(转)

    OpenGL: 3D坐标到屏幕坐标的转换逻辑(gluProject的实现) 遇到需要将3D坐标转换到屏幕坐标的问题,在网上很多朋友也在寻找答案,下面是glu中gluProject函数的实现.(实际上就 ...

最新文章

  1. 【知识积累】JavaMail实现发邮件功能
  2. python 动态修改 类和实例 的方法
  3. maven dependency中scope=compile 和 provided区别
  4. 漫画:删去k个数字后的最小值
  5. efishell无法开机shell_开机出现efi shell卡住不动了解决方法全集
  6. 坑爹的水题之“元芳你怎么看”
  7. 软件测试模型-其他模型(W模型|H模型|X模型)
  8. 等级考试(三):三级网络---似曾相识(续)
  9. 如何在 Mac 上阻止 FaceTime 通话和 iMessage 信息?
  10. EEGLAB及其插件下载安装
  11. linux文本编辑器英文名,科学网—带格式的文本编辑器Typora 之介绍 - 丁祥欢的博文...
  12. outlook 您的组织策略阻止我们为您完成此操作
  13. 服务企业互联网化 打造社会化商业平台
  14. 字体小三、小四号字的数字表示是多少
  15. 5G在智慧农业中的实践和探索
  16. http://www.cnblogs.com/Jackie-zhang/p/6071769.html
  17. 软文营销如何自我激励创造巨大价值
  18. 计算机的四个发展阶段的应用,计算机分为哪四个发展阶段
  19. Java微信公众号高级 微信墙,JAVA折腾微信公众平台(Token验证)
  20. DJL初学者学习笔记(一):Java启动DJL控制台打印No matching cuda flavor for win found: cu65并且在线下载dll文件解决方案

热门文章

  1. new open SQL ABAP语法错误,逗号和转义符变量 when escaped, all host variables must be escaped using@
  2. oracle查询员工表领导级别,emp表中怎么统计每个员工的领导的年薪,并按年薪由高到低排列...
  3. 工信部新规本月底施行 未经用户同意发送商业短信将被罚款
  4. 物联网控制APP入门专题(五)---使用android studio直接编写物联网控制APP
  5. Ubuntu18如何下载微信和qq
  6. 数据中台建设的价值及数据中台架构
  7. 电子商务:说说转化率
  8. Hive使用必知必会系列
  9. 蓝桥杯单片机——串口通信1(11)
  10. win10 EFI文件夹删除了,引导进不去了,该怎么办?