THREE.MeshBasicMaterial
案例
结果
分析
💡 熟悉所有材质的共有属性和基本材质的特殊属性
- 上述场景中包含着地面、三个物体(页面只显示一个,通过GUI来选择哪个物体显示)、光源、性能插件、GUI
创建场景、摄像机、渲染器
创建两个渲染器,因为wireframeLinecap(线框线段端点)、wireframeLinejoin(线框线段连接点)两个属性,webGLRenderer不支持该属性
//场景
var scene;
function initScene() {
scene = new THREE.Scene();
}
//摄像机
var camera;
function initCamera() {
camera = new THREE.PerspectiveCamera(45,window.innerWidth / window.innerHeight,0.1,1000);
camera.position.set(-20,50,40);
camera.lookAt(new THREE.Vector3(10,0,0));
scene.add(camera);
}
//渲染器
var webGLRenderer,canvasRenderer,renderer;
function initRenderer() {
webGLRenderer = new THREE.WebGLRenderer();
webGLRenderer.setClearColor(new THREE.Color(0x000000));
webGLRenderer.setSize(window.innerWidth,window.innerHeight);
webGLRenderer.shadowMap.enabled = true;
canvasRenderer = new THREE.CanvasRenderer();
canvasRenderer.setSize(window.innerWidth,window.innerHeight);
renderer = webGLRenderer;
//将渲染的结果添加到 HTML 框架中的div元素中
document.getElementById("webgl-output").appendChild(renderer.domElement);
}
添加性能插件、光源、摄像机控制器
//初始化性能插件
var stats;
function initStats(){
stats = new Stats();
document.getElementById("webgl-output").appendChild(stats.domElement);
}
//光源
function initLight(){
var ambientLight = new THREE.AmbientLight(0x0c0c0c);
scene.add(ambientLight);
var spotLight = new THREE.SpotLight("#ffffff");
spotLight.position.set(-40,60,-10);
spotLight.castShadow = true;
spotLight.shadow.mapSize = new THREE.Vector2(1024,1024);
spotLight.shadow.camera.far = 130;
spotLight.shadow.camera.near = 40;
scene.add(spotLight);
}
//用户交互插件 鼠标左键按住旋转,右键按住平移,滚轮缩放
var controls;
function initControls() {
controls = new THREE.OrbitControls( camera, renderer.domElement );
//是否可以缩放
controls.enableZoom = true;
//是否自动旋转
controls.autoRotate = true;
//设置相机距离原点的最远距离
controls.minDistance = 1;
//设置相机距离原点的最远距离
controls.maxDistance = 200;
//是否开启右键拖拽
controls.enablePan = true;
}
添加物体对象
//模型
var axes,cube,plane,meshMaterial,sphere,ground,selectedMesh;
function initModels(){
//坐标轴
axes = new THREE.AxesHelper(50);
scene.add(axes);
//材质
meshMaterial = new THREE.MeshBasicMaterial({
color:0x7777ff,
name: "Basic Material",
flatShading: true,
});
//地面
var groundGeometry = new THREE.PlaneGeometry(100,100,4,4);
var groundMaterial = new THREE.MeshBasicMaterial({
color:0x777777,
})
ground = new THREE.Mesh(groundGeometry,groundMaterial);
ground.rotation.x = -Math.PI / 2;
ground.position.y = -20;
ground.receiveShadow = true;
scene.add(ground);
//立方体
var cubeGeometry = new THREE.CubeGeometry(15,15,15);
cube = new THREE.Mesh(cubeGeometry,meshMaterial);
cube.position.set(0,3,2);
cube.castShadow = true;
scene.add(cube);
//球
var sphereGeometry = new THREE.SphereGeometry(14,20,20);
sphere = new THREE.Mesh(sphereGeometry,meshMaterial);
sphere.position.set(0,3,2);
sphere.castShadow = true;
// scene.add(sphere);
//平面
var planeGeometry = new THREE.PlaneGeometry(14,14,4,4);
plane = new THREE.Mesh(planeGeometry,meshMaterial);
plane.position = sphere.position;
selectedMesh = cube;
}
设置GUI
var MBM,MaterialGui,gui;
function initMBM(){
MBM = cube.material;
MBM = new function(){
this.id = cube.id;
this.uuid = cube.uuid;
this.name = "Basic Material";
this.opacity = meshMaterial.opacity;
this.transparent = meshMaterial.transparent;
this.overdraw = meshMaterial.overdraw;
this.visible = meshMaterial.visible;
this.side = "FrontSide";
this.colorWrite = meshMaterial.colorWrite;
this.flatShading = meshMaterial.flatShading;
this.premultipliedAlpha = meshMaterial.premultipliedAlpha;
this.dithering = meshMaterial.dithering;
this.shadowSide = "";
this.vertexColors = "NoColors";
this.fog = true;
this.color = meshMaterial.color.getStyle();
this.wireframe = meshMaterial.wireframe;
this.wireframeLinewidth = 6.9;
this.wireframeLinecap = "round";
this.wireframeLinejoin = "round";
this.switchRenderer = function () {
if (renderer instanceof THREE.WebGLRenderer) {
renderer = canvasRenderer;
document.getElementById("webgl-output").innerHTML = '';
document.getElementById("webgl-output").appendChild(renderer.domElement);
} else {
renderer = webGLRenderer;
document.getElementById("webgl-output").innerHTML = '';
document.getElementById("webgl-output").appendChild(renderer.domElement);
}
}
this.selectedMesh = "cube";
};
gui = new dat.GUI();
MaterialGui = gui.addFolder("THREE.Material");
MaterialGui.add(MBM,'id');
MaterialGui.add(MBM,'uuid');
MaterialGui.add(MBM,'name');
MaterialGui.add(MBM,'opacity',0,1,0.01).onChange(function (e){
meshMaterial.opacity = e;
});
MaterialGui.add(MBM,'transparent').onChange(function (e){
meshMaterial.transparent = e;
});
MaterialGui.add(MBM,'overdraw',0,1,0.01).onChange(function (e){
meshMaterial.overdraw = e;
});
MaterialGui.add(MBM,'visible').onChange(function (e){
meshMaterial.visible = e;
});
MaterialGui.add(MBM,'side',{FrontSide:0,BackSide:1,BothSides:2}).onChange(function (e){
meshMaterial.side = parseInt(e);
});
MaterialGui.add(MBM,'colorWrite').onChange(function (e){
meshMaterial.colorWrite = e;
});
MaterialGui.add(MBM,'flatShading').onChange(function (e){
meshMaterial.flatShading = e;
meshMaterial.needsUpdate = true;
});
MaterialGui.add(MBM,'premultipliedAlpha').onChange(function (e){
meshMaterial.premultipliedAlpha = e;
});
MaterialGui.add(MBM,'dithering').onChange(function (e){
meshMaterial.dithering = e;
});
MaterialGui.add(MBM,'shadowSide',{FrontSide:0,BackSide:1,BothSide:2}).onChange(function (e){
meshMaterial.shadowSide = parseInt(e);
});
MaterialGui.add(MBM,'vertexColors', {NoColors: THREE.NoColors, FaceColors: THREE.FaceColors,
VertexColors: THREE.VertexColors}).onChange(function (vertexColors) {
meshMaterial.vertexColors = parseInt(vertexColors);
});
MaterialGui.add(MBM,'fog');
//THREE.MeshBasicMaterialGUI
var MeshBasicMaterialGUI = gui.addFolder("THREE.MeshBasicMaterial");
MeshBasicMaterialGUI.addColor(MBM,'color').onChange(function (e) {
meshMaterial.color.getStyle(e);
});
MeshBasicMaterialGUI.add(MBM,'wireframe').onChange(function (e) {
meshMaterial.wireframe = e;
});
MeshBasicMaterialGUI.add(MBM,'wireframeLinewidth',0,20).onChange(function (e){
meshMaterial.wireframeLinewidth = e;
});
MeshBasicMaterialGUI.add(MBM,'wireframeLinecap',['butt','round','square']).onChange(function (e) {
meshMaterial.wireframeLinecap = e;
});
MeshBasicMaterialGUI.add(MBM,'wireframeLinejoin',['round','bevel','miter']).onChange(function (e) {
meshMaterial.wireframeLinejoin = e;
});
gui.add(MBM,'switchRenderer');
gui.add(MBM,'selectedMesh',['cube','sphere','plane']).onChange(function (e){
scene.remove(cube);
scene.remove(sphere);
scene.remove(plane);
switch (e){
case 'cube':
scene.add(cube);
selectedMesh = cube;
break;
case 'sphere':
scene.add(sphere);
selectedMesh = sphere;
break;
case 'plane':
scene.add(plane);
selectedMesh = plane;
break;
}
});
}
正确渲染以及窗口自适应函数
function render() {
renderer.render(scene,camera);
}
function animate(){
stats.update();
selectedMesh.rotation.y +=0.02;
render();
requestAnimationFrame(animate);
}
//窗口自适应
function windowOnresize(){
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth,window.innerHeight);
}
完整代码
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name=viewport
content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no,minimal-ui">
<script type="text/javascript" src="../libs/three/three.js"></script>
<script type="text/javascript" src="../libs/three/controls/OrbitControls.js"></script>
<script type="text/javascript" src="../libs/three/renderers/CanvasRenderer.js"></script>
<script type="text/javascript" src="../libs/three/renderers/Projector.js"></script>
<script type="text/javascript" src="../libs/util/dat.gui.js"></script>
<script type="text/javascript" src="../libs/util/Stats.js"></script>
<script type="text/javascript" src="js/MeshBasicMaterial.js"></script>
<link rel="stylesheet" href="../css/default.css">
<title>Title</title>
<style></style>
<script></script>
</head>
<body>
<div id="webgl-output">
</div>
<script type="text/javascript">
(function (){
draw()
})();
</script>
</body>
</html>
//场景
var scene;
function initScene() {
scene = new THREE.Scene();
}
//摄像机
var camera;
function initCamera() {
camera = new THREE.PerspectiveCamera(45,window.innerWidth / window.innerHeight,0.1,1000);
camera.position.set(-20,50,40);
camera.lookAt(new THREE.Vector3(10,0,0));
scene.add(camera);
}
//渲染器
var webGLRenderer,canvasRenderer,renderer;
function initRenderer() {
webGLRenderer = new THREE.WebGLRenderer();
webGLRenderer.setClearColor(new THREE.Color(0x000000));
webGLRenderer.setSize(window.innerWidth,window.innerHeight);
webGLRenderer.shadowMap.enabled = true;
canvasRenderer = new THREE.CanvasRenderer();
canvasRenderer.setSize(window.innerWidth,window.innerHeight);
renderer = webGLRenderer;
//将渲染的结果添加到 HTML 框架中的div元素中
document.getElementById("webgl-output").appendChild(renderer.domElement);
}
//初始化性能插件
var stats;
function initStats(){
stats = new Stats();
document.getElementById("webgl-output").appendChild(stats.domElement);
}
//光源
function initLight(){
var ambientLight = new THREE.AmbientLight(0x0c0c0c);
scene.add(ambientLight);
var spotLight = new THREE.SpotLight("#ffffff");
spotLight.position.set(-40,60,-10);
spotLight.castShadow = true;
spotLight.shadow.mapSize = new THREE.Vector2(1024,1024);
spotLight.shadow.camera.far = 130;
spotLight.shadow.camera.near = 40;
scene.add(spotLight);
}
//模型
var axes,cube,plane,meshMaterial,sphere,ground,selectedMesh;
function initModels(){
//坐标轴
axes = new THREE.AxesHelper(50);
scene.add(axes);
//材质
meshMaterial = new THREE.MeshBasicMaterial({
color:0x7777ff,
name: "Basic Material",
flatShading: true,
});
//地面
var groundGeometry = new THREE.PlaneGeometry(100,100,4,4);
var groundMaterial = new THREE.MeshBasicMaterial({
color:0x777777,
})
ground = new THREE.Mesh(groundGeometry,groundMaterial);
ground.rotation.x = -Math.PI / 2;
ground.position.y = -20;
ground.receiveShadow = true;
scene.add(ground);
//立方体
var cubeGeometry = new THREE.CubeGeometry(15,15,15);
cube = new THREE.Mesh(cubeGeometry,meshMaterial);
cube.position.set(0,3,2);
cube.castShadow = true;
scene.add(cube);
//球
var sphereGeometry = new THREE.SphereGeometry(14,20,20);
sphere = new THREE.Mesh(sphereGeometry,meshMaterial);
sphere.position.set(0,3,2);
sphere.castShadow = true;
// scene.add(sphere);
//平面
var planeGeometry = new THREE.PlaneGeometry(14,14,4,4);
plane = new THREE.Mesh(planeGeometry,meshMaterial);
plane.position = sphere.position;
selectedMesh = cube;
}
//用户交互插件 鼠标左键按住旋转,右键按住平移,滚轮缩放
var controls;
function initControls() {
controls = new THREE.OrbitControls( camera, renderer.domElement );
// 如果使用animate方法时,将此函数删除
//controls.addEventListener( 'change', render );
// 使动画循环使用时阻尼或自转 意思是否有惯性
controls.enableDamping = true;
//动态阻尼系数 就是鼠标拖拽旋转灵敏度
//controls.dampingFactor = 0.25;
//是否可以缩放
controls.enableZoom = true;
//是否自动旋转
controls.autoRotate = true;
//设置相机距离原点的最远距离
controls.minDistance = 1;
//设置相机距离原点的最远距离
controls.maxDistance = 200;
//是否开启右键拖拽
controls.enablePan = true;
}
function render() {
renderer.render(scene,camera);
}
function animate(){
stats.update();
selectedMesh.rotation.y +=0.02;
render();
requestAnimationFrame(animate);
}
//窗口自适应
function windowOnresize(){
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth,window.innerHeight);
}
var MBM,MaterialGui,gui;
function initMBM(){
MBM = cube.material;
MBM = new function(){
this.id = cube.id;
this.uuid = cube.uuid;
this.name = "Basic Material";
this.opacity = meshMaterial.opacity;
this.transparent = meshMaterial.transparent;
this.overdraw = meshMaterial.overdraw;
this.visible = meshMaterial.visible;
this.side = "FrontSide";
this.colorWrite = meshMaterial.colorWrite;
this.flatShading = meshMaterial.flatShading;
this.premultipliedAlpha = meshMaterial.premultipliedAlpha;
this.dithering = meshMaterial.dithering;
this.shadowSide = "";
this.vertexColors = "NoColors";
this.fog = true;
this.color = meshMaterial.color.getStyle();
this.wireframe = meshMaterial.wireframe;
this.wireframeLinewidth = 6.9;
this.wireframeLinecap = "round";
this.wireframeLinejoin = "round";
this.switchRenderer = function () {
if (renderer instanceof THREE.WebGLRenderer) {
renderer = canvasRenderer;
document.getElementById("webgl-output").innerHTML = '';
document.getElementById("webgl-output").appendChild(renderer.domElement);
} else {
renderer = webGLRenderer;
document.getElementById("webgl-output").innerHTML = '';
document.getElementById("webgl-output").appendChild(renderer.domElement);
}
}
this.selectedMesh = "cube";
};
gui = new dat.GUI();
MaterialGui = gui.addFolder("THREE.Material");
MaterialGui.add(MBM,'id');
MaterialGui.add(MBM,'uuid');
MaterialGui.add(MBM,'name');
MaterialGui.add(MBM,'opacity',0,1,0.01).onChange(function (e){
meshMaterial.opacity = e;
});
MaterialGui.add(MBM,'transparent').onChange(function (e){
meshMaterial.transparent = e;
});
MaterialGui.add(MBM,'overdraw',0,1,0.01).onChange(function (e){
meshMaterial.overdraw = e;
});
MaterialGui.add(MBM,'visible').onChange(function (e){
meshMaterial.visible = e;
});
MaterialGui.add(MBM,'side',{FrontSide:0,BackSide:1,BothSides:2}).onChange(function (e){
meshMaterial.side = parseInt(e);
});
MaterialGui.add(MBM,'colorWrite').onChange(function (e){
meshMaterial.colorWrite = e;
});
MaterialGui.add(MBM,'flatShading').onChange(function (e){
meshMaterial.flatShading = e;
meshMaterial.needsUpdate = true;
});
MaterialGui.add(MBM,'premultipliedAlpha').onChange(function (e){
meshMaterial.premultipliedAlpha = e;
});
MaterialGui.add(MBM,'dithering').onChange(function (e){
meshMaterial.dithering = e;
});
MaterialGui.add(MBM,'shadowSide',{FrontSide:0,BackSide:1,BothSide:2}).onChange(function (e){
meshMaterial.shadowSide = parseInt(e);
});
MaterialGui.add(MBM,'vertexColors', {NoColors: THREE.NoColors, FaceColors: THREE.FaceColors,
VertexColors: THREE.VertexColors}).onChange(function (vertexColors) {
meshMaterial.vertexColors = parseInt(vertexColors);
});
MaterialGui.add(MBM,'fog');
//THREE.MeshBasicMaterialGUI
var MeshBasicMaterialGUI = gui.addFolder("THREE.MeshBasicMaterial");
MeshBasicMaterialGUI.addColor(MBM,'color').onChange(function (e) {
meshMaterial.color.getStyle(e);
});
MeshBasicMaterialGUI.add(MBM,'wireframe').onChange(function (e) {
meshMaterial.wireframe = e;
});
MeshBasicMaterialGUI.add(MBM,'wireframeLinewidth',0,20).onChange(function (e){
meshMaterial.wireframeLinewidth = e;
});
MeshBasicMaterialGUI.add(MBM,'wireframeLinecap',['butt','round','square']).onChange(function (e) {
meshMaterial.wireframeLinecap = e;
});
MeshBasicMaterialGUI.add(MBM,'wireframeLinejoin',['round','bevel','miter']).onChange(function (e) {
meshMaterial.wireframeLinejoin = e;
});
gui.add(MBM,'switchRenderer');
gui.add(MBM,'selectedMesh',['cube','sphere','plane']).onChange(function (e){
scene.remove(cube);
scene.remove(sphere);
scene.remove(plane);
switch (e){
case 'cube':
scene.add(cube);
selectedMesh = cube;
break;
case 'sphere':
scene.add(sphere);
selectedMesh = sphere;
break;
case 'plane':
scene.add(plane);
selectedMesh = plane;
break;
}
});
// gui.domElement.style.position = 'absolute';
// gui.domElement.style.right = "300px";
}
function draw(){
initScene();
initCamera();
initRenderer();
initStats();
initLight();
initModels();
initControls();
initMBM();
animate();
window.onresize = windowOnresize;
}
注意事项
💡这个例子里可以设置side属性,通过这个属性可以指定THREE.Geometry对象的哪个面应用材质。
- 可以通过选择plane(平面)网格验证该属性。
- side属性设置为FrontSide或者BackSide时,平面旋转时会有一半的时间看不见。
- side属性设置为BothSides时,这个平面始终都能看见(因为几何体两面都有材质)。
- 设置为BothSides时,由于两面都有材质,所以渲染需要做更多的工作,对场景的性能会有影响。