Depth的精度问题分析

翻译:谢帅shawn

原文:Depth Precision Visualized By Nathan Reed, posted Jul 15 2015 at 03:54PM

Depth precision is a pain in the ass that every graphics programmer has to struggle with sooner or later. Many articles and papers have been written on the topic, and a variety of different depth buffer formats and setups are found across different games, engines, and devices.

Depth的精度是图形开发者迟早要面对的痛点。很多文章讨论过这个问题,不同的游戏,引擎,设备中也有多种不同的Depth缓存格式和设置。

图1

Because of the way it interacts with perspective projection, GPU hardware depth mapping is a little recondite and studying the equations may not make things immediately obvious. To get an intuition for how it works, it’s helpful to draw some pictures.

由于它与透视投影相互作用的方式,GPU硬件的深度映射变得有点深奥,单纯阅读公式并不能一目了然。 为了直观地了解它的工作原理,本文会借助一些图表。

This article has three main parts. In the first part, I try to provide some motivation for nonlinear depth mapping. Second, I present some diagrams to help understand how nonlinear depth mapping works in different situations, intuitively and visually. The third part is a discussion and reproduction of the main results of Tightening the Precision of Perspective Rendering by Paul Upchurch and Mathieu Desbrun (2012), concerning the effects of floating-point roundoff error on depth precision.

本文主要有三个部分。 在第一部分中,我尝试解释一些非线性深度映射的基本原理。 其次,我绘制了一些图表,以帮助直观理解非线性深度映射如何在不同情况下工作。 第三部分是Paul Upchurch和Mathieu Desbrun(2012)关于提高透视渲染精度的主要结果的讨论和实现,其中涉及浮点取整误差对深度精度的影响。

Read More

Cook-Torrance 微表面光照框架

之前的文章中,我们介绍了非常简单的ADS光照模型。

但是实际应用中,它有几个缺点:

  • 通过参数设置出来的光经常会很假
  • 高光效果不够理想
  • 环境贴图效果不够真实

当你出现如上几个问题,说明你对材质的真实度要求已经很高了。这个时候,你可能需要重新理解光照。这里我们尝试引入PBR能量守恒的概念,然后使用一套新的光照框架来解决上面的问题,叫做 Cook-Torrance 微表面光照框架。

Read More

WebGL中的纹理各向异性过滤

翻译:谢帅shawn

原文链接-TojiCode-Anisotropic Filtering in WebGL

首先展示一个简单的示例.

未使用纹理过滤

这个示例虽然简陋但是很好地展示了效果。如果您对这个概念不熟悉,这里简单解释一下。各向异性过滤(Anisotropic Filtering)是标准mip-mapping技术的一个扩展,用于优化在非正交视角下材质的显示效果。如上例中演示的地板和天花板。通过标准的三线形过滤(gl.LINEAR_MIPMAP_LINEAR)离摄像机越远的部分就变得越来越模糊。

使用三线性过滤后

通过使用各向异性过滤,我们更改了在这些特殊场景下mipmaps的采样方式(译者:采样窗口有可能为非标准的矩形甚至平行四边形等等),从而使图像更加清晰。

使用各向异性过滤后

开启这个功能将带来一些性能损失,当您开启它的时候,您可以权衡设置采样数。这是在PC游戏中非常常见的一个设置,所以现在我们能在web上使用它是非常好的。

实现

在支持它的浏览器中使用它非常简单,与其它WebGL扩展一样,我们首先查询它看是否可用:

1
var ext = gl.getExtension(“MOZ_EXT_texture_filter_anisotropic”);

显然,如果使用Chrome,您应该使用WEBKIT而不是MOZ的前缀。如果它返回null,则说明浏览器不支持此功能,我们将很不幸地继续在模糊的墙壁中间生活(译者:好吧,这句是个笑话~~)。反之,如果支持,它将返回一个这个扩展的枚举对象。

然后我们将像设置纹理双线/三线性过滤或者纹理Wrap模式一样,在每个纹理中设置它,需要用到新的扩展标识符:

1
gl.texParameterf(gl.TEXTURE_2D,ext.TEXTURE_MAX_ANISOTROPY_EXT,4);

这里,我们对纹理对象启用了4x过滤(演示中使用的值)。将其设置为1将会关闭此功能,并且您的显卡决定了这个数值的上限。您可以这样查询显卡的支持:

1
var max_anisotropy = gl.getParameter(ext.MAX_TEXTURE_MAX_ANISOTROPY_EXT);

所以,就像我说的,这个是个简单的API,却可以大幅度提高渲染质量。

参考:

纹理过滤模式中的Bilinear、Trilinear以及Anistropic Filtering

ADS光照模型

ADS光照模型是经典模型,光照计算基于简单的经验公式,普遍应用至今。

