[Yugong シリーズ] 2023.08 WEBGL トピック - 2D 特殊効果 - グラフィック リング


序文

ドーナツ チャートは、さまざまなセクターに分割された円形または半円形のチャートであり、各セクターがデータの一部を表します。このタイプのグラフは、特に市場シェアや人口統計データなど、データの相対的な割合やパーセンテージを示すためによく使用されます。ドーナツ グラフは通常円グラフの形で作成されますが、中央に余分な穴があるため、「ドーナツ グラフ」とも呼ばれます。

1.グラフィックリング

1. 距離関数の解析

距離関数は、2 次元空間内の 2 点間のユークリッド距離を計算します。この特定のケースでは、現在のフラグメント座標 (gl_PointCoord によって与えられる) と点 (0.5,0.5) の間の距離を計算するために使用されます。

これは、中心からセグメントの距離を目的の半径と比較することで、セグメントが指定された半径の内側にあるか外側にあるかを判断できるため、円形またはリング形状を作成する場合に便利です。WebGL では、この計算を使用して、リングやディスクなどの円形または円形の形状を描画するフラグメント シェーダーを作成できます。

GLSL ES は、対応する組み込み変数解析を提供します。

  • gl_FragCoord はフラグメントのウィンドウ座標を表します
  • gl_PointCoord は、描画された点内のフラグメントの座標を示します (範囲 [0.0, 1.0])

ここに画像の説明を挿入

2. 2D/3D空間上の2点間の距離

1.二次元

2 次元空間では、2 点 (x1, y1) と (x2, y2) 間のユークリッド距離は次の式で計算できます。

distance = sqrt((x2 - x1)^2 + (y2 - y1)^2)

ここで、sqrt は平方根表記を表します。この式は次のように書くこともできます。

distance = sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2))

このうち、pow関数はべき乗演算を表し、pow(a,b)はaのb乗に等しい。

2. 3 次元
3 次元空間では、2 点( x 1 , y 1 , z 1 ) (x_1, y_1, z_1)( ×1y1z1)( x 2 , y 2 , z 2 ) (x_2, y_2, z_2)( ×2y2z2)は、次の式を使用して計算できます。

d = ( x 2 − x 1 ) 2 + ( y 2 − y 1 ) 2 + ( z 2 − z 1 ) 2 d = \sqrt{(x_2 - x_1)^2 + (y_2 - y_1)^2 + ( z_2 - z_1)^2}d=( ×2バツ1)2+( y2y1)2+( z2z1)2

その中で、ddd は2 点間の距離を表します。

3. ケース

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <script src="../lib/index.js"></script>
</head>
<body>
<canvas id="canvas" width="400" height="400">
  此浏览器不支持canvas
</canvas>
</body>
</html>
<script>

  const ctx = document.getElementById('canvas')

  const gl = ctx.getContext('webgl')

  // 创建着色器源码
  const VERTEX_SHADER_SOURCE = `
    void main() {
      gl_Position = vec4(0.0,0.0,0.0,1.0);
      gl_PointSize = 200.0;
    }
  `; // 顶点着色器

  const FRAGMENT_SHADER_SOURCE = `
    precision lowp float;

    // float distanceSelf(vec3 a, vec3 b) {
    //   float x = a.x - b.x;
    //   float y = a.y - b.y;
    //   float z = a.z - b.z;
    //
    //   float v = x * x + y * y + z * z;
    //
    //   return sqrt(v);
    // }

    float distanceSelf(vec2 a, vec2 b) {
      float x = a.x - b.x;
      float y = a.y - b.y;

      float v = x * x + y * y;

      return sqrt(v);
    }

    void main() {
      // 计算距离
      // float dis = distance(gl_PointCoord, vec2(0.5,0.5));
      float dis = distanceSelf(gl_PointCoord, vec2(0.5,0.5));

      if (dis > 0.5 || (dis < 0.4 && dis > 0.3) || dis < 0.2) {
        discard;
      }
      gl_FragColor = vec4(1.0,0.0,0.0,1.0);
    }
  `; // 片元着色器

  const program = initShader(gl, VERTEX_SHADER_SOURCE, FRAGMENT_SHADER_SOURCE)

  gl.drawArrays(gl.POINTS, 0, 1);
</script>

ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/aa2528877987/article/details/132166747