p5.js備忘録(4)3Dモデルとシェーダー

目次
  1. 3Dモデル
  2. シェーダー

3Dモデル

3DCGツールで作成した3Dモデル(立体のキャラクターなどのデータ)を読み込んで表示できます

*p5.jsでは同じドメイン内からしか3Dモデルを読み込めません

  • loadModel(path, normalize, [successCallback], [failureCallback], [fileType])
    OBJファイルまたはSTLファイルから 3Dモデルを読み込みます
    preload()内に配置する必要があります
    サイズが大きい場合は第二引数にtrueを設定(p5に適したスケールに変更)
    scale() 関数で最終的なサイズにできます
    • path
      ロードするモデルのパス
    • normalize:
      true の場合読み込み時にモデルを標準化されたサイズにスケーリングします
    • successCallback
      モデルが読み込まれると呼び出される関数
      3Dモデルオブジェクトが渡されます
    • failureCallback:
      モデルの読み込みに失敗した場合、イベントエラーで呼び出されます
    • fileType
      モデルのファイル拡張子 「.stl・.obj」
  • model()
    3Dモデルを画面にレンダリングします
  • OBJファイル(.obj)
    ジオメトリと一部のマテリアルおよびテクスチャデータを格納するファイル形式
    p5.j​​s ではジオメトリのみ
  • STLファイル(.stl)
    ジオメトリに関する情報のみ格納するファイル形式
    p5.j​​sでは色付きのSTLファイルはサポートされていません
    *色付きの STLファイルは色のプロパティなしでレンダリングされます
let chair;
function preload() {
  chair = loadModel('chair.obj', true);
}
function setup() {
  createCanvas(windowWidth, windowHeight, WEBGL);
}
function draw() {
  background(200);
  scale(0.5);
  rotateX(frameCount * 0.01);
  rotateY(frameCount * 0.01);
  normalMaterial();
  model(chair);
}

無料で3Dモデルがダウンロードできるサイト

シェーダー

シェーダーはGPUで実行される小さなプログラムです
p5でこれまで行ってきた描画は主にCPUでの計算に依存していて順番に実行するので描画が複雑になるほど表示速度が遅くなります
シェーダーの命令はすべての単一ピクセルに対して一度に実行されるので高速です

「GLSL」はシェーダー言語のひとつでWebGLでは「GLSL」が使用されます
p5.jsでもGLSLを用いた描画が可能です

「GLSL」では2つのシェーダーの記述が必要です

  • 頂点シェーダー(.vert)
    頂点の位置の計算
    位置座標や法線ベクトルなどの頂点の属性だけを参照・変換する記述
  • フラグメントシェーダー(.frag)
    色の情報の描画処理
    ピクセル単位の色の計算をする記述

.vertファイルが最初に実行されジオメトリ上のすべてのピクセルの位置を .frag ファイルに渡す
.fragファイルは位置に応じてピクセルに色を付ける

頂点シェーダーとフラグメントシェーダー

attribute vec3 aPosition;
void main() {
  vec4 positionVec4 = vec4(aPosition, 1.0);
  positionVec4.xy = positionVec4.xy * 2.0 - 1.0;
  gl_Position = positionVec4;
}
#ifdef GL_ES
precision mediump float;
#endif

uniform vec2 u_resolution;
uniform float u_time;
void main(void){
	vec2 st = gl_FragCoord.xy /u_resolution.xy;
	vec3 color = vec3(0.);		
  color.r = cos(u_time);
  color.g = sin(u_time);
	color.b = 0.5;
	gl_FragColor= vec4(color,0.8);
}

頂点シェーダーとフラグメントシェーダーから
loadShader()・createShader() を使用してカスタムシェーダーを作成できます

  • loadShader(vertFilename, fragFilename, [callback], [errorCallback])
    頂点シェーダーとフラグメントシェーダーファイルから新しいp5.Shaderオブジェクトを作成
    戻り値はシェーダー オブジェクト
    preload() で使用する必要があります
    • vertFilename :
      頂点シェーダーソースコードを含むファイルへのパス
    • fragFilename
      フラグメントシェーダーソースコードを含むファイルへのパス
    • callback
      loadShaderの完了後に実行されるコールバック
      成功するとp5.Shaderオブジェクトが最初の引数に渡されます
    • errorCallback
      loadShader内でエラーが発生したときに実行されるコールバック
      エラーの場合エラーが最初の引数に渡されます
  • createShader(vertSrc, fragSrc)
    頂点シェーダーとフラグメントシェーダーコードから新しいp5.Shaderオブジェクトを作成します
  • shader()
    p5.Shaderオブジェクトを設定します
  • setUniform(uniformName, data)
    オブジェクトのユニフォームを設定するために使用されます
    ユニフォームはCPUで実行されるスケッチからの値をGPUで実行されるシェーダープログラムに提供する方法です
    • uniformName
      ユニフォームの名前
      頂点シェーダーとフラグメント シェーダーで使用される名前に対応している必要があります
    • data
      関連付けるデータ
      true/false・数値・数値の配列・または画像 (p5.Image、p5.Graphics、p5.MediaElement、p5.Texture) のいずれか
let theShader;
function preload() {
  theShader = loadShader('shader.vert', 'shader.frag');
}
function setup() {
  createCanvas(windowWidth, windowHeight, WEBGL);
  pixelDensity(1);
  noStroke();
}
function draw() {
  shader(theShader); 
  theShader.setUniform("u_resolution", [width, height]);
  theShader.setUniform("u_time", millis() / 1000.0);
//シェーダーを任意の形状に適用、形状を指定しない限りシェーダーは機能しない
  rect(0,0,width, height);
}
function windowResized(){
  resizeCanvas(windowWidth, windowHeight);
}

見つける😊
*OpenProcessingは、Processingの作品を公開したり共有したりできるサイトです