Sky's blog

Cross Browser Tracking Summary Part-2

字数统计: 2,758阅读时长: 10 min
2018/12/20 Share
1
文章首发于先知 https://xz.aliyun.com/t/3722

前言

本篇文章主要讲解模型和参数选择部分知识,下一篇文章将讲述相关代码实现。

Task(a)-纹理

简单来说即测试片段着色器中的常规纹理特征。
具体来说,即将经典的Suzanne模型在随机生成纹理的画布上呈现。纹理大小为256×256的正方形,通过随机选择每个像素的颜色来创建,即我们在一个像素的三个基色(红色,绿色和蓝色)之间产生0~255的三个随机值,将三个基色混合在一起,并将其用作像素的颜色。

之所以选择这个随机生成的纹理,是因为这个纹理比常规纹理具有更多的指纹特征。原因如下,当片段着色器将纹理映射到模型时,片段着色器需要在纹理中插入点,以便将纹理映射到模型上的每个点。插入值算法在不同的显卡中是不同的,当纹理变化很大时,差异就被放大。因此,我们需要生成在每对相邻像素之间颜色变化很大的这种纹理。
相关模块为:

1
this.testList.push(new TextureTest(this.susanVertices, this.susanIndices, this.susanTexCoords, this.texture));

运行情况


(后续文章将解释这个262144的数组)

Task(b)-渐变

简单来说即测试片段着色器在画布上的渐变特征。
具体来说,不同的渐变颜色被画在一个正方体模型的六个面上,每个面上的4个顶点都作为颜色的出发点,例如下图

并且尽量选择这些渐变颜色来扩大每个面上的色彩之间的差异,例如某个面的一个顶点上蓝色比例非常大(0.9/1),那么另一个顶点的蓝色比例就必须非常少(0.1/1),相应的拥有更多的红色和绿色
相关模块为

1
this.testList.push(new CubeTest('normal'));

运行情况如下

Task(b’)-抗锯齿与渐变

简单来说即测试抗锯齿特征,换句话来说,即测试浏览器如何让模型边缘更加光滑
这里使用与Task(B)相同的方式,并且加入抗锯齿。如果进一步测试,将会发现模型的每个边缘都被柔化

相关模块如下

1
this.testList.push(new CubeTest('aa'));

运行情况如下


和前一张对面,边缘的确有显著的柔化

Task(c)-camera

简单来说即测试投影特性,换句话说,即一个输入片段着色器的投影矩阵
所有的配置信息都与任务一致,除了camera的被移动到了新的位置[-1,-4,-10],得到的立方体比Task(b)更小,因为camera被移动的离立方体更远
相关模块如下

1
this.testList.push(new CameraTest());

运行情况如下

Task(d)-直线与曲线

简单来说即测试直线和曲线。 在画布上绘制一条曲线和三条不同角度的直线。
具体来说,曲线遵循以下公式:

1
y = 256-100cos(2.0πx/ 100.0)+ 30cos(4.0πx/ 100.0)+ 6cos(6.0πx/ 100.0)

其中[0,0]为画布的左上角,x轴向右增加,y轴增加到底部。
三条直线的起点和终点是
{[38.4,115.2],[89.6,204.8]}{[89.6,89.6],[153.6,204.8]}{[166.4,89.6],[217.6,204.8]}
选择这些特定的线条和曲线,以便测试不同的渐变和形状。
相关模块如下

1
this.testList.push(new LineTest('normal'));

运行情况如下

Task(d’)-抗锯齿与直线与曲线

即在Task(d)中加入了抗锯齿
相关模块如下

1
this.testList.push(new LineTest('aa'));

不难发现边缘显著得到柔化

Task(e)-多重模型

简单来说即测试多个不同的模型在同一个画布上如何相互影响
除了Suzanne模型,这里引入了另一种模型:看起来像一个人倚靠在沙发上,称之为sofa模型,我们将两个模型平行放置,并同样对sofa模型用Task(a)中的随机生成的纹理进行着色
相关模块如下

1
this.testList.push(new TextureTest(this.combinedVertices, this.combinedIndices, this.combinedTexCoords, this.texture));

运行情况如下

Task(f)-光线

简单来说即测试漫射点光和Suzanne模型的相互作用。 漫射点光在照亮物体时会引起漫反射。 具体地说,该光是在RGB上具有相同值的白色,对于每种原色,光的功率为2,光源位于[3.0,-4.0,-2.0]

在这个任务中选择一个白光源,因为纹理是各种颜色的,单色光可能会减少纹理上的一些微妙差异。 光线的强度需要精心设计。非常弱的光线不会照亮Suzanne模型,模型就会不可见;非常强的光会使一切变白,减少指纹特征。 在6台机器的小规模实验中,功率从0增加到255,我们发现当光功率为2时,这些机器之间的像素差异最大。并且光照位置可随机选择,不会影响特征指纹识别结果。
相关模块如下

1
this.testList.push(new SimpleLightTest(this.susanVertices, this.susanIndices, this.susanTexCoords, this.susanNormals, this.texture));

运行情况如下

Task(g)-光线与模型

简单来说即测试漫射点光和Suzanne模型与sofa模型的相互作用
因为当某个点的被光照时,一个模型可能会在另一个模型上产生阴影
这个任务中所有的光线配置与Task(f)一致,并且模型与Task(e)一致

相关模块如下

1
this.testList.push(new SimpleLightTest(this.combinedVertices, this.combinedIndices, this.combinedTexCoords, this.combinedNormals, this.texture));

运行情况如下

Task(h)-镜面光

