最終更新:
mikk_ni3_92 2009年12月10日(木) 19:21:28履歴
現在地:メニュー >> Cg >> Cg編02 >> Cg編02::頂点シェーダの記述
次:Cg編02::フラグメントシェーダの記述
シェーダはまず頂点シェーダが最初。
基本は、
『頂点に関するデータ(位置、法線、色など)を受け取って何らかの処理をして出力する』
ということである。
例えばCPUのプログラムで
【例】:vertex.cg
【解説】
頂点データが来るたびに「CgVetexMain関数」へやってくる。
これは、入力データ構造と出力データ構造を定義して、
出力データ構造に値をコピーし「VertexOut型」をリターンしただけのプログラムである。
CgVertexMain関数の引数部分に「in」と付いているが、これは『入力である』という事を明示的に書いているだけ。
省略する事も可能。省略すると「in」と判断される。
入力データ構造、出力データ構造には変数宣言の他に、「 : POSITION」などのような表記がある。
これは属性を示すものであり、そのメンバが何なのかをあらわす。
例えば「float2 positon」は「2要素もつfloat型」だが、それが頂点座標か、色なのかはわからない。
そこで、属性として「 : POSITION」を書いて、Cgに頂点座標であることを伝えている。
頂点シェーダから出力されたものは、フラグメントシェーダの入力となる。
フラグメントシェーダでは、ピクセル単位での処理を行っていく。
その時にラスタライズ化、補間処理がある。
従って、出力としては座標属性「POSITION」が必要である。
基本的にはC言語風。C言語よりも柔軟な記述ができる。
上に書いた例のように、構造体を定義して出力データに値を設定、リターンする方法に加え、
関数の引数に明示的に出力を記述する事も可能。
その場合は「out」と書けばよい。
【例1】
あるいは、構造体ではなくデータそのものを引数にしてもよい。
【例2】
さらには、構造体のメンバにまとめてアクセスすることも可能。
【例3】
次:Cg編02::フラグメントシェーダの記述
次:Cg編02::フラグメントシェーダの記述
シェーダはまず頂点シェーダが最初。
基本は、
『頂点に関するデータ(位置、法線、色など)を受け取って何らかの処理をして出力する』
ということである。
例えばCPUのプログラムで
glColor3f(0,1,0); glBegin(GL_TRIANGLES); glVertex2f(-0.8, 0.8); glVertex2f(0.8, 0.8); glVertex2f(0.0, -0.8); glEnd();と書いてあり、頂点シェーダのプログラムでは次のように書いたとする。
【例】:vertex.cg
//入力頂点
struct VertexIn
{
float2 position : POSITION;
float3 color : COLOR;
};
//出力頂点
struct VertexOut
{
float4 position : POSITION;
float3 color : COLOR;
};
//-------- 頂点シェーダメイン関数 ---------//
VertexOut CgVertexMain(in VertexIn input)
{
VertexOut output;//出力用
output.position = float4(input.position.x,input.position.y,0,1);//位置
output.color = input.color;//色
return output;//フラグメントシェーダへ
}
【解説】
頂点データが来るたびに「CgVetexMain関数」へやってくる。
これは、入力データ構造と出力データ構造を定義して、
出力データ構造に値をコピーし「VertexOut型」をリターンしただけのプログラムである。
CgVertexMain関数の引数部分に「in」と付いているが、これは『入力である』という事を明示的に書いているだけ。
省略する事も可能。省略すると「in」と判断される。
入力データ構造、出力データ構造には変数宣言の他に、「 : POSITION」などのような表記がある。
これは属性を示すものであり、そのメンバが何なのかをあらわす。
例えば「float2 positon」は「2要素もつfloat型」だが、それが頂点座標か、色なのかはわからない。
そこで、属性として「 : POSITION」を書いて、Cgに頂点座標であることを伝えている。
頂点シェーダから出力されたものは、フラグメントシェーダの入力となる。
フラグメントシェーダでは、ピクセル単位での処理を行っていく。
その時にラスタライズ化、補間処理がある。
従って、出力としては座標属性「POSITION」が必要である。
基本的にはC言語風。C言語よりも柔軟な記述ができる。
上に書いた例のように、構造体を定義して出力データに値を設定、リターンする方法に加え、
関数の引数に明示的に出力を記述する事も可能。
その場合は「out」と書けばよい。
【例1】
void CgVertexMain(in VertexIn input, out VertexOut output)
{
output.position = float4(input.position.x,input.position.y,0,1);//位置
output.color = input.color;//色
}
あるいは、構造体ではなくデータそのものを引数にしてもよい。
【例2】
void CgVertexMain(in float2 positionIn : POSITION,in float3 colorIn : COLOR,
out float4 positionOut : POSITION,out float3 colorOut : COLOR)
{
positionOut = float4(positionIn.x,positionIn.y,0,1);//位置
colorOut = colorIn;//色
}
さらには、構造体のメンバにまとめてアクセスすることも可能。
【例3】
output.position = float4(input.position.xy,0,1);//位置「.xy」でxとyをまとめてアクセス output.color = input.color.rgb;//色(rgb)まとめてアクセス
次:Cg編02::フラグメントシェーダの記述

