弊社の一部界隈ではやり始めているWebGL(GLSL)。年末年始の時間を利用して勉強しようとしている人もいらっしゃるのではないでしょうか。私もその一人なのですが、参考になるものが何か無いかな?と探していたところ、素晴らしい参考サイトが見つかりました。
■ GLSL Sandcox
http://glslsandbox.com
GLSLの砂場(遊び場)です。
このサイトには非常に美しいサンプルが多数掲載されており、
何よりそのコードをすぐに試すことができます。
これから勉強を始めようという人にうってつけではないでしょうか!
ということで今回はそのサンプルコードをThree.jsと一緒にためすデモを作ってみました。
以下に長々とコードを表示を記述したのですが、大事なところは2つだけ!
vertexシェーダーとfragmentシェーダー箇所は[GLSL Sandbox]にあるシェーダーを少し書き換えるだけでいろいろ試すことができます。表示そのものはWebGLで出力されるので当然iPhone(iOS8)でも見ることができました。
参考コード
http://glslsandbox.com/e#20474.0
HTML+CSS+JavaScriptsample
html,body{height:100%;overflow:hidden;}
body{ margin: 0; padding: 0; background: #000;}
#container{ width: 100%; height: 100%; }
void main( void )
{
gl_Position = vec4( position, 1.0 );
}
uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;
void main( void )
{
vec2 p = ( gl_FragCoord.xy / resolution.xy ) * 2.0 – 1.0;
vec3 c = vec3( 0.0, 0.0, 0.0 );
float amplitude = 0.10;
float glowT = sin(time) * 0.5 + 0.5;
float glowFactor = mix( 0.15, 0.35, glowT );
c += vec3(0.02, 0.03, 0.13) * ( glowFactor * abs( 1.0 / sin(p.x + sin( p.y + time ) * amplitude ) ));
c += vec3(0.02, 0.10, 0.03) * ( glowFactor * abs( 1.0 / sin(p.x + sin( p.y + time+1.00 ) * amplitude+0.1 ) ));
c += vec3(0.13, 0.02, 0.03) * ( glowFactor * abs( 1.0 / sin(p.x + sin( p.y + time+2.00 ) * amplitude+0.2 ) ));
gl_FragColor = vec4( c, 1.0 );
}
(function(){
var container,camera,scene,renderer,mesh;
// シェーダーとの通信に使う箇所です。
var uniforms = {
time: { type: “f”, value: 1.0 },
resolution: { type: “v2”, value: new THREE.Vector2() },
mouse: { type: “v2”, value: new THREE.Vector2() }
};
uniforms.resolution.value.x = window.innerWidth;
uniforms.resolution.value.y = window.innerHeight;
/*
1.初期化
2.three.jsに必要なものの生成
3.アニメーションスタート
*/
init();
createObject();
animate();
/*
以下関数
*/
// リサイズ設定
window.addEventListener( ‘resize’, onWindowResize, false );
function onWindowResize()
{
uniforms.resolution.value.x = window.innerWidth;
uniforms.resolution.value.y = window.innerHeight;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function init()
{
// 表示領域の設定
container = document.getElementById(‘container’);
// カメラ
var _width = window.innerWidth;
var _height = window.innerHeight;
camera = new THREE.PerspectiveCamera( 50, _width / _height, 1, 1000 );
camera.position.z = 1;
// カメラフォーカス
var _focus = new THREE.Vector3();
_focus.set( 0, 0, 0 );
camera.lookAt( _focus );
// シーン
scene = new THREE.Scene();
scene.fog = new THREE.Fog( 0x050505, 200, 1000 );
// 環境光
scene.add( new THREE.AmbientLight( 0x050505 ) );
// renderer
renderer = new THREE.WebGLRenderer( { antialias: false } );
renderer.setClearColor( scene.fog.color, 1 );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
}
function createObject()
{
// シェーダーを映すスクリーンの設定
var geometry = new THREE.PlaneBufferGeometry( 2, 2 );
var material = new THREE.ShaderMaterial( {
uniforms: uniforms,
vertexShader: document.getElementById( ‘vertexShader’ ).textContent,
fragmentShader: document.getElementById( ‘fragmentShader’ ).textContent
});
var mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
}
function animate()
{
requestAnimationFrame( animate );
render();
}
function render()
{
var timer = Date.now() * 0.0001;
uniforms.time.value += 0.05;
renderer.render( scene, camera );
}
})();