最終更新: mikk_ni3_92 2010年02月26日(金) 17:32:56履歴
現在地:メニュー >> Cg >> Cg編08
Index :Cg編07<< Cg編08 >> Cg編09
フラグメントシェーダはピクセル単位の処理である。
従って、画像処理もできる。
例えばグレイスケール画像への変換は次のようになる。
【例】:fragment.cg グレースケール変換
表示する時は平行投影を使う。
そして、描画の時はウィンドウのサイズに合わせた矩形を描画すればよい。
【例】:表示させる
【例】:vertex.cg
【例】:fragment.cg
Index :Cg編07<< Cg編08 >> Cg編09
フラグメントシェーダはピクセル単位の処理である。
従って、画像処理もできる。
例えばグレイスケール画像への変換は次のようになる。
【例】:fragment.cg グレースケール変換
//フラグメントの入力 struct FragmentIn { float4 position : POSITION; //ラスタライズ用(使用しない) float3 color : COLOR; … … }; //フラグメントの出力 struct FragmentOut { float3 color : COLOR; }; //--------- フラグメントシェーダメイン関数 ------------// FragmentOut CgFragmentMain(in FragmentIn input, … …) { FragmentOut output;//フラグメント出力 float gray = dot(input.color.xyz, float3(0.299, 0.587, 0.114)); output.color = float3(gray,gray,gray); return output; }
- Cg編08::まとめ1(グレイスケール変換)
表示する時は平行投影を使う。
そして、描画の時はウィンドウのサイズに合わせた矩形を描画すればよい。
【例】:表示させる
//画像サイズ情報 struct ImageSizeInfo { int w; int h; }; ImageSizeInfo imgInfo; … … void reshape(int w, int h) { glutReshapeWindow(imgInfo.w,imgInfo.h);//画像サイズにウィンドウを合わせる glViewport(0, 0, imgInfo.w,imgInfo.h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0,imgInfo.w,0,imgInfo.h);//平行投影 glMatrixMode(GL_MODELVIEW); } … … glBegin(GL_QUADS); glTexCoord2f(0.f,0.f); glVertex2f(0.f,0.f); glTexCoord2f(1,0.f); glVertex2f(imgInfo.w,0.f); glTexCoord2f(1, 1); glVertex2f(imgInfo.w, imgInfo.h); glTexCoord2f(0.f, 1); glVertex2f(0.f, imgInfo.h); glEnd(); … …
【例】:vertex.cg
//入力頂点 struct VertexIn { float4 position : POSITION; float2 texcoord : TEXCOORD0; }; //出力頂点 struct VertexOut { float4 position : POSITION; float2 texcoord : TEXCOORD0; }; //-------- 頂点シェーダメイン関数 ---------// VertexOut CgVertexMain(in VertexIn input,uniform float4x4 modelViewProj) { VertexOut output;//出力用 output.position = mul(modelViewProj, input.position); output.texcoord = input.texcoord; return output; }▲投影変換する+テクスチャ座標をわたす
【例】:fragment.cg
//フラグメントの入力 struct FragmentIn { float4 position : POSITION; //ラスタライズ用(使用しない) float2 texcoord : TEXCOORD0; }; //フラグメントの出力 struct FragmentOut { float3 color : COLOR; }; //--------- フラグメントシェーダメイン関数 ------------// FragmentOut CgFragmentMain(in FragmentIn input, uniform sampler2D decal : TEX0)//TEX0でも可 { FragmentOut output;//フラグメント出力 output.color = tex2D(decal,input.texcoord); return output; }▲「tex2D関数」でテクセルを拾えばよい
基本的に平行投影。
違いは、テクスチャ座標の指定方法。画像のサイズをそのまま対応付けることができる。
違いは、テクスチャ座標の指定方法。画像のサイズをそのまま対応付けることができる。
glBegin(GL_QUADS); glTexCoord2f(0.f,0.f); glVertex2f(0.f,0.f); glTexCoord2f(imgInfo.w,0.f); glVertex2f(imgInfo.w,0.f); glTexCoord2f(imgInfo.w, imgInfo.h); glVertex2f(imgInfo.w, imgInfo.h); glTexCoord2f(0.f, imgInfo.h); glVertex2f(0.f, imgInfo.h); glEnd();
頂点シェーダはかわらない。
フラグメントシェーダは「texRECT関数」でテクセル値をとってくる。
【例】:fragment.cg
フラグメントシェーダは「texRECT関数」でテクセル値をとってくる。
【例】:fragment.cg
//フラグメントの入力 struct FragmentIn { float4 position : POSITION; //ラスタライズ用(使用しない) float2 texcoord : TEXCOORD0; }; //フラグメントの出力 struct FragmentOut { float3 color : COLOR; }; //--------- フラグメントシェーダメイン関数 ------------// FragmentOut CgFragmentMain(in FragmentIn input, uniform samplerRECT decal : TEX0)//TEX0でも可 { FragmentOut output;//フラグメント出力 output.color = texRECT(decal,input.texcoord); return output; }
【例】:fragment.cg
【例】:main.cpp
//フラグメントの入力 struct FragmentIn { float4 position : POSITION; //ラスタライズ用(使用しない) float2 texcoord : TEXCOORD0; }; //フラグメントの出力 struct FragmentOut { float3 color : COLOR; }; //--------- フラグメントシェーダメイン関数 ------------// FragmentOut CgFragmentMain(in FragmentIn input, uniform samplerRECT decal : TEX0, uniform half Kernels[9]) { FragmentOut output;//フラグメント出力 int k=0; for(int y = -1; y < 2; ++y) { for(int x = -1; x < 2; ++x) { output.color += texRECT(decal,input.texcoord + half2(y,x)) * Kernels[k]; ++k; } } return output; }
【例】:main.cpp
CGparameter CgFragmentKernel;//フィルタ用カーネル float kernelData[9]={-1,-1,-1, -1,9,-1, -1,-1,-1};//係数(鮮鋭化フィルタ) //名前の関連付けと値設定 CgFragmentKernel = cgGetNamedParameter(CgFragmentProgram, "Kernels"); cgGLSetParameterArray1f(CgFragmentKernel,0,0,kernelData);//配列データを渡す