OpenGL Shader-矩形绘制

669 阅读2分钟

「这是我参与2022首次更文挑战的第4天,活动详情查看:2022首次更文挑战

绘制矩形

在了解如何绘制圆之后对于如何绘制矩形除了实现公式不同外基本上是类似的。

矩形的公式如下所示,x表示宽,y表示高,r表示边长:

max(abs(x),abs(y)) = 4

根据上述公式可得绘制正方形结果。 image.png

宽高变化

如果期望实现长方形的绘制结果可以在宽或者高上增加减参数,例如abs(x)-4

max(abs(x) - 4,abs(y)) = 4

如上公式修改x轴后abs(x)-4矩形的宽变成8,实现了长方形矩阵绘制结果。 image.png

位移变化

若希望对矩形做位移变化则在abs函数内部对x或y做处理,例如x轴减8操作abs(x - 8)

max(abs(x - 8) - 4,abs(y - 4)) = 4

对x轴和y轴做操作后会发现矩形绘制起点位移到了(0,0)坐标点。 image.png

综上所述实现了矩形的绘制,宽高设置、位移变化基本操作,再者继续学习如何对矩形做旋转操作。

矩阵旋转

了解矩阵旋转之前先回顾勾股定理:

正弦函数

sinA = a / c

image.png

余弦函数

cosA = b / c

image.png

接下来推导矩阵旋转公式,在二维坐标系中旋转是绕着某一个点进行旋转。最常见的场景是绕着坐标系原点旋转。

image.png

  1. 当点v绕原点旋转θ角,得到点v’。
  2. 点v坐标是(x,y),点v’坐标是(x’,y’)。
  3. 原点坐标到点v距离是r,点v向量与x轴夹角是ϕ
  4. 可得出x=rcosϕ,y=rsinϕ;x’=rcos(θ+ϕ),y’=rsin(θ+ϕ)。
  5. 根据三角函数推导出x’=rcosθcosϕ-rsinθsinϕ,y’=rsinθcosϕ+r*cosθsinϕ。
  6. 然后带入x和y的表达式最终推导出x’=xcosθ-ysinθ,y’=xsinθr*ycosθ。

用矩阵表示如下所示:

xy\begin{vmatrix} x’ \\ y’ \end{vmatrix} = cosθsinθsinθcosθ\begin{vmatrix} cosθ & -sinθ \\ sinθ & cosθ \end{vmatrix} * xy\begin{vmatrix} x \\ y \end{vmatrix}

再转换成在glsl中的函数就是 mat2(cos(th),sin(th),-sin(th),cos(th)) * uvmat2是二维矩阵,uvx,y坐标。具体的选择代码如下所示。将需要的旋转角度带入到方法函数rotate得到旋转之后的向量再套用矩阵函数绘制矩阵图像。

// 旋转函数
vec2 rotate(vec2 uv,float th){
    return mat2(cos(th),sin(th),-sin(th),cos(th)) * uv;
}
vec3 sdfSquare(vec2 uv, float size) {
  float x = uv.x;
  float y = uv.y;
  vec2 rotated = rotate(vec2(x,y), iTime);
  float d = max(abs(rotated.x), abs(rotated.y)) - size;
  
  return d > 0. ? vec3(0.) : vec3(1., 0., 0.);
}
无角度旋转角度
image.pngimage.png

参考