のぐそんブログ

暗いおじさんがシコシコ書くブログです。

GLSLのstep()を使っての矩形の描き方

閾値を超えたら1.0を返し、超えなかったら0.0を返すstep関数を使って矩形を描画してみたいと思います。

ポイントは2点です。 1. 1つの矩形をつくるために2つの矩形の値を掛け合わせる 2. 二つ目の矩形は基準点を右上にもってくる為1から座標を引く

↑の画像が見づらい場合はこちら

void main( void ) {

    vec2 st = gl_FragCoord.xy /min(resolution.x,resolution.y);          
    vec2 p1 = step(vec2(0.2,0.2),st);
    vec2 p2 = step(vec2(0.2,0.2),1.0 - st);
    
    float c1 = p1.x * p1.y;
    float c2 = p2.x * p2.y;
    
    vec3 color = vec3(c1 * c2);
 
    gl_FragColor = vec4(color,1.0);

}

矩形描画処理を関数にしてみる

矩形の描画処理を関数にして、複数の矩形を描いてみます。 上の例では、右上の座標を指定する際に、右上を基準点としましたが、 指定がわかりずらいので、基準点は左下に統一使用とおもいます。

float drow(vec2 st, float l , float b, float r, float t){
    vec2 p1 = step(vec2(l,b),st);
    //右上の指定方法がわかりやすいように指定したx,y座標も1.0から引数を引くようにする
    vec2 p2 = step(vec2(1.0 - r,1.0 - t),1.0 - st);
    
    float c1 = p1.x * p1.y;
    float c2 = p2.x * p2.y;
    
    return c1 * c2;
}


void main( void ) {

    vec2 st = gl_FragCoord.xy /min(resolution.x,resolution.y);
            
    float c1 = drow(st,0.1,0.1,0.2,0.2);
    float c2 = drow(st,0.15,0.15,0.4,0.4);
    
    vec3 color = vec3(c1);
     color += vec3(c2,0.0,0.0);
 
    gl_FragColor = vec4(color,1.0);

}

基準点を中心にしてみる

中心の基準点をもってくる場合は、1.0から引く代わりに、縦横比から引くようにするとうまくいきました。

vec2 ratio =  resolution/min(resolution.x,resolution.y);

float drow(vec2 st, float l , float b, float r, float t){
    vec2 p1 = step(vec2(l,b),st);

    vec2 p2 = step(vec2( ratio.x - r,ratio.y - t), ratio - st);
    
    float c1 = p1.x * p1.y;
    float c2 = p2.x * p2.y;
    
    return c1 * c2;
}


void main( void ) {

    vec2 st = (gl_FragCoord.xy * 2.0 -  resolution)/min(resolution.x,resolution.y);
            
    float c1 = drow(st,-1.0 ,-1.0,0.0,0.0);

    
    vec3 color = vec3(c1);

 
    gl_FragColor = vec4(color,1.0);

}

左上を基準点として高さ、幅を指定して矩形を描画する

より直感てきに位置指定する為幅と高さを指定できるようにしてみる。

f:id:nogson2:20171104115810p:plain

void main( void ) {

    vec2 st = gl_FragCoord.xy /min(resolution.x,resolution.y);
    
    float top = 0.1;
    float left = 0.1;
    float height = 0.2;
    float width = 0.2;
    
    float l = step(left,st.x);
    float b = step(1.0 - top - height,st.y);
    float r = step(1.0-(left + width), 1.0-st.x);
    float t = step(top, 1.0-st.y);
    
    float c = l * b * r * t;
    
    vec3 color = vec3(c);
     //color += vec3(c2,0.0,0.0);
 
    gl_FragColor = vec4(color,1.0);

}

lengthをつかって矩形を描く

f:id:nogson2:20171106155753p:plain

void main( void ) {
    vec2 st = (gl_FragCoord.xy * 2.0 - resolution) / min(resolution.x, resolution.y);
    vec4 col = vec4(0);
    
    //座標の絶対値が0.5以下の場合は0.0にする
    vec2 c = max(abs(st ) - 0.5,0.0);
    
    //座標の距離を切り上げ 0.0以外の値は1.0になる
    float d = length(c);
    d = ceil(d);    
    gl_FragColor = vec4(d);
}

f:id:nogson2:20171106160601p:plain

参考

↓がすごくわかりやすいです。

GLSLでモンドリアン風 | Superpeachman