简单来说即测试另一种色彩的漫射点光与镜面点光对2个模型的作用
与漫射点光相似,镜面点光将会导致照射对象的镜面反射,两束光源都位于[0.8,-0.8,-0.8]
漫射点光的RGB为[0.75,0.75,1.0],镜面点光的RGB为[0.8,0.8,0.8]

这里有两件事值得注意。其一,我们选择了一个特殊的camera位置,其距离模型很近,并且有更大的影响,尤其是当sofa模型后部被镜面点光照射时。其二,虽然漫射点光是偏蓝色的,但是它依旧含有不少红色与绿色,我们想要测试其他颜色的光线,但是最后发现,在纹理是彩色的时候,白光依旧是最好的,它能获取到最多的指纹特征

相关代码如下,这里进行了多重测试,例如加入抗锯齿,再加入90度旋转,所以得到3组数据

1
this.testList.push(new MoreLightTest(this.combinedVertices, this.combinedIndices, this.combinedTexCoords, this.combinedNormals, this.texture));

运行情况如下

Task(i)-双纹理

简单来说即测试对同一对象进行不同的纹理覆盖会有什么影响
我们生成另一种随机的纹理对Suzanne和sofa模型进行覆盖

相关代码

1
this.testList.push(new TwoTexturesMoreLightTest(this.combinedVertices, this.combinedIndices, this.combinedTexCoords, this.combinedNormals, this.texture, this.texture1));

运行情况如下

Task(j)-Alpha

该任务由8个子任务组成,即测试不同alpha值的影响
我们将Suzanne和sofa模型平行放置,并且从我们精心设置的alpha值集合{0.09,0.1,011,0.39,0.4,0.41,0.79,1}中选择alpha值,其中0表示完全透明,1表示完全不透明。
此时又有两点值得注意,其一,我们精心选择了3个变化不大的值,去反应不同alpha值带来的变化:{0.1,0.4,0.8},并且值以0.01的速度变化,因为GUPs不能接受更小的步长。其二,因为Suzanne和sofa模型的放置,他们有一部分是重叠的,所以当模型变得透明时,sofa模型被隐藏的部分变得可见。
相关代码如下

1
this.testList.push(new TransparentTest(this.combinedVertices, this.combinedIndices, this.combinedTexCoords, this.combinedNormals, this.texture));

运行情况,因为我们选择了8种alpha值集合,所以得到8组数据

Task(k)-复合光

测试复合光特性,例如反射光,移动光,追踪光
特别的,我们生成了5000个金属环模型,并以随机的角度将他们放置在地面上,同时堆叠在一起。为了稳定性,我们选择了一个随机数种子用来生成随机数,这样测试即可被重复在不同的浏览器和机器上。两束射向底部的光源,分别是黄色和红色,其一直在整个场景的右上角旋转。当光线照射到金属环的下方,其他的环同时也会被反射光照射,此时两种颜色的光混合在一起。
注意,这里我们使用单色光源,因为模型不是彩色的,这样做可以为我们提供更多的相互影响的细节
相关代码

1
this.testList.push(new LightingTest());

运行情况,在第二组里加入了抗锯齿,所以得到了两组数据

更多渲染任务

Task(l)-切面

相关模块为:

1
this.testList.push(new ClippingTest());

运行情况

Task(m)-立方体纹理和菲涅尔效应

相关代码如下

1
this.testList.push(new BubbleTest());

运行情况

Task(n/o)-DDS与PVR纹理

相关代码

1
this.testList.push(new CompressedTextureTest());

运行情况如下,因为有2种纹理(DDS与PVR纹理),所以得到2组数据


Task(p)-浮点纹理

运行情况如下

Task(r)-字符集

为了获取浏览器支持的字符集列表,例如拉丁语,中文或是阿拉伯语。因为目前没有浏览器提供接口去获取其支持的字符集,于是我们想到了一个侧信道的方式去探测,方法如下:
每一种字符集都会被浏览器进行渲染,如果该字符集被支持,那么浏览器就会渲染成功。否则,如果字符集不被支持,那么就会渲染出方块。如下图:

我们容易知道在这个被测试的浏览器中,我们容易知道,Javanese,Sudanese,Lontara和Thaana不被支持

后记

可以看到这些任务深入研究了图片渲染引擎的特征,js没办法直接获取到显卡的设置和驱动,但是通过这种方法,当不同的显卡渲染同一张图片时,因设置不同,渲染出来的图片hash也不同。用这种图片hash作为特征,其实是从侧面得到机器显卡的特征,同一台机器在不同的浏览器上用到同一个显卡,所以可以看到这些task的跨浏览器稳定性都很高,总共10余种task。

点击赞赏二维码,您的支持将鼓励我继续创作!
CATALOG
  1. 1. 前言
  2. 2. Task(a)-纹理
  3. 3. Task(b)-渐变
    1. 3.1. Task(b’)-抗锯齿与渐变
  4. 4. Task(c)-camera
  5. 5. Task(d)-直线与曲线
    1. 5.1. Task(d’)-抗锯齿与直线与曲线
  6. 6. Task(e)-多重模型
  7. 7. Task(f)-光线
  8. 8. Task(g)-光线与模型
  9. 9. Task(h)-镜面光
  10. 10. Task(i)-双纹理
  11. 11. Task(j)-Alpha
  12. 12. Task(k)-复合光
  13. 13. 更多渲染任务
    1. 13.1. Task(l)-切面
    2. 13.2. Task(m)-立方体纹理和菲涅尔效应
    3. 13.3. Task(n/o)-DDS与PVR纹理
    4. 13.4. Task(p)-浮点纹理
  14. 14. Task(r)-字符集
  15. 15. 后记