BPR( Based Physical Render ),基于物理的渲染。光照基本遵照物理公式。效果逼真,但性能差一些,桌面端游戏已大规模应用,目前发展迅速。随着移动端硬件性能的提高,很多移动端甚至WebGL渲染器也开始应用BPR技术。three.js中实现了PhysicShader,Egret-3d中也实现了近似的PhysicShader模型(FakePBRPass),还没有仔细研究。

Read More

摄像机与视图矩阵

3D渲染管线中,一般会对顶点坐标进行一系列变换,将三维坐标投影到屏幕空间上。过程中用到了三个矩阵,也就是我们常说的PVM矩阵。

  • 模型矩阵(ModelMatrix),将顶点坐标从局部坐标转换到世界坐标。
  • 视图矩阵(ViewMatrix),将顶点坐标从世界坐标转换到相机坐标。
  • 透视矩阵(ProjectionMatrix),将顶点坐标从相机坐标转换到2D屏幕坐标。
1
PVMMatrix = ProjectionMatrix * ViewMatrix * ModelMatrix;

Read More

WebGL中的Alpha与混色

混色

要想实现直觉上的透明颜色,混色的数学原理如下:

1
2
3
4
// 源颜色指的是我们要绘制的颜色
// 目标颜色指的是当前位置颜色缓冲区中的颜色
// 结果颜色 = 源颜色 * 源alpha + 目标颜色 * (1 - 目标alpha)
color = sColor.rgb * sColor.a + dColor.rbg * (1 - sColor.a);

实际上,我们的计算机就是通过这种方式来绘制透明图形的。

这里有个小误区,很多人认为gl标准混色为

gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);

其实是不对的,正确的应该是:

gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA)

因为在经验公式中,a通道并不需要取均值!

在很多3D引擎中,往往会在材质导入的时候就进行预乘处理。

Read More

着色器实现描边效果

无尽之剑场景

网上流传着很多炫酷的着色器。着色器的代码往往很高效。但是,阅读着色器代码(GLSL)却很困难。(所谓神奇不过是,它做了很多事情而你又不理解它而已)

着色器代码为什么不好阅读呢:一是着色器代码中往往充斥着数学计算与公式;二是读者往往不了解着色器处理图片的原理。

有关着色器的原理,让我们先进行一个思想实验。

Read More

WebGL的最佳实践

翻译:谢帅shawn

原文链接-Mozila开发者文档-WebGL_best_practices

本文提供的建议和技巧可以用来提高的WebGL的表现。遵循这些建议可以使您的Web程序的兼容更多的设备和浏览器,并且提高性能。

需要避免的事情

  • 你应该确保程序运行中不产生任何WebGL报错(这些报错是通过getError()捕获的)。在Firefox的默认设置下,WebGL报错将在控制台中产生一个特殊的JavaScript警告。建议你打开webgl.verbose偏好设置。设置webgl.verbose将使每一个WebGL的错误,和其他一些WebGL的问题,合并为一个带有描述的JavaScript警告消息。你应该不想让一大波报错喷涌到控制台吧?当然。
  • 不应该在WebGL的着色器使用#ifdef GL_ES语句;尽管一些早期的例子中这样做了,不过这是没有必要的。
  • 除非你真的需要这么做,否则不要显式设置片段着色器的精度为highp。试着用mediump精度。使用highp精度的片段着色器可能导致你的程序在最新的手机硬件上不工作。从Firefox 11开始,webgl.getShaderPrecisionFormat()方法可以用来检查硬件对highp精度的支持,并且输出当前平台所有能支持的精度。

Read More

在游戏引擎中的JS性能优化

author: @谢帅shawn

优化的适用范围

最近在做游戏引擎性能优化,关于js执行性能有些内容拿来这里分享。

首先需要明确两点:

第一,本文讨论的js性能问题,都是在大量执行的情况下才暴露出来的。一般来说,60fps的游戏,如果每帧需要执行2000次以上,那么就可以考虑本文的优化思路了。如果执行频次没有达到以上量级,性能并不会有明显提升。

第二,得到的这些性能红利在某些情况下需要牺牲代码结构与可读性,考虑在实际项目中是否值得。很多时候,需要牺牲一点点性能来使你的代码更容易维护。切忌对项目过度优化。

Read More

通过ColorTransform滤镜实现的昼夜交替效果

author: @谢帅shawn

2D场景的3D展现

游戏是视觉艺术,好的游戏总是能给我们带来视觉上的震撼。而光与影是游戏视觉的两把利器。但是,大部分2D游戏开发者不擅于开发光影效果,或者说,大部分2D游戏开发工具并不会很好地提供相关的功能。

未来,2D游戏将不仅局限于2D技术。2D只是一种表现形式,而不应该被技术所限制。就像今天的像素游戏是为了像素而像素一样,未来的游戏选择2D只是选择一种表达方式,至于特效与视觉后期处理,3D技术将成为不可或缺的必要补充。

Alto's Adventure

游戏《Alto’s Adventure》中,大量运用了高级的光影效果。虽然该游戏是2D表现形式,但3D引擎(Unity)的出色表现为游戏的最终效果贡献不少。

Read More