ThreeJs_horse

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
	<head>
		<title>three.js webgl - shadow map</title>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
		<style>
			body {
				font-family: Monospace;
				background-color: #000;
				color: #fff;
				margin: 0px;
				overflow: hidden;
			}
			#info {
				position: absolute;
				top: 10px;
				width: 100%;
				text-align: center;
				z-index: 100;
				display:block;
			}
			#info a { color: #f00; font-weight: bold; text-decoration: underline; cursor: pointer }
		</style>
	</head>

	<body>

		<div id="info">
		<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> 
		- shadowmap - models by 
		<a href="http://mirada.com/">mirada</a> from <a href="http://ro.me">rome</a><br />
		move camera with WASD / RF + mouse<br />
		<a href="https://www.xinxing-pipe.com/" target="_blank" rel="noopener">whxx</a> 
		- HappyNewYear 
		</div>
		
		<script src="../build/three.js"></script>
		<script src="js/controls/FirstPersonControls.js"></script>
		<script src="js/shaders/UnpackDepthRGBAShader.js"></script>
		<script src="js/Detector.js"></script>
		<script src="js/libs/stats.min.js"></script>

		<script>

			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();//如果探测器没有webgl 就增加
			//阴影map宽度、高度
			var SHADOW_MAP_WIDTH = 2048, SHADOW_MAP_HEIGHT = 1024;
			//当前窗口高宽
			var SCREEN_WIDTH = window.innerWidth;//界面宽度
			var SCREEN_HEIGHT = window.innerHeight;//界面高度
		
			var FLOOR = -250;//地面,窗体中显示的高度

			var ANIMATION_GROUPS = 25;//动作组

			var camera, controls, scene, renderer;//相机 控制 场景 渲染
			var container, stats;//容器 统计

			var NEAR = 5, FAR = 3000;//近距离位置,远距离位置
			var morph, morphs = [], mixer, animGroups = [];//变形,混合,动作组

			var light;
			var clock = new THREE.Clock();//计时,表

			init();
			animate();

			
			function init() {//初始化

				//1 设置容器
				container = document.createElement( 'div' );//声明  容器=文档产生div标签
				document.body.appendChild( container );//增加一个容器

				//2 SCENE
				//2.1CAMERA 场景 相机 相机=透视(23,宽高比,近 远)
				camera = new THREE.PerspectiveCamera( 23, SCREEN_WIDTH / SCREEN_HEIGHT, NEAR, FAR );
				camera.position.set( 700, 50, 1900 );//空间位置
				
				//2.2 控制
				controls = new THREE.FirstPersonControls( camera );//第1人控制(相机)
				controls.lookSpeed = 0.0125;//看的速度
				controls.movementSpeed = 500;//移动速度
				controls.noFly = false;
				controls.lookVertical = true;//看垂直
				controls.constrainVertical = true;//容器平行
				controls.verticalMin = 1.5;//最小平行
				controls.verticalMax = 2.0;//最大平行
				controls.lon = 250;//限制
				controls.lat = 30;

				//2.3 SCENE场景
		
				scene = new THREE.Scene();
				scene.background = new THREE.Color( 0x59472b );
				scene.fog = new THREE.Fog( 0x59472b, 1000, FAR );//迷雾

				//2.4 LIGHTS
				//2.4.1ambient 环境光
				var ambient = new THREE.AmbientLight( 0x444444 );//环境或包围
				scene.add( ambient );//场景+环境光
				
				//2.4 light 特征光
				light = new THREE.SpotLight( 0xffffff, 1, 0, Math.PI/2 );//斑点光
				light.position.set( 0, 1500, 1000 );//光源位置
				light.target.position.set( 0, 0, 0 );//光目标位置
				light.castShadow = true;//投影
				light.shadow = new THREE.LightShadow( new THREE.PerspectiveCamera( 50, 1, 700, FAR ) );//透镜
				light.shadow.bias = 0.0001;//偏好、偏差
				light.shadow.mapSize.width = SHADOW_MAP_WIDTH;//阴影宽度
				light.shadow.mapSize.height = SHADOW_MAP_HEIGHT;
				scene.add( light );//场景+特征照射光
				
				//3 c产生场景
				createScene();

				// RENDERER

				renderer = new THREE.WebGLRenderer();//渲染器
				renderer.setPixelRatio( window.devicePixelRatio );//像素比率
				renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
				container.appendChild( renderer.domElement );
				renderer.autoClear = false;
				//
				renderer.shadowMap.enabled = true;//阴影
				renderer.shadowMap.type = THREE.PCFSoftShadowMap;

				// STATS 统计
				stats = new Stats();
				container.appendChild( stats.dom ); //容器添加

				//
				window.addEventListener( 'resize', onWindowResize, false );//增加事件监听

			}

			//窗口变化
			function onWindowResize() {
				SCREEN_WIDTH = window.innerWidth;//获得宽度
				SCREEN_HEIGHT = window.innerHeight;//获得长度

				camera.aspect = SCREEN_WIDTH / SCREEN_HEIGHT;//单光束发射断层
				camera.updateProjectionMatrix();//更新投射(凸起物)矩阵

				renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );

				controls.handleResize();//句柄.调整大小

			}

			function createScene( ) {//创建场景

				//1 GROUND  基础 地面
				var geometry = new THREE.PlaneBufferGeometry( 100, 100 );//平面缓冲几何形状
				var planeMaterial = new THREE.MeshPhongMaterial( { color: 0xffdd99 } );//
				var ground = new THREE.Mesh( geometry, planeMaterial );//地面
				ground.position.set( 0, FLOOR, 0 );//设置底板
				ground.rotation.x = - Math.PI / 2;//旋转
				ground.scale.set( 100, 100, 100 );//刻度,改变大小
				ground.castShadow = false;//投影
				ground.receiveShadow = true;//收到阴影
				scene.add( ground );//场景增加底板

				//2  TEXT 增加文字
				var loader = new THREE.FontLoader();//字体导入
				loader.load( 'fonts/helvetiker_bold.typeface.json', function ( font ) {

					var textGeo = new THREE.TextBufferGeometry( "WHXX PIPES Co.ltd", {
					<!-- var textGeo = new THREE.TextBufferGeometry( "YanWJ_HappyNewYear", { -->
						font: font,//字体
						size: 200,
						height: 50,
						curveSegments: 12,//曲面分段
						bevelThickness: 2,//斜率厚度
						bevelSize: 5,
						bevelEnabled: true

					});

					textGeo.computeBoundingBox();//估算--弹跳
					var centerOffset = -0.5 * ( textGeo.boundingBox.max.x - textGeo.boundingBox.min.x );//中心偏移
					var textMaterial = new THREE.MeshPhongMaterial( { color: 0xff0000, specular: 0xffffff } );//文本材料					
					
					var mesh = new THREE.Mesh( textGeo, textMaterial );//啮合网眼
					mesh.position.x = centerOffset;
					mesh.position.y = FLOOR + 67;
					mesh.castShadow = true;//投影
					mesh.receiveShadow = true;
					scene.add( mesh );//文本加入场景

				} );

				//3 CUBES_文字底座立方体
				//3.1 cubes_one
				var mesh = new THREE.Mesh( new THREE.BoxGeometry( 1500, 220, 150 ), planeMaterial );
				mesh.position.y = FLOOR - 50;
				mesh.position.z = 20;
				mesh.castShadow = true;
				mesh.receiveShadow = true;
				scene.add( mesh );
				
				//3.2cubes_two
				var mesh = new THREE.Mesh( new THREE.BoxGeometry( 1600, 170, 250 ), planeMaterial );
				mesh.position.y = FLOOR - 50;
				mesh.position.z = 20;
				mesh.castShadow = true;
				mesh.receiveShadow = true;
				scene.add( mesh );
				
				//4 混合搅拌 
				mixer = new THREE.AnimationMixer( scene );//搅拌器
				for ( var i = 0; i !== ANIMATION_GROUPS; ++ i ) {
					var group = new THREE.AnimationObjectGroup();
					animGroups.push( new THREE.AnimationObjectGroup() );
				}

				//5  MORPHS 变体
				function addMorph( geometry, speed, duration, x, y, z, fudgeColor, massOptimization ) {
					var material = new THREE.MeshLambertMaterial( { color: 0xffaa55, morphTargets: true, vertexColors: THREE.FaceColors } );

					if ( fudgeColor ) {//捏造颜色
						material.color.offsetHSL( 0, Math.random() * 0.5 - 0.25, Math.random() * 0.5 - 0.25 );
					}

					var mesh = new THREE.Mesh( geometry, material );//网格=几何+材质
					mesh.speed = speed;//网格速度
					var clip = geometry.animations[ 0 ];//修剪=几何.动画.索引
					
					if ( massOptimization ) {//聚集优化组合
						var index = Math.floor( Math.random() * ANIMATION_GROUPS ),//索引=地板 动作数据
							animGroup = animGroups[ index ];//动作组=动作大组索引
						animGroup.add( mesh );//动作组加网格

						if ( ! mixer.existingAction( clip, animGroup ) ) {//如果不存在,混合器.存在动作(剪辑,动组)
							var randomness = 0.6 * Math.random() - 0.3;//随机
							var phase = ( index + randomness ) / ANIMATION_GROUPS;//分阶段=索引+随机/动作组

							mixer.clipAction( clip, animGroup ).//混合器.剪辑动作(修剪,动组)
									setDuration( duration ).//设置持续时间
									startAt( - duration * phase ).//开始(持续时间*分段)
									play();//运行

						}

					} else {

						mixer.clipAction( clip, mesh ).//混合.剪辑(剪辑,网格)
								setDuration( duration ).//设置持续时间
								startAt( - duration * Math.random() ).
								play();

					}

					mesh.position.set( x, y, z );//网格.位置
					mesh.rotation.y = Math.PI/2;
					mesh.castShadow = true;//网格.投影
					mesh.receiveShadow = true;
					scene.add( mesh );//场景增加网格

					morphs.push( mesh );//变形.推进(网格)

				}

				var loader = new THREE.JSONLoader();//装载
				
				loader.load( "models/animated/horse.js", function( geometry ) {//装载主角
					for ( var i = - 600; i < 601; i += 2 ) {
						addMorph( geometry, 550, 1, 100 - Math.random() * 3000, FLOOR, i, true, true );//变形
					}
				} );
				
				<!-- loader.load( "obj/morphs/fox.js", function( geometry ) { -->
					<!-- addMorph( geometry, 200, 1000, 100 - Math.random() * 500, FLOOR - 5, 600 ); -->
				<!-- } ); -->

				/*
				loader.load( "obj/morphs/shdw3walk.js", function( geometry ) {
					addMorph( geometry, 40, 2000, -500, FLOOR + 60, 245 );
				} );

				loader.load( "obj/morphs/flamingo.js", function( geometry ) {
					addMorph( geometry, 500, 1000, 500 - Math.random() * 500, FLOOR + 350, 40 );
				} );

				loader.load( "obj/morphs/stork.js", function( geometry ) {
					addMorph( geometry, 350, 1000, 500 - Math.random() * 500, FLOOR + 350, 340 );
				} );

				loader.load( "obj/morphs/mountainlion.js", function( geometry ) {
					addMorph( geometry, 400, 1000, 500 - Math.random() * 500, FLOOR - 5, 700 );
				} );

				loader.load( "obj/morphs/bearBrown.js", function( geometry ) {
					addMorph( geometry, 300, 2500, -500, FLOOR - 5, -750 );
				} );

				loader.load( "obj/morphs/parrot.js", function( geometry ) {
					addMorph( geometry, 450, 500, 500 - Math.random() * 500, FLOOR + 300, 700 );
				} );
				*/

			}

			//动画

			function animate() {
				requestAnimationFrame( animate );//请求动画框(动作\生命)
				stats.begin();
				render();//提交
				stats.end();

			}

			function render() {

				var delta = clock.getDelta();//时钟得到德尔塔
				if ( mixer ) mixer.update( delta );//混合器更新
				for ( var i = 0; i < morphs.length; i ++ ) {//变体长度
					morph = morphs[ i ];//改变=变体索引
					morph.position.x += morph.speed * delta;//改变位置=变体速度*系数
					if ( morph.position.x  > 2000 )  {//改变位置
						morph.position.x = -1000 - Math.random() * 500;
					}

				}

				controls.update( delta );//控制更新

				renderer.clear();//渲染器.清理
				renderer.render( scene, camera );//渲染器提交(场景,相机)

			}

		</script>

	</body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值