<!DOCTYPE html>
<!-- 添加小人,使用序列图 -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html" charset="utf-8"/>
<title>Babylon - Getting Started</title>
<!-- Link to the last version of BabylonJS -->
<script src="https://preview.babylonjs.com/babylon.js"></script>
<!-- Link to the last version of BabylonJS loaders to enable loading filetypes such as .gltf -->
<script src="https://preview.babylonjs.com/loaders/babylonjs.loaders.min.js"></script>
<!-- Link to pep.js to ensure pointer events work consistently in all browsers -->
<script src="https://code.jquery.com/pep/0.4.1/pep.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/cannon.js/0.6.2/cannon.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.2/dat.gui.min.js"></script>
<script src="https://preview.babylonjs.com/gui/babylon.gui.min.js"></script>
<!-- <script src="https://cdn.rawgit.com/BabylonJS/Extensions/master/DynamicTerrain/dist/babylon.dynamicTerrain.min.js"></script> -->
<script src="./dy.js"></script>
<script src="./noise.js"></script>
</head>
<style>
html, body {
overflow: hidden;
width : 100%;
height : 100%;
margin : 0;
padding : 0;
}
#renderCanvas {
width : 100%;
height : 100%;
touch-action: none;
}
</style>
<body>
<canvas id="renderCanvas" touch-action="none"></canvas>
<script>
const canvas = document.getElementById("renderCanvas");
var engine = null;
// 这里还不能用let,不然就爆炸,获取不到engine
var scene = null;
var sceneToRender = null;
const createDefaultEngine = function() { return new BABYLON.Engine(canvas, true, { preserveDrawingBuffer: true, stencil: true, disableWebGL2Support: false}); };
let createScene=async function(){
// 关键函数都写在这个里面
var scene = new BABYLON.Scene(engine);
var skyColor = new BABYLON.Color3( .45, .65, 1.0);
scene.clearColor = BABYLON.Color3.Blue();
// var camera = new BABYLON.TargetCamera("cam", BABYLON.Vector3.Zero(), scene);
// camera.attachControl(canvas, true);
// 跟随相机
var camera = new BABYLON.FreeCamera("camera1", new BABYLON.Vector3(0, 5, -10), scene);
camera.attachControl(canvas, true);
let light=new BABYLON.HemisphericLight('light1',new BABYLON.Vector3(1.5,1.0,0.0),scene)
light.instensity=0.75
light.specular=BABYLON.Color3.Black()
light.groundColor=BABYLON.Color3.White()
scene.fogMode = BABYLON.Scene.FOGMODE_EXP2;
scene.fogColor = skyColor;
var fogDensity = 0.0020;
var fogAmplitude = fogDensity * 0.2;
var fogCycle = 10.0;
scene.fogDensity = fogDensity;
// 添加雾气
let node=new BABYLON.AbstractMesh('n',scene)
// 相机就绑定在这个mesh上面,后续操作就操作这个节点,带动相机移动
camera.parent=node
// 一些常量
let circumference=40000
// 地球周长
let everest=8.848
// 地球最高点
let mapFactor=0.25
// 用于获取地图的地球测量的因子
let elevationFactor=5.0
// 仰角倍增管
let nbPoints=2000
let initialCamPosition=new BABYLON.Vector3(100,20,10000)
// 初始相机位置
let downLimit=5.0
let upLimit=50.0
let speed=2.0
let altitudeRange=upLimit-downLimit
let halfAltitude=altitudeRange*0.5
let terrainTexture=new BABYLON.Texture("http://jerome.bousquie.fr/BJS/images/earthDouble.png",scene)
let terrainMat=new BABYLON.StandardMaterial('tm',scene)
terrainMat.diffuseTexture=terrainTexture
let terrain
let terrainReady=false
let createTerrain=function(mapData,mapSubX,mapSubZ){
let params={
mapData:mapData,
mapSubX:mapSubX,
mapSubZ:mapSubZ,
terrainSub:250
}
terrain=new BABYLON.DynamicTerrain('t',params,scene)
terrain.LODLimits=[4,3,2,2,1,1,1,1]
terrain.mesh.material=terrainMat
terrain.isAlwaysVisible=true
terrainReady=true
terrain.createUVMap()
terrain.updateCameraLOD=function(terrainCamera){
let cameraLOD=Math.abs((terrainCamera.globalPosition.y/30)|0)
return cameraLOD
}
}
let hmURL="http://jerome.bousquie.fr/BJS/images/worldHeightMapDouble.png"
let mapWidth=circumference*mapFactor
let mapHeight=circumference*mapFactor
let hmOptions={
width:mapWidth,
height:mapHeight,
subX:nbPoints,
subZ:nbPoints,
maxHeight:everest*elevationFactor,
onReady:createTerrain
}
let mapData=new Float32Array(nbPoints*nbPoints*3)
BABYLON.DynamicTerrain.CreateMapFromHeightMapToRef(hmURL,hmOptions,mapData,scene)
// 天空也是动态地形,但是这个感觉有点浪费:但是呢,这个是不大的,而且只是出现在头顶,或者视野前方
var skyMapSub = 300;
var skyMap = new Float32Array(skyMapSub * skyMapSub * 3);
var skyMapColor = new Float32Array(skyMapSub * skyMapSub * 3);
var l = 0;
var w = 0;
for (l = 0; l < skyMapSub; l++) {
for (w = 0; w < skyMapSub; w++) {
var rnd = Math.sin(l * w * 0.001) * 0.5 * Math.random();
skyMap[(w + l * skyMapSub) * 3] = (w - skyMapSub * 0.5) * circumference * mapFactor / skyMapSub;
skyMap[(w + l * skyMapSub) * 3 + 1] = rnd * 10.0;
skyMap[(w + l * skyMapSub) * 3 + 2] = (l - skyMapSub * 0.5) * circumference * mapFactor / skyMapSub;
skyMapColor[(w + l * skyMapSub) * 3] = skyColor.r + rnd;
skyMapColor[(w + l * skyMapSub) * 3 + 1] = skyColor.g + rnd;
skyMapColor[(w + l * skyMapSub) * 3 + 2] = skyColor.b;
}
}
var skyMaterial = new BABYLON.StandardMaterial("sm", scene);
skyMaterial.diffuseColor = BABYLON.Color3.White();
skyMaterial.specularColor = BABYLON.Color3.Black();
var sky = new BABYLON.DynamicTerrain("sky", {mapData: skyMap, mapSubX: skyMapSub, mapSubZ: skyMapSub, terrainSub: 70, mapColors: skyMapColor, invertSide: true}, scene);
sky.isAlwaysVisible = true;
sky.mesh.material = skyMaterial;
skyMaterial.backFaceCulling = false;
var skyAltitude = upLimit * 0.85;
var skyAltitudeAmplitude = skyAltitude * 0.60;
var skyAltitudeCycle = 1.2;
var skyAlpha = 0.4;
var skyAlphaAmplitude = 0.3;
var skyAlphaCycle = 2.0;
var skyColorAmplitude = 0.1;
var skyColorCycle = 1.0;
var skyColorDelta = 0.0;
// 飞行参数
let angZ=0.0
let angY=0.0
let angX=0.0
let deltaAngY=speed*0.01
// 转向速度
let deltaAngX=0.8
// 上提,下放速度
let deltaAngZ=0.8
// 倾斜速度
let pointerDistanceX=0.0
let pointerDistanceY=0.0
let tmpVect=BABYLON.Vector3.Zero()
camera.getDirectionToRef(BABYLON.Axis.Z,tmpVect)
// 相机的位置
node.position = initialCamPosition.scale(mapFactor);
// 其实这里给的位置还不算,因为后面会立马更新的
let y=downLimit
// 相机的高度
let k=0.0
let lineY=0.0
// 视线高度线Y位置
scene.registerBeforeRender(()=>{
camera.getDirectionToRef(BABYLON.Axis.Z, tmpVect);
tmpVect.scaleInPlace(1);
//每次自动移动的方向
// 将凸轮移动到它所看到的方向
node.position.addInPlace(tmpVect);
if(terrain){
y=terrain.getHeightFromMap(node.position.x,node.position.z)+downLimit
}
node.position.y=BABYLON.Scalar.Clamp(node.position.y,y,upLimit)
// value,min,max:取min和max之间的值
if(scene.pointerY){
py=(scene.pointerY/canvas.height-0.5)*deltaAngX
angX=Math.atan(py)
}
if(scene.pointerX){
//其实当我们鼠标左向变化的时候,不仅需要z轴倾斜,如果把他当成一辆车来看,可能一个隐式的操作是掉头
px=(-2.0*scene.pointerX/canvas.width+1.0)*deltaAngZ
angZ=Math.atan(px)
angY-=angZ*deltaAngY
}
node.rotation.x=angX
node.rotation.z=angZ
node.rotation.y=angY
sky.mesh.position.y = skyAltitude + Math.sin(k * skyAltitudeCycle) * skyAltitudeAmplitude;
skyMaterial.alpha = skyAlpha - Math.sin(k * skyAlphaCycle) * skyAlphaAmplitude;
scene.fogDensity = fogDensity + Math.sin(k * fogCycle) * fogAmplitude;
skyColorDelta = skyColorAmplitude * Math.sin(k * skyColorCycle);
scene.clearColor.r = skyColor.r - skyColorDelta;
scene.clearColor.g = skyColor.g - skyColorDelta;
//scene.clearColor.b = skyColor.b - skyColorDelta;
k += 0.001;
})
return scene
}
window.initFunction=async function(){
let asyncEngineCreation=async function(){
try{
return createDefaultEngine()
}catch(e){
return createDefaultEngine()
}
}
window.engine=await asyncEngineCreation()
if(!engine){
throw('engine should not be null')
}
window.scene=createScene()
}
initFunction().then(()=>{
scene.then((returnedScene)=>{
sceneToRender=returnedScene
})
let limit=60
let count=0
let fps=0
engine.runRenderLoop(function(){
count++
if(count===limit){
fps=Math.round(engine.getFps())
count=0
console.log('当前帧数是'+fps)
}
if(sceneToRender&&sceneToRender.activeCamera){
sceneToRender.render()
}
})
})
window.addEventListener('resize',function(){
engine.resize()
})
</script>
</body>
</html>
网友评论