Skip to content

高光网格材质MeshPhongMaterial

🕒 Published at:

高光网格材质MeshPhongMaterial和基础网格材质MeshBasicMaterial、漫反射网格材质MeshLambertMaterial一样都是网格模型的Mesh的材质。

高光网格材质MeshPhongMaterial和漫反射网格材质MeshLambertMaterial一样会受到光照的影响。

对光照的反射特点

MeshPhongMaterial和MeshLambertMaterial都会收到光照的影响区别在于,对光线反射方式有差异。

MeshPhongMaterial可以实现MeshLambertMaterial不能实现的高光反射效果。对于高光效果,你可以想象一下,你在太阳下面观察一辆车,你会发现在特定角度和位置,你可以看到车表面某个局部区域非常高亮。

MeshPhongMaterial可以提供一个镜面反射效果,可以类比你生活中拿一面镜子,放在太阳光下,调整角度,可以把太阳光反射到其它地方,如果反射光对着眼睛,也就是反射光线和视线平行的时候,会非常刺眼。

MeshLambertMaterial对应的Mesh受到光线照射,没有镜面反射的效果,只是一个漫反射,也就是光线向四周反射。

关键代码

通过MeshPhongMaterial的高光亮度.shininess属性,可以控制高光反射效果。.specular属性可以控制高光颜色。

js
// 模拟镜面反射,产生一个高光效果
const material = new THREE.MeshPhongMaterial({
  color: 0xff0000,
  shininess: 20, //高光部分的亮度,默认30
  specular: 0xeeeeee //高光部分的颜色
});

效果

代码

js
// 引入three.js
import * as THREE from 'three';
// 引入轨道控制器扩展库OrbitControls.js
import {
    OrbitControls
} from 'three/addons/controls/OrbitControls.js';
/**
 * 创建3D场景对象Scene
 */
const scene = new THREE.Scene();

// 创建网格模型

//BoxGeometry:长方体
// const geometry = new THREE.BoxGeometry(100, 100, 100);
// SphereGeometry:球体
const geometry = new THREE.SphereGeometry(50);

// MeshBasicMaterial不受光照影响
// const material = new THREE.MeshBasicMaterial({
//     color: 0xff0000, 
// });

// 漫反射,没有镜面反射效果,不会产生局部高光效果
// const material = new THREE.MeshLambertMaterial({
//     color: 0xff0000, 
// });

// 模拟镜面反射,产生一个高光效果
const material = new THREE.MeshPhongMaterial({
    color: 0xff0000,
    shininess: 20, //高光部分的亮度,默认30
    specular: 0x444444, //高光部分的颜色
});

const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);

//辅助观察的坐标系
const axesHelper = new THREE.AxesHelper(100);
scene.add(axesHelper);


//光源设置
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
directionalLight.position.set(400, 200, 300);
scene.add(directionalLight);
const ambient = new THREE.AmbientLight(0xffffff, 0.4);
scene.add(ambient);


//渲染器和相机
const width = window.innerWidth;
const height = window.innerHeight;
const camera = new THREE.PerspectiveCamera(30, width / height, 1, 3000);
camera.position.set(292, 223, 185);
camera.lookAt(0, 0, 0);


const renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);
document.body.appendChild(renderer.domElement);



// 设置相机控件轨道控制器OrbitControls
const controls = new OrbitControls(camera, renderer.domElement);


// 渲染循环
function render() {
    renderer.render(scene, camera);
    requestAnimationFrame(render);
}
render();


// 画布跟随窗口变化
window.onresize = function () {
    renderer.setSize(window.innerWidth, window.innerHeight);
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
};