(十九) THREE.Material 知识详解

THREE.Material 是 Three.js 中的一个基类,用于定义三维物体的外观属性,如颜色、纹理、透明度等。Three.js 提供了多种不同的材质类型,每种材质都有其独特的特性和用途,以满足不同的渲染需求。THREE.Material 本身是一个抽象基类,实际使用的材质都是其子类。


常见的材质类型

以下是 Three.js 中一些常见的材质类型及其特点:

1. THREE.MeshBasicMaterial

  • 特性:不考虑光照,适用于不需要光照效果的情况。
  • 属性:主要属性包括颜色 (color)、透明度 (opacity) 和透明模式 (transparent)。

示例

var material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });

2. THREE.MeshLambertMaterial

  • 特性:使用 Lambertian 反射模型,模拟漫反射效果。
  • 属性:除了颜色和透明度外,还包括环境贴图 (envMap)、法线贴图 (normalMap) 等。

示例

var material = new THREE.MeshLambertMaterial({ color: 0x00ff00 });
3. THREE.MeshPhongMaterial

  • 特性:扩展了 Lambertian 反射模型,支持高光效果。
  • 属性:包括高光强度 (shininess) 和高光颜色 (specular)。

示例

var material = new THREE.MeshPhongMaterial({ color: 0x00ff00, specular: 0x111111, shininess: 10 });
4. THREE.MeshStandardMaterial

  • 特性:物理基础的材质,支持金属度和粗糙度。
  • 属性:包括金属度 (metalness)、粗糙度 (roughness) 和环境贴图 (envMap)。

示例

var material = new THREE.MeshStandardMaterial({ color: 0x00ff00, metalness: 0.5, roughness: 0.5 });
5. THREE.MeshPhysicalMaterial

  • 特性:扩展了标准材质,提供更多物理属性。
  • 属性:包括透明度 (transparency)、折射率 (ior) 和发射光 (emissive)。

示例

var material = new THREE.MeshPhysicalMaterial({ color: 0x00ff00, metalness: 0.5, roughness: 0.5, ior: 1.5 });
6. THREE.ShaderMaterial

  • 特性:允许用户自定义着色器代码。
  • 属性:包括顶点着色器 (vertexShader) 和片段着色器 (fragmentShader)。

示例

var vertexShader = `
  varying vec3 vPosition;
  void main() {
    vPosition = position;
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
  }
`;

var fragmentShader = `
  uniform vec3 color;
  varying vec3 vPosition;
  void main() {
    gl_FragColor = vec4(color, 1.0);
  }
`;

var material = new THREE.ShaderMaterial({
  uniforms: { 'color': { value: new THREE.Color(0x00ff00) } },
  vertexShader: vertexShader,
  fragmentShader: fragmentShader
});
材质的基本属性

不论哪种材质类型,都有一些基本的属性是共有的:

  • color:物体的颜色。
  • map:基础颜色贴图。
  • alphaMap:透明度贴图。
  • bumpMap:凹凸贴图。
  • normalMap:法线贴图。
  • displacementMap:置换贴图。
  • specularMap:高光贴图。
  • emissive:物体的自发光颜色。
  • emissiveMap:自发光贴图。
  • transparent:是否开启透明模式。
  • opacity:物体的透明度。
  • side:指定材质在哪一面渲染,可以是 THREE.FrontSideTHREE.BackSide THREE.DoubleSide
  • depthTest:是否进行深度测试。
  • depthWrite:是否写入深度缓冲区。
  • blending:混合模式,如 THREE.AdditiveBlendingTHREE.SubtractiveBlending 等。
  • vertexColors:是否启用顶点颜色。
示例代码

以下是一个简单的示例,展示如何在 Three.js 场景中使用不同的材质:

// 创建场景
var scene = new THREE.Scene();

// 创建相机
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;

// 创建渲染器
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// 创建一个立方体
var geometry = new THREE.BoxGeometry(1, 1, 1);

// MeshBasicMaterial
var materialBasic = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
var cubeBasic = new THREE.Mesh(geometry, materialBasic);
cubeBasic.position.x = -2;
scene.add(cubeBasic);

// MeshLambertMaterial
var materialLambert = new THREE.MeshLambertMaterial({ color: 0x0000ff });
var cubeLambert = new THREE.Mesh(geometry, materialLambert);
cubeLambert.position.x = 0;
scene.add(cubeLambert);

// MeshPhongMaterial
var materialPhong = new THREE.MeshPhongMaterial({ color: 0xff0000, specular: 0x111111, shininess: 10 });
var cubePhong = new THREE.Mesh(geometry, materialPhong);
cubePhong.position.x = 2;
scene.add(cubePhong);

// 创建一个地面平面
var planeGeometry = new THREE.PlaneGeometry(20, 20, 1, 1);
var planeMaterial = new THREE.MeshStandardMaterial({ color: 0x808080 });
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.rotation.x = -Math.PI / 2;
plane.position.y = -0.5;
scene.add(plane);

// 创建平行光
var directionalLight = new THREE.DirectionalLight(0xffffff, 1.0);
directionalLight.position.set(1, 1, 1).normalize();
scene.add(directionalLight);

// 渲染函数
function animate() {
    requestAnimationFrame(animate);

    // 旋转立方体
    cubeBasic.rotation.x += 0.01;
    cubeBasic.rotation.y += 0.01;
    
    cubeLambert.rotation.x += 0.01;
    cubeLambert.rotation.y += 0.01;
    
    cubePhong.rotation.x += 0.01;
    cubePhong.rotation.y += 0.01;

    renderer.render(scene, camera);
}
animate();

在这个示例中,我们创建了三个不同的立方体,并分别为它们指定了不同的材质类型:THREE.MeshBasicMaterialTHREE.MeshLambertMaterial THREE.MeshPhongMaterial。通过观察这三个立方体在平行光照射下的表现,可以对比不同材质之间的差异。

你可能感兴趣的:(three.js,Three.js,vue)