シェーダーのパターンメモ


任意の関数y=f(x)

k = y-f(x)とすると、描きたい関数周辺つまり、y-f(x) = 0付近に関して値が0に近づくので、これをstep関数で区切ってやれば良い。正規化もしくはサイズ調整には、y軸方向はf(x)→f(x)/2と変更することや、x軸方向はx→2*xとすることで対応可能。

"void main(){",
        "vec2 st = gl_FragCoord.xy*2.0/resolution.xy-1.0;",
        "float fx = abs(st.y-pow(st.x*2.0,3.0)-2.0*pow(st.x*2.0,2.0)+1.0);",
        "gl_FragColor = vec4(vec3(step(0.02,fx)),1.0);",
        "}"

任意の極座標関数

極座標関数は、r = distance(st,vec2(0,0))、theta = atan(st.y,st.x)とすることで取得した値を元にy=f(x)と同様に記述する。このときglslのatanはst.x = 0のときの例外処理を行っていないので、ここを対応する必要がある。(参考→https://qiita.com/7CIT/items/ad76cfa6771641951d31)

拡大縮小に関してはかなりめんどくさいが、基本的にrに関して縮小すれば良いと思うので、r = f(theta)と記述できるときはf(theta)→f(theta)/2とかすればいいと思う。それ以外の形状の関数はどうしよう。

また、極座標は-1〜1の範囲の座標系で描画したいので0-1の座標系を変換するための関数を用意しておくと楽かもしれない。

        "void main(){",
        "vec2 st = gl_FragCoord.xy*2.0/resolution.xy-1.0;",
        "float r = distance(st,vec2(0.0,0.0));",
        "float theta = atan2(st.y,st.x)+pi;",
        "float k = r-(1.0*(1.0+cos(theta))/2.0);",
        "k = 1.0-k;",
        "gl_FragColor = vec4(vec3(step(1.0,k)),1.0);",
        "}"

二次元シェーダを升目上に増やす。

0-1座標系に対して、それを何倍かしfractを使って小数以下を取ることで座標系を複製する。

void main(){
vec2 st = gl_FragCoord.xy/resolution.xy;
st = st*2.0-1.0;
st = fract(st);
st = to_cent(st);
float r = distance(st,vec2(0.0,0.0));
float theta = atan2(st.y,st.x)+pi;
gl_FragColor = vec4(vec3(distance(st,vec2(0.0,0.0))),1.0);
}