前言
我们之前提到过——坐标修正的概念。但只是一笔带过。今天我们来详细了解下坐标修正。话不多说,直接开始。
什么是坐标修正
我们在前面文章的 shader 编写中,都进行了坐标修正。即以下代码:
vec2 uv =fragCoord/iResolution.xy; //坐标除以画布大小得到归一化uv坐标
// uv 居中
uv=(uv*2.)-1.0;
uv.x*=iResolution.x/iResolution.y; // 修正uv坐标未自动适应画布比例的问题
从代码中,我们不难看出,我们进行了以下操作:
- 得到 uv 坐标,uv 坐标的范围为[0-1]
- 将 uv 坐标系的原点移到中心点
- 修正坐标系的比例
所以,我们可以知道,坐标修正即是对坐标系进行以上三个步骤。
详解坐标修正
我们接下来详细解释下,为何上述三步可以达到坐标修正的目的?
uv 坐标
uv 坐标:输入坐标fragCoord除以画布大小iResolution.xy,我们就能得到一个归一化的坐标,把它命名为uv,所以,我们使用 vec2 uv =fragCoord/iResolution.xy;可以得到我们的 uv 坐标,x,y 的范围都在[0,1]之间。
以下为 uv 坐标可视化的图片:
原点居中
我们先来看原点未居中的 uv 的图片:
再来看看我们原点居中了的 uv 的图片:
为何uv=(uv*2.)-1.0能实现原点居中的效果呢?我们来仔细分析下:
uv*2.0——我们的 uv 范围变成了[0,2](uv*2.)-1.0——我们的 uv 范围变成了[-1,1],这时候,我们的原点在(0,0)点,并且(0,0)点为中心点
画布比例修正
画布比例修正:uv.x*=iResolution.x/iResolution.y;,是三步中相对最难理解的点。我将会画图解释,希望讲解清楚。
我们为什么要进行画布比列修正呢?
当我们在一个16:9的屏幕上使用 shader 绘制一个圆:
为什么会这样呢?——这是因为我们画布的宽高不相等,所以,我们x轴和y轴上的一个单位代表的长度不一样
我们可以看到,取相同刻度,x轴上长度大于y轴上长度,所以,我们画出来的圆会是一个椭圆。
那我们怎么得到一个圆呢?——uv.x*=iResolution.x/iResolution.y;
为什么这样做就可以得到一个圆呢?
-
在宽屏情况下,iResolution.x/iResolution.y > 1
-
uv.x*=iResolution.x/iResolution.y;——使得uv.x变大了,x轴上每个刻度代表的值变大了,即:r=0.5,之前我在x轴上取0.5需要两个刻度,现在我可能就只需要1个刻度。这样就使得我们的图形比例跟y轴保持一致了。
我们可以看到,蓝色的刻度便是原来代表(1,0)和(-1,0)的刻度,现在它们已经是(2,0)和(-2,0)了。这样我们取r=0.5,便只需要之前的1/4个刻度了便可以了。x轴上的图案便被按照相应比例缩小了。
总结
以上便是坐标修正的全部内容了,如有错误之处,欢迎大家留言指出,谢谢大家了。