threejsでShaderMaterialとかを使うと、自分で直接GLSLをいじれる。
そのためのメモ。
##入出力
###VertexShader
- 入力 なし
- 出力 gl_Position (vec4) _ 2次元平面上の頂点座標
- 出力 gl_PointSize (float) _ 点のサイズ
###FragmentShader
- 入力 gl_FrontFacing (bool) ポリゴンの表裏のブール値
- 入力 gl_FragCoord (vec4) ウィンドウ座標=canvas上の座標 (x,y,z, 1/w)
- 入力 gl_PointCoord (vec2) ポイントスプライト時の2次元座標
- 出力 gl_FragColor (vec4) ピクセルの描画色
- 出力 gl_FragData[] ([]) glDrawBuffersとかで使う配列データ
これら以外はuniform
##GLSL ES上で扱われる型
- int (整数)
- ivec2,ivec3,ivec4 (intのベクトル)
- bool (ブール)
- bvec2,bvec3,bvec4 (boolのベクトル)
- float
- vec2,vec3,vec4 (floatのベクトル)
- mat2,mat3,mat4 (行列)
- sampler2D (2次元テクスチャ)
- samplerCube (3次元テクスチャ)
##threejsによって既に定義されている変数
変数名 | 説明 |
---|---|
modelMatrix | オブジェクト座標からワールド座標へ変換する |
viewMatrix | ワールド座標から視点座標へ変換 |
modelViewMatrix | modelMatrixとviewMatrixの積算 |
projectionMatrix | カメラの各種パラメータから3次元を2次元に射影し、クリップ座標系に変換する行列 |
cameraPosition | カメラの位置 |
normalMatrix | 頂点法線ベクトルを視点座標系に変換する行列 |
position | 頂点座標 |
normal | 頂点法線ベクトル |
uv | テクスチャを貼るためのUV座標 |
バーテックスシェーダーでは全部使える。
フラグメントシェーダーでは,viewMatrixとcameraPositionのみ使える。
フラグメントシェーダー側で使うときはバーテックスシェーダ内でvarying変数に一旦いれたりする。vUv=vu; みたいな感じで。
##threejsからuniform/attributeを渡すとき指定する文字列(type)
よくつかいそうなのは
- i (整数)
- f (float)
- v2 (THREE.Vector2)
- v3 (THREE.Vector3)
- v4 (THREE.Vector4)
- c (THREE.Color)
- m4 (THREE.Matrix4)
- t (THREE.Texture)
var uniformsExample = {
"uInt" : { type: "i", value: 1 }, // single integer
"uFloat" : { type: "f", value: 3.14 }, // single float
"uVec2" : { type: "v2", value: new THREE.Vector2( 0, 1 ) }, // single Vector2
"uVec3" : { type: "v3", value: new THREE.Vector3( 0, 1, 2 ) }, // single Vector3
"uVec4" : { type: "v4", value: new THREE.Vector4( 0, 1, 2, 3 ) }, // single Vector4
"uCol" : { type: "c", value: new THREE.Color( 0xffaa00 ) }, // single Color
"uMat4" : { type: "m4", value: new THREE.Matrix4() }, // single Matrix4
"uTex" : { type: "t", value: THREE.ImageUtils.loadTexture( "texture.jpg" ) }, // regular texture
"uTexCube" : { type: "t", value: THREE.ImageUtils.loadTextureCube( [ "px.jpg", "nx.jpg", // cube texture
"py.jpg", "ny.jpg",
"pz.jpg", "nz.jpg" ] ) },
"uIntArray" : { type: "iv1", value: [ 1, 2, 3, 4, 5 ] }, // integer array (plain)
"uIntArray3" : { type: "iv", value: [ 1, 2, 3, 4, 5, 6 ] }, // integer array (ivec3)
"uFloatArray" : { type: "fv1", value: [ 0.1, 0.2, 0.3, 0.4, 0.5 ] }, // float array (plain)
"uFloatArray3" : { type: "fv", value: [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6 ] }, // float array (vec3)
"uVec2Array" : { type: "v2v", value: [ new THREE.Vector2( 0.1, 0.2 ),
new THREE.Vector2( 0.4, 0.5 ) ] }, // Vector2 array
"uVec3Array" : { type: "v3v", value: [ new THREE.Vector3( 0.1, 0.2, 0.3 ),
new THREE.Vector3( 0.4, 0.5, 0.6 ) ] }, // Vector3 array
"uVec4Array" : { type: "v4v", value: [ new THREE.Vector4( 0.1, 0.2, 0.3, 0.4 ),
new THREE.Vector4( 0.4, 0.5, 0.6, 0.7 ) ] }, // Vector4 array
"uMat4Array" : { type: "m4v", value: [ new THREE.Matrix4(), new THREE.Matrix4() ] }, // Matrix4 array
"uTexArray" : { type: "tv", value: [ new THREE.Texture(), new THREE.Texture() ] } // texture array (regular)
// texture units start from value
};
引用元: https://github.com/mrdoob/three.js/wiki/Uniforms-types
##座標変換と行列の関係性
オブジェクト座標系(ローカル座標系)
↓
*modelMatrix
↓
ワールド座標系
↓
*viewMatrix
↓
視点座標系(カメラから見た座標)
↓
*projectionMatrix
↓
クリップ座標系 = xyzを-1〜+1で表す座標系
↓
ウィンドウ座標系 = canvas上の座標系
##基本的なfragmentShader/vertexShader
varying vec2 vUv;// fragmentShaderに渡すためのvarying変数
void main()
{
// 処理する頂点ごとのuv(テクスチャ)座標をそのままfragmentShaderに横流しする
vUv = uv;
// 変換:ローカル座標 → 配置 → カメラ座標
vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
// 変換:カメラ座標 → 画面座標
gl_Position = projectionMatrix * mvPosition;
}
//uniform 変数としてテクスチャのデータを受け取る
uniform sampler2D texture;
// vertexShaderで処理されて渡されるテクスチャ座標
varying vec2 vUv;
void main()
{
// テクスチャの色情報をそのままピクセルに塗る
gl_FragColor = texture2D(texture, vUv);
}
var materialShaderSimple = new THREE.ShaderMaterial({
vertexShader: vartexShaderString
fragmentShader: fragmentShaderString,
uniforms: {
texture: { type: 't', value: ImageUtils.loadTexture("**.png")} }
});
※こちらを参考にしました。 http://izmiz.hateblo.jp/entry/2014/09/27/235743
##GLSL ES組み込み関数
覚えにくいものを抜粋
関数名 | 説明 |
---|---|
sign(x) | 符号判別、負:-1,ゼロ:0,正:1 |
fract(x) | 小数の部分だけ返す |
mod(x,y) | x/yのあまり |
clamp(x,y,a) | クランプ処理min(max(x,y),a) |
mix(x,y,a) | 線形補間 |
smoothstep(edge0,edge1,x) | xの要素のうち、edge0以下のものは0.0、edge1以上のものは1.0にする。xがedge0とedge1の間にあるときには、3次エルミート補間を返す。 |
step(a,x) | x<aのとき0, x≧aのとき1 |
sqrt(x),inverssqrt(x) | inversは1/sqrt(x) |
normalize(x) | 正規化 |
faceforward(N,I,Nref) | 法線ベクトルNを条件により反転 |
reflect(I,N) | 法線ベクトルNの面に対して入射ベクトルIの反射ベクトルを返す |
refract(I,N,eta) | 屈折率etaの法線ベクトルNの面に対し、 |
length(x) | ベクトルの長さ=絶対値 |
distance(x,y) | x,yの距離 |
dot(x,y) | 内積 |
cross(x,y) | 外積 |
texture2D(uTexture, texCoords) | uTextureのtexCoords座標の色(vec4)を返す |
参考:glsl辞典
http://ec.nikkeibp.co.jp/nsp/dl/08513/HTML5GAMES_AppC.pdf
##threejs内でshaderが格納されている場所
- THREE.ShaderChunk = 共通で使われるGLSLのコード片
- THREE.UniformsUtils = uniformsの定義を操作するユーティリティ関数群
- THREE.UniformsLib = 共通で使われるuniforms定義
- THREE.ShaderLib = 各マテリアルで使用するシェーダー定義