Shader #7 : 正三角形

f:id:zonu_a0:20210603011102p:plain

Shadertoy

www.shadertoy.com

ソースコード

Image

{
    // 画面の中心
    vec2 center = iResolution.xy * 0.5;
    
    // ピクセルの座標
    vec2 pixel = fragCoord.xy;
    
    // 正三角形の高さ
    float height = 0.7 * iResolution.y;
    
    // √3
    float sqrt3 = sqrt(3.0);
    
    // 一辺の長さ
    float edgeLen = height * (2.0 / sqrt3);
    
    // 正三角形の底辺の中点
    vec2 bottomMidpt = center - vec2(0.0, height / 2.0);
    
    // 中心からピクセルまでの差分ベクトル
    vec2 diff = pixel - bottomMidpt;
    
    //  正三角形の各辺の内側か判定
    float insideA = step(diff.x + diff.y / sqrt3, edgeLen / 2.0);
    float insideB = step(-diff.x + diff.y / sqrt3, edgeLen / 2.0);
    float insideC = step(bottomMidpt.y, pixel.y);
    
    //  正三角形内かを判定
    float inside = insideA * insideB * insideC;
    
    // ピクセルの色を設定
    fragColor = vec4(inside, inside, inside, 1.0);
}

解説

    // 画面の中心
    vec2 center = iResolution.xy * 0.5;
    
    // ピクセルの座標
    vec2 pixel = fragCoord.xy;
    
    // 正三角形の高さ
    float height = 0.7 * iResolution.y;
  • コメントのまま
  • 正三角形の高さ = 画面の高さの70%
    // √3
    float sqrt3 = sqrt(3.0);
    
    // 一辺の長さ
    float edgeLen = height * (2.0 / sqrt3);

  • 一辺の長さは 高さ * (2 / √3) で求められる
    // 正三角形の底辺の中点
    vec2 bottomMidpt = center - vec2(0.0, height / 2.0);
    
    // bottomMidptを原点としたピクセル座標
    vec2 diff = pixel - bottomMidpt;

  • 図にすると上のような感じ
  • diffbottomMidptを原点とした座標
    //  正三角形の各辺の内側か判定
    float insideA = step(diff.x + diff.y / sqrt3, edgeLen / 2.0);
    float insideB = step(-diff.x + diff.y / sqrt3, edgeLen / 2.0);
    float insideC = step(bottomMidpt.y, pixel.y);
    
    //  正三角形内かを判定
    float inside = insideA * insideB * insideC;

  • insideA = 辺Aより内側なら1、外側なら0
    • (edgeLen / 2.0, 0), (0, (edgeLen / 2.0) * √3) の2点間の線分が辺Aの境界
  • inside = すべての辺の内側(正三角形内)なら1になる
    // ピクセルの色を設定
    fragColor = vec4(inside, inside, inside, 1.0);