THREE.jsでフラグメントシェーダを使ってみるの基礎基礎メモ1
フラグメントシェーダを使って色を変更してみたいと思います。
基礎の復習
ベースとなるコードです。
js
window.onload = () => { let windowWidth = window.innerWidth; let windowHeight = window.innerHeight; // rendererの作成 let renderer = new THREE.WebGLRenderer(); // canvasをbodyに追加 document.body.appendChild(renderer.domElement); // canvasをリサイズ renderer.setSize(windowWidth, windowHeight); // scene作成 let scene = new THREE.Scene(); // camera作成 let camera = new THREE.PerspectiveCamera(75, windowWidth / windowHeight, 0.1, 1000); camera.position.z = 100; // Geometry作成 let geometry = new THREE.PlaneBufferGeometry(100, 100); // Material作成 let material = new THREE.ShaderMaterial({ vertexShader: myVert, fragmentShader: myFrag, uniforms:{ uColor: {type: "c", value: new THREE.Color(0xFF0000)} } }); // Mesh作成 let mesh = new THREE.Mesh(geometry,material); // Meshをシーンに追加 scene.add(mesh); // draw renderer.render(scene, camera); };
vert(頂点シェーダー)
void main() { gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }
frag(フラグメントシェーダー)
precision mediump float; uniform vec3 uColor; void main(){ gl_FragColor =vec4(uColor, 1.0); }
結果
マウス座標で色を変えてみる
マウス座標を取得して色を変更してみたいと思います。 requestAnimationFrameでuniformsを更新していきます。
js
window.onload = () => { let windowWidth = window.innerWidth; let windowHeight = window.innerHeight; let mouse = new THREE.Vector2(0.0, 0.0); // rendererの作成 let renderer = new THREE.WebGLRenderer(); // canvasをbodyに追加 document.body.appendChild(renderer.domElement); // canvasをリサイズ renderer.setSize(windowWidth, windowHeight); // scene作成 let scene = new THREE.Scene(); // camera作成 let camera = new THREE.PerspectiveCamera(75, windowWidth / windowHeight, 0.1, 1000); camera.position.z = 100; // Geometry作成 let geometry = new THREE.PlaneBufferGeometry(100, 100); // Material作成 let material = new THREE.ShaderMaterial({ vertexShader: myVert, fragmentShader: myFrag, uniforms: { uMouse: { type: "v2", value: mouse }, } }); // Mesh作成 let mesh = new THREE.Mesh(geometry, material); // Meshをシーンに追加 scene.add(mesh); //マウス座標を取得 renderer.domElement.addEventListener('mousemove', function (e) { mouse = new THREE.Vector2( e.clientX / windowWidth, e.clientY / windowHeight); }, false); // draw render(); //描画 function render() { renderer.render(scene, camera); material.uniforms.uMouse.value = mouse; // animation requestAnimationFrame(render); } };
frag(フラグメントシェーダー)
precision mediump float; uniform vec2 uMouse; void main(){ // テクスチャ座標をカラーに出力 gl_FragColor =vec4(uMouse.x,uMouse.y,0.0, 1.0); }
結果
マウスを動かすと色が変わります。
See the Pen vJqRqb by nogson (@satofaction) on CodePen.
経過時間で色を変えてみる
window.onload = () => { let windowWidth = window.innerWidth; let windowHeight = window.innerHeight; let clock = new THREE.Clock(); let time = 0.0; // rendererの作成 let renderer = new THREE.WebGLRenderer(); // canvasをbodyに追加 document.body.appendChild(renderer.domElement); // canvasをリサイズ renderer.setSize(windowWidth, windowHeight); // scene作成 let scene = new THREE.Scene(); // camera作成 let camera = new THREE.PerspectiveCamera(75, windowWidth / windowHeight, 0.1, 1000); camera.position.z = 100; // Geometry作成 let geometry = new THREE.PlaneBufferGeometry(100, 100); // Material作成 let material = new THREE.ShaderMaterial({ vertexShader: myVert, fragmentShader: myFrag, uniforms: { uTime: { type: "f", value: time }, } }); // Mesh作成 let mesh = new THREE.Mesh(geometry, material); // Meshをシーンに追加 scene.add(mesh); //マウス座標を取得 renderer.domElement.addEventListener('mousemove', function (e) { mouse = new THREE.Vector2( e.clientX / windowWidth, e.clientY / windowHeight); }, false); // draw render(); //描画 function render() { renderer.render(scene, camera); //経過時間を取得 time = clock.getElapsedTime(); material.uniforms.uTime.value = time; // animation requestAnimationFrame(render); } };
frag(フラグメントシェーダー)
precision mediump float; uniform float uTime; void main(){ float t = abs(cos(uTime)); gl_FragColor =vec4(t,t,t, 1.0); }
結果
See the Pen YxovGW by nogson (@satofaction) on CodePen.
まとめ
すごい基礎的な部分なのですが、なかなか上手くいきません。 とにかく色々やってみるしかありません。