/* フィーブル藩国ライブ壁紙モジュール */ 'use strict'; var modLiveWallpaper = function() { /* * 定数定義 */ // 回転角度計算 const DEG0001 = Math.PI / 36000; const DEG0005 = Math.PI / 7200; const DEG001 = Math.PI / 3600; const DEG025 = Math.PI / 1080; const DEG050 = Math.PI / 720; const DEG054 = Math.PI / 660; const DEG060 = Math.PI / 600; const DEG066 = Math.PI / 540; const DEG075 = Math.PI / 480; const DEG100 = Math.PI / 360; // 全天球サイズ const SPHERE_SIZE = 700; // カメラの移動上限 const CAMERA_MAX_Y = 500; // モジュール変数 var scene, camera, renderer, stats; // レンダリング関数格納用&ID var rendering, animationId; // レンダリング停止関数の格納用 var closeScene; /* * public 定義 */ return { feebleCastle : modFeebleCastle(), // フィーブル城モジュール cyberSpace : modCyberSpace(), // サイバー空間モジュール anohoshi : modAnohoshi(), // あの星モジュール checkWebGL : checkWebGL, // WebGL対応判定 addStats : addStats, // ステータス表示追加 removeStats : removeStats, // ステータス表示削除 resize : rendererResize, // レンダリングサイズ再設定 animation : rendererAnimation, // レンダリング開始 cancel : cancelAnimation // レンダリング停止 }; /** * フィーブル城モジュール */ function modFeebleCastle() { // モジュール定数 const FOG_MIN = 0.00015; const FOG_MAX = 0.0005; // モジュール変数 var oneDay, pointLight, meshSkySphere, meshSun, meshMoon, meshOceanSphere, pcStars = [], meshClouds = []; /* * public 定義 */ return { setScene : setScene // あの星作成 }; /** * フィーブル城作成 * canvas 描画対象のcanvasのelement * quolity 描画の解像度 */ function setScene(canvas, quolity, oneDayTime, volClouds, volStars) { var texLoader = new THREE.TextureLoader(); // 設定値の引数をモジュール変数に格納 oneDay = oneDayTime; // シーン作成 scene = new THREE.Scene(); scene.fog = new THREE.FogExp2(0xffffff, 0.0001); // レンダリングで制御する // カメラ作成 camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 17000 ); // 平行光源作成 var ambientLight = new THREE.AmbientLight ( 0x222222 ); scene.add( ambientLight ); // 点光源 pointLight = new THREE.PointLight( 0xffffff, 1, 3000 ); pointLight.position.set( -100, 0, 0 ); scene.add( pointLight ); // レンダラー作成 renderer = new THREE.WebGLRenderer({ canvas:canvas }); rendererResize(quolity); // フィーブル城作成 var texCastle = texLoader.load('/common/img/back/feebleCastle/castle.png'); // 面作成(星が隠れないようにテクスチャに合わせた形にする) texCastle.minFilter = THREE.LinearFilter; var geoCastle = new THREE.Geometry(); geoCastle.vertices.push( new THREE.Vector3(250,96,0), new THREE.Vector3(210,112,0), new THREE.Vector3(-280,-160,0), new THREE.Vector3(280,-160,0) ); geoCastle.faces.push( new THREE.Face3(0,1,2), new THREE.Face3(0,2,3) ); geoCastle.faceVertexUvs[0].push([ new THREE.Vector2((280 + 250) / 560, 0.80), new THREE.Vector2((280 + 210) / 560, 0.85), new THREE.Vector2(0, 0) ], [ new THREE.Vector2((280 + 250) / 560, 0.80), new THREE.Vector2(0, 0), new THREE.Vector2(1, 0) ]); geoCastle.computeFaceNormals(); var meshCastle = new THREE.Mesh( geoCastle, new THREE.MeshPhongMaterial({ map:texCastle, transparent:true }) ); meshCastle.position.x = 50; meshCastle.position.y = -30; meshCastle.position.z = -400; scene.add( meshCastle ); // アイランド作成 var texIsland = texLoader.load('/common/img/back/feebleCastle/fblr.png'); texIsland.minFilter = THREE.LinearFilter; var meshIsland = new THREE.Mesh( new THREE.PlaneBufferGeometry ( 338, 191, 1, 1 ), new THREE.MeshPhongMaterial({ map:texIsland, transparent:true}) ); meshIsland.position.x = -1500; meshIsland.position.y = -650; meshIsland.position.z = -2500; scene.add( meshIsland ); // 海 var texOcean = texLoader.load('/common/img/back/feebleCastle/ocean.jpg'); texOcean.wrapS = texOcean.wrapT = THREE.RepeatWrapping; texOcean.repeat.set(150, 150); meshOceanSphere = new THREE.Mesh( new THREE.SphereGeometry(15000, 72, 72), new THREE.MeshPhongMaterial({ map:texOcean }) ); meshOceanSphere.position.y = -15700; meshOceanSphere.position.z = -2000; meshOceanSphere.rotation.z = Math.PI / 2; scene.add( meshOceanSphere ); setSky(volClouds, volStars); // レンダリング関数を指定 rendering = renderingFeebleCastle; closeScene = closeSceneFeebleCastle; } function closeSceneFeebleCastle() { oneDay = void 0; pointLight = void 0; meshSkySphere = void 0; meshSun = void 0; meshMoon = void 0; meshOceanSphere = void 0; pcStars = []; meshClouds = []; } function setSky(volClouds, volStars) { var texLoader = new THREE.TextureLoader(); // 太陽 var texSun = texLoader.load('/common/img/back/feebleCastle/sun.png'); texSun.minFilter = THREE.LinearFilter; meshSun = new THREE.Mesh( new THREE.CircleGeometry ( 144, 36 ), new THREE.MeshLambertMaterial({ map:texSun, transparent:true, blending:THREE.AdditiveBlending }) ); scene.add( meshSun ); // 月 var texMoon = texLoader.load('/common/img/back/feebleCastle/moon.png'); texMoon.minFilter = THREE.LinearFilter; meshMoon = new THREE.Mesh( new THREE.SphereGeometry(96, 36, 36), new THREE.MeshBasicMaterial({ map:texMoon, transparent:true }) ); meshMoon.rotation.x -= Math.PI / 18; scene.add( meshMoon ); // 星の各座標作成 var geometry = new THREE.Geometry(); for ( i = 0; i < volStars; i ++ ) { var vertex = new THREE.Vector3(); vertex.x = Math.random() * 18000 - 9000; vertex.y = Math.random() * 18000 - 9000; vertex.z = Math.random() * 9000 - 9000; if (vertex.length() > 7000) { geometry.vertices.push( vertex ); } } // 作成する星の設定を作成 var paramParticles = [ [ 0xffffff, 80 ], [ 0xaaffff, 50 ], [ 0xffeeff, 50 ], [ 0xffaaaa, 40 ], [ 0xffffff, 32 ], [ 0xaaffff, 32 ], [ 0xffeeff, 32 ], [ 0xffffee, 32 ] ]; // 粒子座標に星を配置 var texParticle = texLoader.load("/common/img/back/feebleCastle/particle.png") var color, size, materials = []; for (var i = 0; i < paramParticles.length; i++) { color = paramParticles[i][0]; size = paramParticles[i][1]; materials[i] = new THREE.PointsMaterial( { color:color, size:size, map:texParticle, transparent:true, opacity:0 } ); pcStars[i] = new THREE.Points( geometry, materials[i] ); pcStars[i].sortParticles = false; // 粒子座標をレイヤーごとにランダム回転 pcStars[i].rotation.x = Math.random() * Math.PI; pcStars[i].rotation.y = Math.random() * Math.PI; pcStars[i].rotation.z = Math.random() * Math.PI; scene.add( pcStars[i] ); } // 雲作成 for (var i = 0; i < volClouds; i++) { var texCloud = texLoader.load('/common/img/back/feebleCastle/cloud' + Math.round(2 * Math.random()) + '.png'); texCloud.minFilter = THREE.LinearFilter; meshClouds[i] = new THREE.Mesh( new THREE.PlaneBufferGeometry(1280 * (1 + 2 * Math.random()), 480 * (1 + 2.5 * Math.random()), 1, 1 ), new THREE.MeshPhongMaterial({ map:texCloud, transparent:true, blending:THREE.AdditiveBlending, depthTest:false}) ); meshClouds[i].geometry.applyMatrix( new THREE.Matrix4().makeTranslation(0, 10000, 0) ); meshClouds[i].position.y = -10000 + 6000 * Math.random(); meshClouds[i].position.z = -3800 - Math.round(5 * Math.random()); meshClouds[i].rotation.z = Math.random() * Math.PI; scene.add( meshClouds[i] ); } // 空 meshSkySphere = new THREE.Mesh( new THREE.SphereGeometry(9000, 36, 36), new THREE.MeshPhongMaterial({ side:THREE.BackSide, color:0x000000 }) ); scene.add( meshSkySphere ); } // フィーブル城レンダリング function renderingFeebleCastle() { // 海の回転 meshOceanSphere.rotateX(DEG0005); // 現在時間 var nowTime = new Date().getTime() + 32400000; // 日本標準時+9時間 // 日の出入計算用のcos、sin var sinWaveS = Math.sin(- nowTime * Math.PI / oneDay * 2 - Math.PI / 2); var cosWaveS = Math.cos(- nowTime * Math.PI / oneDay * 2 - Math.PI / 2); // 朝焼け夕焼け計算用のcos、sin var sinWaveB = Math.max(Math.abs(Math.sin(- nowTime * Math.PI / oneDay * 2 - Math.PI / 0.996)) - 0.95, 0) * 20; var glowClr = new THREE.Color(sinWaveB * 0.85, sinWaveB * 0.41, sinWaveB * 0.17); // 太陽の軌道 meshSun.position.x = 3200 * cosWaveS - 5000; meshSun.position.y = 5000 * sinWaveS - 2000; meshSun.position.z = -6000 * cosWaveS; // 空の明るさ scene.fog.color.setRGB(0, 0.066, 0.2); scene.fog.color.add( new THREE.Color(0.733 * (sinWaveS + 0.9) / 1.9, 0.8 * (sinWaveS + 0.9) / 1.9, 0.8 * (sinWaveS + 0.9) / 1.9) ); scene.fog.color.add( glowClr ); scene.fog.density = FOG_MIN + (FOG_MAX - FOG_MIN) * (sinWaveS + 1) / 2; // フィーブル城にあたる太陽光 pointLight.color.setRGB((sinWaveS + 1) / 2, (sinWaveS + 1) / 2, (sinWaveS + 1) / 2); pointLight.color.add( glowClr ); // 月の出入計算用のcos、sin var cosWaveM = Math.cos(- nowTime * 1.1 * Math.PI / oneDay * 2); var sinWaveM = Math.sin(- nowTime * 1.1 * Math.PI / oneDay * 2); // 月の軌道 meshMoon.position.x = -3200 * cosWaveM - 5000; meshMoon.position.y = -5000 * sinWaveM - 2000; meshMoon.position.z = 6000 * cosWaveM; // 月の満ち欠け meshMoon.rotation.z = Math.PI / (1080 * (nowTime % oneDay)); // Math.PI / 360 / (nowTime % oneDay) * 30 // 日中は星を非表示 for (var i = 0; i < pcStars.length; i++) { pcStars[i].material.opacity = Math.min(Math.min(sinWaveS + 0.66, 0) * 5 * -1, 1); } // 雲の移動 var rotZ; for (var i = 0; i < meshClouds.length; i++) { rotZ = - DEG0001 + DEG0001 * (meshClouds[i].position.z % 5) * (300000 / oneDay); meshClouds[i].rotateZ( rotZ ); } // レンダリング実行 renderer.render( scene, camera ); } } /** * サイバー空間モジュール */ function modCyberSpace() { // モジュール変数 var meshFblRes, meshRing01, meshRing02, meshRing03, meshRing04, meshBackSphere, pcParticles = []; /* * public 定義 */ return { setScene : setScene // サイバー空間作成 }; /** * サイバー空間作成 * canvas 描画対象のcanvasのelement * quolity 描画の解像度 * sphere [img:全天球に貼り付けるテクスチャ名, clr:背景色] * colorFog フォグ色 * colorAmbient 環境光色 * colorPoint 下からのライト色 * colorRing サイバー魔法陣の色 * volParticle 上昇粒子の数 * colorParticle 上昇粒子の色 */ function setScene(canvas, quolity, sphere, colorFog, colorAmbient, colorPoint, colorRing, volParticle, colorParticle) { var texLoader = new THREE.TextureLoader(); // シーン作成 scene = new THREE.Scene(); scene.fog = new THREE.FogExp2(colorFog, 0.0005); // カメラ作成 camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 2000 ); camera.position.set( 0, 0, 600 ); // レンダラー作成 renderer = new THREE.WebGLRenderer({ canvas:canvas }); rendererResize(quolity); // 平行光源作成 var ambientLight = new THREE.AmbientLight ( colorAmbient ); scene.add( ambientLight ); // ポイント光源作成 var pointLight0 = new THREE.PointLight( colorPoint, 6.0, 1000 ); pointLight0.position.set( 0.0, -500.0, 0.0 ); scene.add( pointLight0 ); // 壁紙全天球作成 if (sphere['img'] == '') { meshBackSphere = new THREE.Mesh( new THREE.SphereGeometry(SPHERE_SIZE, 36, 36), new THREE.MeshPhongMaterial({ side:THREE.BackSide, color:sphere['clr'] }) ); } else { var texBack = texLoader.load('/common/img/back/' + sphere['img']); texBack.wrapS = texBack.wrapT = THREE.RepeatWrapping; var imgBackRepX = 10, imgBackRepY = 10; // 背景のリピート回数を算出 var imgBack = new Image(); imgBack.src = '/common/img/back/' + sphere['img']; if (imgBack.width > 0) { imgBackRepX = Math.round(SPHERE_SIZE * Math.PI / 2 / imgBack.width) * -1; imgBackRepY = Math.round(SPHERE_SIZE * Math.PI / 2 / imgBack.height); } texBack.repeat.set(imgBackRepX, imgBackRepY); meshBackSphere = new THREE.Mesh( new THREE.SphereGeometry(SPHERE_SIZE, 36, 36), new THREE.MeshPhongMaterial({ side:THREE.BackSide, map:texBack, color:sphere['clr'] }) ); } scene.add( meshBackSphere ); // サイバー魔法陣作成 setCyberSpaceAddRing(scene, colorRing); // FBLロゴ作成 var texFblRes = texLoader.load('/common/img/back/cyberSpace/fblR_sb.png'); texFblRes.minFilter = THREE.LinearFilter; meshFblRes = new THREE.Mesh( new THREE.PlaneBufferGeometry ( 360, 240, 1, 1 ), new THREE.MeshBasicMaterial({ side:THREE.DoubleSide, map:texFblRes, transparent:true, opacity:0.8, depthTest:false }) ); meshFblRes.position.y -= 90; scene.add( meshFblRes ); // 上昇粒子作成 setCyberSpaceAddParticle(scene, volParticle, colorParticle); // レンダリング関数を指定 rendering = renderingCyberSpace; closeScene = closeCyberSpace; } function closeCyberSpace() { meshFblRes = void 0; meshRing01 = void 0; meshRing02 = void 0; meshRing03 = void 0; meshRing04 = void 0; meshBackSphere = void 0; pcParticles = []; } // サイバー魔法陣作成 function setCyberSpaceAddRing(scene, colorRing) { var texLoader = new THREE.TextureLoader(); // サイバー魔法陣1作成 var texRing01 = texLoader.load('/common/img/back/cyberSpace/ringA01.png'); texRing01.minFilter = THREE.LinearFilter; meshRing01 = new THREE.Mesh( new THREE.CircleGeometry ( 333, 32 ), new THREE.MeshLambertMaterial({ map:texRing01, transparent:true, emissive:colorRing, emissiveIntensity:1000, depthTest:false }) ); meshRing01.rotation.x -= Math.PI / 2; meshRing01.position.y -= 270; scene.add( meshRing01 ); // サイバー魔法陣2作成 var texRing02 = texLoader.load('/common/img/back/cyberSpace/ringA02.png'); texRing02.minFilter = THREE.LinearFilter; meshRing02 = new THREE.Mesh( new THREE.CircleGeometry ( 333, 32 ), new THREE.MeshLambertMaterial({ map:texRing02, transparent:true, emissive:colorRing, depthTest:false }) ); meshRing02.rotation.x -= Math.PI / 2; meshRing02.position.y -= 245; scene.add( meshRing02 ); // サイバー魔法陣3作成 var texRing03 = texLoader.load('/common/img/back/cyberSpace/ringA03.png'); texRing03.minFilter = THREE.LinearFilter; meshRing03 = new THREE.Mesh( new THREE.CircleGeometry ( 333, 32 ), new THREE.MeshLambertMaterial({ map:texRing03, transparent:true, emissive:colorRing, depthTest:false }) ); meshRing03.rotation.x -= Math.PI / 2; meshRing03.position.y -= 230; scene.add( meshRing03 ); // サイバー魔法陣4作成 var texRing04 = texLoader.load('/common/img/back/cyberSpace/ringA04.png'); texRing04.minFilter = THREE.LinearFilter; meshRing04 = new THREE.Mesh( new THREE.CircleGeometry ( 333, 32 ), new THREE.MeshLambertMaterial({ map:texRing04, transparent:true, emissive:colorRing, depthTest:false }) ); meshRing04.rotation.x -= Math.PI / 2; meshRing04.position.y -= 220; scene.add( meshRing04 ); } // 上昇粒子作成 function setCyberSpaceAddParticle(scene, volParticle, colorParticle) { var texLoader = new THREE.TextureLoader(); // 粒子の各座標作成 var geometry = new THREE.Geometry(); for ( i = 0; i < volParticle; i ++ ) { var vertex = new THREE.Vector3(); vertex.x = Math.random() * SPHERE_SIZE * 2 - SPHERE_SIZE; vertex.y = Math.random() * SPHERE_SIZE * 2 - SPHERE_SIZE; vertex.z = Math.random() * SPHERE_SIZE * 2 - SPHERE_SIZE; geometry.vertices.push( vertex ); } // 作成する粒子の設定を作成 var paramParticles = [ [ new THREE.Color(colorParticle), 12 ], [ new THREE.Color(colorParticle), 8 ], [ new THREE.Color(colorParticle).offsetHSL(0, 0, -0.1), 8 ], [ new THREE.Color(colorParticle).offsetHSL(0, 0, -0.1), 4 ] ]; // 粒子座標に粒子を配置 var texParticle = texLoader.load("/common/img/back/cyberSpace/particle.png") var color, size, materials = []; for (var i = 0; i < paramParticles.length; i++) { color = paramParticles[i][0]; size = paramParticles[i][1]; materials[i] = new THREE.PointsMaterial( { color:color, size:size, map:texParticle, transparent:true, depthTest:false } ); pcParticles[i] = new THREE.Points( geometry, materials[i] ); pcParticles[i].sortParticles = false; // 粒子座標をレイヤーごとにランダム回転(縦に回転する粒子を制限) pcParticles[i].rotation.x = Math.random() * Math.PI / 10; pcParticles[i].rotation.y = Math.random() * Math.PI; pcParticles[i].rotation.z = Math.random() * Math.PI / 10; scene.add( pcParticles[i] ); } } // サイバー空間レンダリング function renderingCyberSpace() { // スクロールに合わせてカメラを移動する camera.position.y = ( $(window).scrollTop() ) * 0.4; if (camera.position.y > CAMERA_MAX_Y) { camera.position.y = CAMERA_MAX_Y; } camera.lookAt( scene.position ); // FBLロゴ回転 meshFblRes.rotateY(- DEG075); // サイバー魔法陣回転 meshRing01.rotateZ(- DEG075); meshRing02.rotateZ(DEG060); meshRing03.rotateZ(- DEG066); meshRing04.rotateZ(DEG054); // 全天球回転 meshBackSphere.rotateY(- DEG050); // 粒子の回転・上昇 for (var i = 0; i < pcParticles.length; i++) { // pointCloudをそれぞれまとめて回転 pcParticles[i].rotation.y += DEG025; // 粒子を個別に上昇 for (var j = 0; j < pcParticles[i].geometry.vertices.length; j++) { // vertex更新フラグ。描画の更新に必須 pcParticles[i].geometry.verticesNeedUpdate = true; // 粒子上昇 pcParticles[i].geometry.vertices[j].setY(pcParticles[i].geometry.vertices[j].y + 0.1); // 全天球から出たら下に戻す if (pcParticles[i].geometry.vertices[j].y > 700) { pcParticles[i].geometry.vertices[j].setY( -700 ); } } } // レンダリング実行 renderer.render( scene, camera ); } } /** * あの星モジュール */ function modAnohoshi() { // モジュール定数 const SKY_BORDER = 1200; const GRD_BORDER = -1200; // モジュール変数 var colorBack, climaxBorder, colorClimax, climaxFlag = -1, climaxCount = 0, pcStars = [], meshGround, meshWp; /* * public 定義 */ return { setScene : setScene // あの星作成 }; /** * あの星作成 * canvas 描画対象のcanvasのelement * quolity 描画の解像度 * bgColor 背景色 */ function setScene(canvas, quolity, clrBack, volHoshi, climax, clrClimax, king) { var texLoader = new THREE.TextureLoader(); // 引数をモジュール変数に格納 climaxBorder = climax; colorBack = new THREE.Color(clrBack); colorClimax = new THREE.Color(clrClimax); // シーン作成 scene = new THREE.Scene(); // カメラ作成 camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 12000 ); camera.position.set( 0, 0, 0 ); camera.lookAt(new THREE.Vector3(0, 0, -1000)); // レンダラー作成 renderer = new THREE.WebGLRenderer({ canvas:canvas }); rendererResize(quolity); // 地面作成 var texGround = texLoader.load('/common/img/back/anohoshi/ground.png'); meshGround = new THREE.Mesh( new THREE.PlaneBufferGeometry ( 12800, 640, 1, 1 ), new THREE.MeshBasicMaterial({ map:texGround }) ); meshGround.position.y = -1300; meshGround.position.z = -3000; scene.add( meshGround ); // 壁紙作成 meshWp = new THREE.Mesh( new THREE.PlaneBufferGeometry ( 12800, 6000, 1, 1 ), new THREE.MeshBasicMaterial({ color:colorBack }) ); meshWp.position.z = -3100; scene.add( meshWp ); // 藩王作成 if (king) { var texFeeble = texLoader.load('/common/img/back/anohoshi/feeble.png'); texFeeble.minFilter = THREE.LinearFilter; var meshFeeble = new THREE.Mesh( new THREE.PlaneBufferGeometry (128, 284, 1, 1), new THREE.MeshBasicMaterial({ map:texFeeble, transparent:true }) ); meshFeeble.position.x = 900; meshFeeble.position.y = -600; meshFeeble.position.z = -1500; scene.add( meshFeeble ); } // 雪の星作成 setStars(scene, volHoshi); // レンダリング関数を指定 rendering = renderingAnohoshi; closeScene = closeAnohoshi; } function closeAnohoshi() { colorBack = void 0; climaxBorder = void 0; colorClimax = void 0; climaxFlag = -1; climaxCount = 0; pcStars = []; meshGround = void 0; meshWp = void 0; } // 雪の星作成 function setStars(scene, volHoshi) { var texLoader = new THREE.TextureLoader(); // スター座標にスターを配置 var texStar = texLoader.load("/common/img/back/anohoshi/star.png"); texStar.minFilter = THREE.LinearFilter; var clrWork, color, size, geometry, materials = []; for (var i = 0; i < 20; i++) { clrWork = 1 * (Math.random() * 0.9 + 0.1) size = Math.round(178 - 89 * Math.random()); materials[i] = new THREE.ShaderMaterial({ uniforms: { color: { type: 'c', value: new THREE.Color(clrWork, clrWork, clrWork) }, shadowColor: { type: 'c', value: new THREE.Color(clrWork, clrWork, clrWork) }, texture: { type: 't', value: texStar }, size: { type: 'f', value: size }, // ほしの描画用設定 rotDeg: { type:'f', value: [] }, speed: { type:'f', value: [] } }, vertexShader: document.getElementById('vshader').textContent, fragmentShader: document.getElementById('fshader').textContent, // 通常マテリアルのパラメータ blending: THREE.NormalBlending, transparent: true, depthTest: false }); // スター用のBufferGeometory geometry = new THREE.BufferGeometry(); var position = []; var rotation = []; // スターの各座標作成 var hoshiCnt = volHoshi + i * 2; for (var j = 0; j < hoshiCnt; j ++ ) { position.push( Math.random() * 2000 - 1000, Math.random() * (SKY_BORDER - GRD_BORDER) - (SKY_BORDER - GRD_BORDER) / 2, - 2000 + 100 * i + j ); rotation.push(0.0); materials[i].uniforms.rotDeg.value.push(Math.PI / 36 * (0.1 + 0.9 * Math.random())); materials[i].uniforms.speed.value.push(Math.random() * (4.0 - i * 0.2) + 0.3); } geometry.addAttribute('position', new THREE.BufferAttribute(new Float32Array(position), 3)); geometry.addAttribute('rotation', new THREE.BufferAttribute(new Float32Array(rotation), 1)); pcStars[i] = new THREE.Points( geometry, materials[i] ); pcStars[i].sortParticles = false; // スター座標をレイヤーごとに5度の範囲で回転(落下・上昇角度) pcStars[i].rotation.z = Math.PI / 9 * (Math.random() * 2 - 1); scene.add( pcStars[i] ); } } // あの星レンダリング function renderingAnohoshi() { // スクロールに合わせてカメラを移動する camera.position.y = ( $(window).scrollTop() ) * 0.4; if (camera.position.y > CAMERA_MAX_Y) { camera.position.y = CAMERA_MAX_Y; } renderingAnohoshiChkClimax(); if (climaxCount < 0) { // クライマックスでカメラ引き・押し climaxCount++; camera.position.z += climaxFlag; } else { renderingAnohoshiMove(); } // レンダリング実行 renderer.render( scene, camera ); } function renderingAnohoshiChkClimax() { // 規定数のスターが落ちる・登るしたらモードチェンジ if (climaxCount > climaxBorder) { climaxCount = -40; // クライマックス時のカメラ移動距離 climaxFlag *= -1; // スターの色変化 if (climaxFlag < 0) { // 白黒 for (var i = 0; i < pcStars.length; i++) { pcStars[i].material.uniforms.color.value = new THREE.Color(pcStars[i].material.uniforms.shadowColor.value); } meshWp.material.color = new THREE.Color(colorBack); } else { // カラフル for (var i = 0; i < pcStars.length; i++) { var mColor = pcStars[i].material.uniforms.color.value; if (colorClimax.r == 1.0) mColor.r = 1.0; else mColor.r *= colorClimax.r; if (colorClimax.g == 1.0) mColor.g = 1.0; else mColor.g *= colorClimax.g; if (colorClimax.b == 1.0) mColor.b = 1.0; else mColor.b *= colorClimax.b; pcStars[i].material.uniforms.color.value = new THREE.Color(mColor.r, mColor.g, mColor.b); } var clrWp = meshWp.material.color; meshWp.material.color = new THREE.Color(clrWp.r * colorClimax.r * 1.4, clrWp.g * colorClimax.g * 1.4, clrWp.b * colorClimax.b * 1.4); } } } function renderingAnohoshiMove() { for (var i = 0; i < pcStars.length; i++) { // スターを個別に上昇 for (var j = 0; j < pcStars[i].geometry.attributes.position.count; j++) { var idxY = pcStars[i].geometry.attributes.position.itemSize * j + 1; var posY = pcStars[i].geometry.attributes.position.array[idxY]; var rot = pcStars[i].geometry.attributes.rotation.array[j]; // 落下上昇 posY += climaxFlag * pcStars[i].material.uniforms.speed.value[j]; // 回転 rot += climaxFlag * pcStars[i].material.uniforms.rotDeg.value[j]; // 範囲から出たら上・下に戻す。また、回転が無限に増え続けるので初期化する if (posY > SKY_BORDER) { posY = GRD_BORDER; rot = Math.PI * Math.random(); climaxCount++; } else if (posY < GRD_BORDER) { posY = SKY_BORDER; rot = Math.PI * Math.random(); climaxCount++; } pcStars[i].geometry.attributes.position.array[idxY] = posY; pcStars[i].geometry.attributes.rotation.array[j] = rot; } pcStars[i].geometry.attributes.position.needsUpdate = true; pcStars[i].geometry.attributes.rotation.needsUpdate = true; } } } /** * 使用中のブラウザがWebGLに対応しているかを判定する。 * @returns {Boolean} 対応正否 */ function checkWebGL(canvas) { return (canvas.getContext('webgl')) ? true : false; } /** * 描画ステータス作成 */ function addStats() { stats = new Stats(); stats.domElement.style.position = 'fixed'; stats.domElement.style.right = '3px'; stats.domElement.style.bottom = '3px'; $('body')[0].appendChild( stats.domElement ); } /** * 描画ステータス削除 */ function removeStats() { $('body')[0].removeChild( stats.domElement ); } /** * 描画サイズ再設定 */ function rendererResize(quolity) { var w = $(window).width() / quolity; var h = $(window).height() / quolity; renderer.setSize(w, h); camera.aspect = w / h; camera.updateProjectionMatrix(); } /** * アニメーション実行 */ function rendererAnimation() { // 各ブラウザ間での関数名の違いを吸収 var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame; window.requestAnimationFrame = requestAnimationFrame; animationId = requestAnimationFrame( rendererAnimation ); rendering(); if (stats !== undefined) { stats.update(); } } /** * アニメーション停止 */ function cancelAnimation() { // 各ブラウザ間での関数名の違いを吸収 var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame; window.requestAnimationFrame = requestAnimationFrame; if (stats !== undefined) { removeStats(); } window.cancelAnimationFrame( animationId ); animationId = undefined; if (closeScene !== undefined) { closeScene(); closeScene = void 0; } rendering = void 0; stats = void 0; renderer = void 0; camera = void 0; scene = void 0; } }(); // アクセス用関数略名定義 var LW = { 'Check' : { 'WebGL' : modLiveWallpaper.checkWebGL }, 'Set' : { 'FeebleCastle' : modLiveWallpaper.feebleCastle.setScene, 'CyberSpace' : modLiveWallpaper.cyberSpace.setScene, 'Anohoshi' : modLiveWallpaper.anohoshi.setScene }, 'Stats' : { 'Add' : modLiveWallpaper.addStats, 'Remove' : modLiveWallpaper.removeStats }, 'Renderer' : { 'Resize' : modLiveWallpaper.resize, 'Start' : modLiveWallpaper.animation, 'Stop' : modLiveWallpaper.cancel }, };