ラベル GLSL の投稿を表示しています。 すべての投稿を表示
ラベル GLSL の投稿を表示しています。 すべての投稿を表示

2012年3月8日木曜日

Quartz Composer / GLSL Shader / BokehなFragment Shaderを生成するコード

参考
  • THE ART-LOG OF MARTINS UPITIS: a GLSL depth of field filter with bokeh
  • GLSL depth of field with bokeh v2.4 (update)


  • コード
    参考のコード他をよくわからないまま弄くり回していました.
    とりあえずサンプリングする点を求めるのにコードにしたのでそれをメモしておきます.

    #include <stdio.h>
    #include <stdlib.h>
    double *cross(double *p, double *q) {
    double *r;
    r= (double *)malloc(3*sizeof(double));
    r[0]= p[1]*q[2]-p[2]*q[1];
    r[1]=-p[0]*q[2]+p[2]*q[0];
    r[2]= p[0]*q[1]-p[1]*q[0];
    return r;
    }
    double *sub(double *p, double *q) {
    double *r;
    r= (double *)malloc(3*sizeof(double));
    r[0]= p[0]-q[0];
    r[1]= p[1]-q[1];
    r[2]= p[2]-q[2];
    return r;
    }
    int isinCircle(double *q) {
    return (q[0]*q[0]+q[1]*q[1]<0.25)?1:0;
    }
    int isin6(double *q)
    {
    double p[6][3]= {
    { 0.0, 0.50, 0.},
    { 0.5, 0.25, 0.},
    { 0.5,-0.25, 0.},
    { 0.0,-0.50, 0.},
    {-0.5,-0.25, 0.},
    {-0.5, 0.25, 0.}};
    double *r;
    int i, c= 0;

    for(i= 0; i<5; i++) {
    r= cross(sub(p[i], q), sub(p[i+1], q));
    c+= r[2]<0?0:1;
    }
    r= cross(sub(p[5], q), sub(p[0], q));
    c+= r[2]<0?0:1;

    return (c==0)?1:0;
    }
    int main(int argc, char* argv[]) {

    double q[3]= {0., 0., 0.};
    int j,k,c= 0;
    int r= 5;

    printf("uniform sampler2D RenderedTexture;\nuniform sampler2D DepthTexture;\n");
    printf("const float blurclamp = 1.;\nconst float bias = 10.;\nuniform float focus;\n");
    printf("uniform float pixelsWide;\nuniform float pixelsHigh;\n");
    printf("vec2 texcel = vec2(1./pixelsWide, 1./pixelsHigh);\n");
    printf("void main()\n{\n");
    printf("\tvec4 depth = texture2D(DepthTexture,gl_TexCoord[0].xy );\n");
    printf("\tfloat factor = ( depth.x - focus );\n");
    printf("\tvec2 dofblur = vec2 (clamp( factor * bias, -blurclamp, blurclamp ));\n");
    printf("\tvec4 col = vec4(0.0);\n");

    for(k= -r; k<r; k++) {
    for(j= -r; j<r; j++) {
    q[0]= k/(r*2.);
    q[1]= j/(r*2.);
    if (isin6(q)==1) {
    if (0) {
    printf("\tcol += texture2D(RenderedTexture, gl_TexCoord[0].xy + (vec2(");
    printf("%2d., %2d.", k, j);
    printf(")*texcel) * dofblur);\n");
    }
    else {
    printf("\tcol.r += texture2D(RenderedTexture, gl_TexCoord[0].xy + (vec2(");
    printf("%2d., %2d.", k, j);
    printf(")*texcel) * dofblur*vec2( .000, .50)).r;\n");
    printf("\tcol.g += texture2D(RenderedTexture, gl_TexCoord[0].xy + (vec2(");
    printf("%2d., %2d.", k, j);
    printf(")*texcel) * dofblur*vec2( .866,-.25)).g;\n");
    printf("\tcol.b += texture2D(RenderedTexture, gl_TexCoord[0].xy + (vec2(");
    printf("%2d., %2d.", k, j);
    printf(")*texcel) * dofblur*vec2(-.866,-.25)).b;\n");
    }
    c++;
    }
    }
    }

    printf("\tgl_FragColor = col/%d.;\n\tgl_FragColor.a = 1.0;\n}\n", c);
    return 0;
    }



    結果
    こんな感じ.

    2012年3月1日木曜日

    Quartz Composer / GLSL Shader / 凸多角形の内外判定

    参考
    外積の使い方 - Tari Lari Run


    やってみた

    //Fragment Shader
    uniform sampler2D texture;

    void main()
    {
    vec3 q= vec3(gl_TexCoord[0].xy+vec2(-0.5,-0.5), 0.);

    int n= 6;
    vec3 p[6];
    //反時計回りの定義
    p[0]= vec3( 0.0, 0.50, 0.);
    p[1]= vec3( 0.5, 0.25, 0.);
    p[2]= vec3( 0.5, -0.25, 0.);
    p[3]= vec3( 0.0, -0.50, 0.);
    p[4]= vec3(-0.5, -0.25, 0.);
    p[5]= vec3(-0.5, 0.25, 0.);

    int c= 0;
    for(int i=0; i<n; i++) {
    c+= cross(p[i]-q, p[(i+1)%n]-q).z>0.?0:1; //pが時計回りなら z>0?1:0
    }

    gl_FragColor = (c==n)?vec4(0):vec4(1);
    gl_FragColor.a= 1.;
    }

  • Vertex Shader側はQuartz ComposerのGLSL Shaderのデフォルトのまま
  • Shader内はGLSL Gridを置いてある


  • 結果

    (多角形の頂点を0.9倍して余白をつくってある)

    2011年11月15日火曜日

    Quartz Composer / Crosshatch shader をやってみた (あとiPod CMを思い出して)

    動機
    @yone80さんがPOSTした こちらの記事を参考にGLSL Shader パッチでやってみた.


    結果


    iPod CM
    で,ふと古いiPod CMを思い出してMMD_DM_Renderパッチに白黒反転したこのGLSL Shaderパッチをかぶせてみた.




    pmd: 'Lat式ミクVer2.3_Normal.pmd'(Lat様)('VPVP wiki - モデルデータ/VOCALOID関連'より),
    vmd: '恋愛サーキュレーション-ミク.vmd'(せっけんP様)('VPVP wiki - モーションデータ/ダンス'より)
    感謝 )
    ※Clickすると拡大します.

    っぽい?

    2011年6月22日水曜日

    Quartz Composer / Fragment Shader(GLSL Shaderパッチ)をいじってみた

    動機:
    nobokoさんこのpostをみてこちらの動画(FORTUNE - Staring At The Ice Melt (album teaser BULLY))を見て,「GLSL ShaderパッチのFragment Shaderでそれっぽくできないかしら?」と思いちょっとやってみた.


    やってみた:
    Fragment Shaderのコードとしてはこんなかんじ.
    Vertex Shaderはそのまま.
    uniform sampler2D texture;
    uniform float i;
    uniform float direction;
    void main()
    {
    vec4 c= texture2D(texture, gl_TexCoord[0].xy);

    if (direction<0.5) {
    if (i > gl_TexCoord[0].x) {
    c= texture2D(texture, vec2(i, gl_TexCoord[0].y));
    }
    }
    else {
    if (i > gl_TexCoord[0].y) {
    c= texture2D(texture, vec2(gl_TexCoord[0].x, i));
    }
    }
    gl_FragColor= c;
    }


    float iは0-1の間の値
    float directionは0.5を境界に縦と横の切り替え(boolでよかったのでは…。)


    結果:
    っぽい?

    2011年4月18日月曜日

    Quartz Composer / Projection Mapping的なことをやってみたい

    動機
    これとかこれとかがTumblrで流れてきて面白そうだなぁ…ってなってあれこれ調べてみてたらこの記事を発見した.
    で,GLSLでできるらしいのでやってみた.


    結果


    • GLSL ShaderのVertex側プログラムは参考の通り, Fragment側はデフォルトをそのまま.
    • GLSL Shaderの中にはWidth, Heightをともに2にしたSpriteを入れておく.ついでにDepth testingもNone.
    • GLSL ShaderのrenderSizeは一応Width, Heightともに2にしといた.
    • BL, BR, TL, TRは描画領域内を0〜1までで与える.


    ちなみにmix関数は'mix(x, y, a)= x*(1.0-a)+y*a'らしい(a=0.0でx, a=1.0でy, a=0.0→1.0でmix=x→yってこと).

    2011年2月17日木曜日

    OpenGL Shader Builder / 「GLSLシェーダによるカートゥーンレンダリング」をやってみた

    動機
    こちらの記事をみつける.OpenGL Shader Builderってあったなぁって思い出す.これでやれば簡単に試せるのかしら?と思う.


    やってみた
    0.同サイトのサンプルをDownloadし,展開する.
    1.cartoon.fsをダブルクリックすることで,'OpenGL Shader Builder'が立ち上がり,cartoon.fsがGL_FRAGMENT_SHADERとしてプログラムに登録される.
    2.cartoon.vsは中にある日本語コメント部がどうもうまく処理されないらしいのでテキストエディタ等で削除して保存する.ダブルクリックでGL_VERTEX_SHADERとして登録される.

    3.toon.bmpをPreview等で開き,黒い部分が上側,濃い色が左側にくるように修正し(垂直方向に反転)保存する.その後OpenGL Shader BuilderのTexturesタブの0番目にDrag&Dropで登録する.またWrapの設定を'CLAMP_TO_EDGE'に変更する.

    4.OpenGL Shader BuilderのRenderタブで'Tours'を選択し,トーラスをDragでグリグリ動かす.気が向いたら'Clear Color'を変えてみる.


    結果


    参考
    GLSLシェーダによるカートゥーンレンダリング / ArakinのGLSLを使ったOpenGLプログラム
    感謝

    2011年1月27日木曜日

    Quartz Composer / GLSLでボロノイ図(力技)

    追記(2011/1/28 3):



    追記(2011/1/28 2):









    追記(2011/1/28): 距離を求めるのにdistance関数というのがあるらしいので修正してみた.

    やってみた
    こんな感じでパッチ用意.


    GLSL Shaderの中にはSpriteを一つ入れておく(デフォルトのまま).


    でGLSL ShaderのInspector/Settingで以下のようにVertex, Fragment Shaderを設定.
    Vertex Shader

    varying vec4 p;
    void main()
    {
    gl_Position = gl_Vertex;
    p = gl_Vertex;
    }


    Fragment Shader

    vec3 red= vec3(1.0,0.0,0.0);
    vec3 green= vec3(0.0,1.0,0.0);
    vec3 blue= vec3(0.0,0.0,1.0);

    vec2 p1= vec2(-1.0, -1.0);
    vec2 p2= vec2( 1.0, -1.0);
    vec2 p3= vec2(-1.0, 1.0);

    varying vec4 p;
    void main() {
    //float r1= ((p.x-p1.x)*(p.x-p1.x))+((p.y-p1.y)*(p.y-p1.y));
    //float r2= ((p.x-p2.x)*(p.x-p2.x))+((p.y-p2.y)*(p.y-p2.y));
    //float r3= ((p.x-p3.x)*(p.x-p3.x))+((p.y-p3.y)*(p.y-p3.y));
    float r1= distance(p.xy, p1);
    float r2= distance(p.xy, p2);
    float r3= distance(p.xy, p3);


    vec3 color;
    if (r1<r2 && r1<r3)
    color= red;
    else if (r2<r1 && r2<r3)
    color= green;
    else
    color= blue;

    gl_FragColor = vec4(color, 1.0);
    }



    結果


    別の例
    vec2 p1= vec2(-0.5, -0.5);
    vec2 p2= vec2( 0.0, 0.0);
    vec2 p3= vec2( 0.5, 0.5);



    参考
    4KBプロシージャルGFX入門講座 2時限目 感謝