■ Profile.別性能表
DESC
Profile とは Graphics 命令セットの種類のこと
C, C++ で Target Machine を指定するのと同じ
Cg Compiler にこの Hardware 用に Compile しろというのと同じ
WARNING
GPU によって利用できる命令セット, インストラクション数に限界がある
コンパイルができても Load で失敗する可能性がある
// foo.fsh(133) : error C5051: profile does not support conditional returns
cgc -arbfp1 foo.fsh
// vertex shader は tex2D 命令は support しない
// foo.fsh(176) : error C3004: function "tex2D" not supported in this profile
cgc -arbvp1 foo.fsh
■ 行列の積(mul)
POINT
Cg の mul は次の順番で処理される。
mul( m, v ) は以下の計算結果になる。
m00 m01 m02 vx m00*vx + m01*vy + m02*vz
m10 m11 m12 vy == m10*vx + m11*vy + m12*vz
m20 m21 m22 vz m20*vx + m21*vy + m22*vz
WARNING
// 可換ではない
mul( v, m ) != mul( m, v )
// Fragment Shader で確認できる
float3x3 m = {
{ 1, 1, 1 },
{ 0, 0, 0 },
{ 0, 0, 0 },
};
{
float3x3 m = {
{ 1, 0, 0 },
{ 1, 0, 0 },
{ 1, 0, 0 },
};
// 結果は白 ( 1, 1, 1 )になる。
return float4( mul( m, float3(1,1,1) ), 1 );
}
行列の変換がよく理解できなくなるため, 正解をかいておく
Application::Mtx -> transpose -> Mul( mtx, vtx );
Model -> World -> View -> Projection
mul(m, IN.pos) mul(v, posW) mul( p, posV )
法線の変換
POINT
N, T の関係から N の変換行列を求める。
T の変換は 位置の変換と同じ処理をする
N.T = 0;
Nw.Tw = Nw . (W*Tl) = (Wt * Nw) . Tl
(a)bc (Nx) (Tl)
(a)bc (Ny) = (Tl)
(a)bc (Nz) (Tl)
Nw . ( W[0].Tx, W[1].Ty, W[2].Tz )
( Nx, Ny, Nz ) . ( W[0].Tx, W[1].Ty, W[2].Tz )
Nx には W[0] の成分がかかるから
左から 行列をかけるときは 転置して W[0] を縦に配置する
Wt*Nw = Nl が成り立つ ( )
// 転置の逆行列
Nw = (Wt)-1 * Nl
■ shader.コツ
Constant Register 数に気をつける
Matrix の積ではなく, dot ( 内積 )で代用する
命令数に気をつける
■ SYNTAX
POINT
global 変数として定義しても良い。
この方が, 関数の引数よりもテストしやすいので利用すること
// インクルード
#include "common.h"
// global として定義
uniform float scl = 1;
float4 main(
// 仮引数として定義
uniform float scl;
)
マクロも使える
// #define
#define LIGHT_NUM 7
#ifdef _MAYA_
#else
#endif
// 引き数つきマクロ
#define LIGHT_DECLARE( N ) float4 light_ ## N
// C と同じく \ で複数行を連結する。
#define LIGHT_DECLARE( N ) float normalmap_scale ## N \
< \
UIName = "Nomalmap Scale" \
> = {0.1f}
■ 行列
// 成分のとり方
float3 v = m._m03_m13_m23;
// 1行目を取得。
float3 v = m[0];
Cg 内の Matrix と 成分を調査
守ること.
Application -> Cg に渡す際に transpose すること
かける順番
mul( m, v );
次のように構成だと考えられる
Ax Ay Az T
[00][01][02][03] (x) = (Xnew + Tx)
[10][11][12][13] (y) (yNew + Ty)
[20][21][22][23] (z) (zNew + Tz)
[30][31][32][33] (1) (1)
POINT
mul( m, v )は 次の計算
v.x = 0行目 ( m[0] ) * v
v.y = 1行目 ( m[1] ) * v
v.z = 2行目 ( m[2] ) * v
v.w = 3行目 ( m[3] ) * v
[] 演算子は行列の行を取得する。
次の計算で確認できる。
float4x4 m;
m[0] = float4(1,1,0,0);
m[1] = float4(0,1,0,0);
m[2] = float4(0,0,1,0);
m[3] = float4(0,0,0,1);
// { 1, 0.5, 0, 1 } == オレンジ色
float s = 0.5f;
OUT.col = mul( m, float4(s,s,0,1) );
// { 0.5, 1, 0, 1 } == ライトグリーン
m[0] = float4(1,0,0,0);
m[1] = float4(1,1,0,0);
m[2] = float4(0,0,1,0);
m[3] = float4(0,0,0,1);
OUT.col = mul( m, float4(s,s,0,1) );
// 成分指定 がどこを指すかチェック
m[0] = float4(1,0,0,0);
m[1] = float4(1,1,0,0);
m[2] = float4(0,0,1,0);
m[3] = float4(0,0,0,1);
m._m10 = 0; // 1行, 0 列
m._m11 = 0;
// { 0.5, 0, 0, 1 } Dark Red
float s = 0.5f;
OUT.col = mul( m, float4(s,s,0,1) );
行列スウィズル演算子
< type>< rows>x< columns> という形式の行列型の場合、
matrix._m< row>< col>
matrix._m< row>< col>[_m< row>< col>][...]
という表記法を使用して、個々の行列要素にアクセスしたり(< row>< col>ペアが1つのみの場合)
行列の要素からベクトルを構成したり(< row>< col>ペアが複数存在する場合)することができる。
行と列の番号は0 から始まる
// 連続で指定できる
// Assign the main diagonal of myMatrix to myFloatVec4.
fvec4 = myMatrix.m_00_m11_m22_m33;
float4x4 a と宣言したとすると、a[3] は a._m30_m31_m32_m33 に等しくなる
どちらの式も、行列の3 行目を取り出す
// Az 成分( 列 )をとる
float3 Az = m._m02_m12_m22;
// Cg Reference より抜粋
mul() は 3 つの使用方法がある。
行列 × 列ベクトル
mul(M, v);
行ベクトル × 行列
mul(v, M);
行列 × 行列
mul(M, N);
// 次のような 記述になる
(m11 m21 m31 m41) (v1)
(m12 m22 m32 m42) (v2)
(m13 m23 m33 m43) (v3)
(m14 m24 m34 m44) (v4)
float3 eyevec_w = viewI._m03_m13_m23 - pos_w;
OUT.test = float4( viewI._m03_m13_m23, 1.0f );
float3x3 nmatrix = float3x3( tan, bin, nml );
nmatrix[0] = tan;
nmatrix[1] = bin;
nmatrix[2] = nml;
float4 a = float4( 1.236812, -0.714074, -0.866025, -0.577350 );
float4 b = float4( 0.000000, 1.428148, -0.866025, -0.577350 );
float4 c = float4( -1.236812, -0.714074, -0.866025, -0.577350 );
float4 d = float4( 1.785185, 0.507938, -68.817703, 120.788200 );
// float4 から matrix 生成
float4x4 mtxLit = float4x4( a, b, c, d );
float4 a = float4(1,2,3,1);
return float4(a[0], a[1], a[2], 1 );
// 要素をえる( 0 行 0 列 )
float4x4 m;
float f = m[0][0];
■ Reference(Cg)
■ floor
SYNTAX
floor( f )
DESC
f 以下の最大の整数
浮動小数点 の 整数部 をとりだす
■ frac
SYNTAX
frac( f )
DESC
f の小数部
■ cross
SYNTAX
cross(float3 a, float3 b)
DESC
ベクトル a と b の外積
a から b への外積
a = 1, 0, 0
b = 0, 1, 0
0 0 1
0 0 1
-----
0 0 1
0 1 0
1 0 0
-----
0 0 0
1 0 0
0 1 0
-----
0 0 1
0 0 1
------
-1
c = a * b の定義 ( aからbまで回す右ねじの進む向き)
a.y*b.z + a.z * b.x + a.x + b.y
-
b.y*a.z + b.z*a.x + + b.x*a.y
float3 cross(float3 a, float3 b)
{
return a.yzx * b.zxy - a.zxy * b.yzx;
}
// fragment shader で試すと 青
return float4( cross( float3(1,0,0), float3(0,1,0) ), 1 );
// 黒
return float4( cross( float3(0,1,0), float3(1,0,0) ), 1 );
■ lerp
SYNTAX
lerp(a, b, f)
DESC
(1-f)*a + f*b
TIP
WARNING
描画結果が正しくない現象が見られる
自前で計算した方が無難
■ reflect
SYNTAX
floatN reflect( floatN i, floatN n);
DESC
param n: Normal ( 要 normalize )
param i: IncidentVector
WARNING
i は VtxPos - EyePos
Lighting 時とは逆向き の Vector
PROFILE
fp20
■ tex2Dproj
SYNTAX
tex2Dproj (sampler2D tex, float4 sq);
DESC
Texture 座標を W=1 の空間に変換後に sampling する
PROFILE
PS20
シャドウマップルックアップ:
テクスチャ座標のz 成分が、シャドウマップと比較する深度値を保持
シャドウマップルックアップでは
深度比較テクスチャリングのためにアプリケーションにより構成された関連テクスチャのユニットが必要
これがないと、深度比較は実際に実行されない
■ clamp
SYNTAX
clamp(x, a, b)
DESC
x < a = x = a
x > b = x = b
else x;
■ abs
SYNTAX
abs(x)
DESC
abs(x) x の絶対値
■ length
SYNTAX
float length( floatN vec )
DESC
vec の長さ( ノルム )を返す
float length( float3 vec ) {
return sqrt( dot(vec, vec) );
}
■ exp
SYNTAX
exp(x)
DESC
Euler ^ x
■ exp2
SYNTAX
exp2(x)
DESC
2^x
■ step
SYNTAX
floatN step( floatN a, floatN x)
DESC
x >= a となる階段関数で変換した値を返す。
■ normalize
SYNTAX
normalize(x)
DESC
N次元ベクトルを正規化する