本文搬自我的Github,https://github.com/555chy/three.js-example-comment,有兴趣的可以一起来完善,这个为Three.js的Example进行注解,方便初学者阅读
three.js 官网 Example 地址:https://threejs.org/examples/
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - convex geometry</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;
margin: 0px;
overflow: hidden;
}
#info {
position: absolute;
color: #fff;
top: 0px;
width: 100%;
padding: 5px;
text-align:center;
}
a {
color: #fff;
}
</style>
</head>
<body>
<div id="info"><a href="http://threejs.org" target="_blank">three.js</a> - ConvexGeometry</div>
<script src="../build/three.js"></script>
<!--
轨道控制,鼠标左键旋转(与鼠标方向相同,用于非触摸屏上),右键平移,中键靠近或远离;也可以使用键盘控制
-->
<script src="js/controls/OrbitControls.js"></script>
<!--
凸几何体
-->
<script src="js/geometries/ConvexGeometry.js"></script>
<!--
检测支持(canvas,webgl,workers,fileApi)
-->
<script src="js/Detector.js"></script>
<!--
统计插件(FPS,渲染时间,chrome内存使用率,而且支持自定义)
-->
<script src="js/libs/stats.min.js"></script>
<script>
//如果不支持webgl,则会在body内添加一个不支持的提示信息DIV
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var group, camera, scene, renderer;
init();
animate();
function init() {
scene = new THREE.Scene();
//如果它的值是true,会得到一个绘图缓冲区,执行抗锯齿。默认情况下,它的值是true
renderer = new THREE.WebGLRenderer( { antialias: true } );
//devicePixelRatio是设备上物理像素和设备独立像素(device-independent pixels (dips))的比例,与Android上的DIP相仿,作用是在所有设备上的显示效果都相近
renderer.setPixelRatio( window.devicePixelRatio );
//更新待渲染场景的大小
renderer.setSize( window.innerWidth, window.innerHeight );
//将渲染器的DOM元素(即Canvas)添加到HTML中
document.body.appendChild( renderer.domElement );
// camera
/*
透视相机
PerspectiveCamera(fov, aspect, near, far)
fov(视场):从相机位置能够看到的部分场景。推荐默认值45
aspect(长宽比):渲染结果输出区域的横向长度和纵向长度的比值。推荐默认值window.innerWidth/window.innerHeight
near(近面):定义从距离相机多近的地方开始渲染场景。推荐默认值0.1
far(远面):定义相机可以从它所处的位置看多远。默认值1000
*/
camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 1000 );
//定义相机的位置,有如下两种方式。如果不设置的话,相机位置为默认的Vector3{x:0,y:0,z:0}
//camera.position.x = 15;
//camera.position.y = 20;
//camera.position.z = 30;
camera.position.set( 15, 20, 30 );
scene.add( camera );
// controls
//轨道控制,鼠标左键旋转(与鼠标方向相同,用于非触摸屏上),右键平移,中键靠近或远离;也可以使用键盘控制
controls = new THREE.OrbitControls( camera, renderer.domElement );
//设置通过鼠标滚轮能移动到的最近和最远距离
controls.minDistance = 20;
controls.maxDistance = 50;
//最大极角默认是Math.PI,最小极角默认是0。它们控制可以上下翻转的角度
controls.maxPolarAngle = Math.PI / 2;
/*
环境光,提供的是在不同位置和方向上强度都相同的光源,它的颜色会添加到整个场景和所有对象的当前颜色上,相当于光照模型中各物体之间的反射光,因此通常用来表现光强中非常弱的那部分光
AmbientLight( color, intensity)
color 光源的颜色
intensity 光照强度,默认为1
*/
scene.add( new THREE.AmbientLight( 0x222222 ) );//0x222222,接近黑色
/*
点光源,空间中的一点,朝所有方向发射光线
PointLight(color, intensity, distance, decay)
color 光源的颜色
intensity 光照强度,默认为1
distance 光照射的距离
decay 衰减系数
*/
var light = new THREE.PointLight( 0xffffff, 1 );
camera.add( light );
//AxisHelper(坐标轴)只能在WebGLRenderer下显示,不能在CanvasRenderer下显示
scene.add( new THREE.AxisHelper( 20 ) );
//纹理加载器
var loader = new THREE.TextureLoader();
var texture = loader.load( 'textures/sprites/disc.png' );//这是一个白色的圆,外部透明
group = new THREE.Group();
scene.add( group );
// points
//Dodecahedron(正12面体,每个面均是正五边形),10为外接球半径
var pointsGeometry = new THREE.DodecahedronGeometry( 10 );
for ( var i = 0; i < pointsGeometry.vertices.length; i ++ ) {
//add是向量相加,multiplyScalar是向量乘以一个标量
//pointsGeometry.vertices[ i ].add( randomPoint().multiplyScalar( 2 ) ); // wiggle(扭动) the points
}
//PointsMaterial是WebGLRenderer下的粒子渲染器
var pointsMaterial = new THREE.PointsMaterial( {
//color和map同时设置的话,color和map的颜色会混合叠加(blender)
color: 0x0080ff,//蓝色
map: texture,
size: 1,
/*
当像素的透明度小于alphaTest阈值的时候,它就会被fragment shader舍弃
这是为了处理前面颜色为透明,但是依然保存在缓冲区,这样就会显示为白色,而不会显示后面物体的颜色
*/
alphaTest: 0.5
} );
//粒子系统
var points = new THREE.Points( pointsGeometry, pointsMaterial );
group.add( points );
// convex hull(凸状外壳)
//这种材质会考虑光照的影响,可以用来创建颜色暗淡的、不光亮的物体
var meshMaterial = new THREE.MeshLambertMaterial( {
color: 0xffffff,
opacity: 0.5,
//只有设置tansparent为true,透明度才会有效
transparent: true
} );
//通过改造后的原始几何体,创建凸几何体
var meshGeometry = new THREE.ConvexGeometry( pointsGeometry.vertices );
/*
为了达到透视效果,必须渲染内部和外部,需要分别添加两个side。
注意:这边不能使用DoubleSide,因为效果差距很大
*/
mesh = new THREE.Mesh( meshGeometry, meshMaterial );
mesh.material.side = THREE.BackSide; // back faces
mesh.renderOrder = 0;
group.add( mesh );
mesh = new THREE.Mesh( meshGeometry, meshMaterial.clone() );
mesh.material.side = THREE.FrontSide; // front faces
mesh.renderOrder = 1;
group.add( mesh );
/*
//双面渲染无法实现透视效果
//mesh = new THREE.Mesh( pointsGeometry, meshMaterial );
mesh = new THREE.Mesh( meshGeometry, meshMaterial );
mesh.material.side = THREE.DoubleSide;
group.add( mesh );
*/
window.addEventListener( 'resize', onWindowResize, false );
}
//随机一个在半径为1的球内的点
function randomPoint() {
return new THREE.Vector3( THREE.Math.randFloat( - 1, 1 ), THREE.Math.randFloat( - 1, 1 ), THREE.Math.randFloat( - 1, 1 ) );
}
function onWindowResize() {
//重新设置相机的宽高比。如果宽高比不对,那么正方形可能就不是正方形了
camera.aspect = window.innerWidth / window.innerHeight;
//更新透视相机的投影矩阵
camera.updateProjectionMatrix();
//更新待渲染场景的大小
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
requestAnimationFrame( animate );
//按照右手螺旋定则绕Y轴旋转
group.rotation.y += 0.005;
render();
}
function render() {
renderer.render( scene, camera );
}
</script>
</body>
</html>