Teste de função do mapa ambiental
MeshPhysicalMaterial
Camada de verniz
MeshPhysicalMaterial
Ambos MeshStandarMaterial
são materiais PBR com atributos de metalicidade metalness
e rugosidade . Eles são um subconjunto dos materiais PBR. Além de herdarem esses atributos, também agregam verniz, transmitância de luz, refletividade, brilho, índice de refração, etc.roughness
MeshPhysicalMaterial
MeshStandarMaterial
Propriedades da camada de verniz.clearcoat
O atributo da camada de verniz .clearcoat
pode ser usado para simular uma camada de molde transparente escovada na superfície do objeto. .clearcoat
O intervalo é de 0 a 1 e o padrão é 0.
const material = new THREE.MeshPhysicalMaterial( {
clearcoat: 1.0,//物体表面清漆层或者说透明涂层的厚度
} );
Sobre o material MeshPhysicalMaterial
MeshPhysicalMaterial
É um tipo de material em Three.js. É um material de renderização com base física (PBR) que pode simular a iluminação e o reflexo do material no mundo real. Ele suporta materiais metálicos e não metálicos e pode definir atributos como rugosidade, metalicidade, oclusão de ambiente, mapa normal e mapa de deslocamento para obter efeitos de renderização mais realistas. MeshPhysicalMaterial
Ele também suporta reflexão especular e transparência, que podem ser usadas para criar vidro, água, metal e outros materiais realistas. Ao utilizá MeshPhysicalMaterial
-lo, é preciso observar que ele requer muitos cálculos e pode afetar o desempenho, por isso precisa ser otimizado de acordo com a situação real.
Rugosidade da camada de verniz.clearcoatRoughness
Refere-se à faixa de rugosidade da camada transparente da superfície que é 0-1.
cenas a serem usadas
Este efeito pode ser usado para fazer modelos de carros, como janelas, caixilhos, vidros, etc. Você pode simular
o efeito da pintura da carroceria por meio das propriedades da camada de verniz .clearcoat
e das propriedades de rugosidade da camada de verniz do material PBR.clearcoatRoughness
const mesh = gltf.scene.getObjectByName('外壳');
mesh.material = new THREE.MeshPhysicalMaterial( {
clearcoat: 1.0,//物体表面清漆层或者说透明涂层的厚度
clearcoatRoughness: 0.1,//透明涂层表面的粗糙度
} );
A situação real pode ser ajustada de acordo com o modelo. Os ajustes podem ser depurados por meio da GUI e os efeitos reais de depuração podem ser visualizados no capítulo anterior.
Transmissão de material físico
Para simular melhor os efeitos visuais do vidro e do plástico translúcido, você pode usar este atributo em vez do atributo transparente comum. .opacity
Use .transmission
o atributo para definir a transparência da malha, que pode manter alta refletividade mesmo sob transmissão completa.
Como usar:
const geometry = new THREE.TorusKnotGeometry(10, 3, 100, 16);
const material = new THREE.MeshPhysicalMaterial({
color: 0x30cff8,
transmission: 1,
});
const torusKnot = new THREE.Mesh(geometry, material);
scene.add(torusKnot);
Efeito:
índice de refração.ior
O índice de refração de materiais não metálicos varia de 1,0 a 2,333. O valor padrão é 1,5.
const geometry = new THREE.TorusKnotGeometry(10, 3, 100, 16);
const material = new THREE.MeshPhysicalMaterial({
color: 0x30cff8,
transmission: 1,
ior:1.5,
});
const torusKnot = new THREE.Mesh(geometry, material);
scene.add(torusKnot);
Analisar material gltf
Geralmente, o material de malha padrão é usado por padrão MeshStandardMaterial
. Se alguns materiais gltf tiverem atributos como .clearcoat
, .transmission
etc., e o material de malha padrão MeshStandardMaterial
não puder ser expresso, o material de malha física será usado MeshPhysicalMaterial
para analisar o material gltf.
gltf.scene.traverse(function(obj) {
if (obj.isMesh) {
console.log('obj.material',obj.material);
}
});
console.log('外壳',mesh1.material);
console.log('玻璃',mesh2.material);
Código completo:
/*
* @Author: SouthernWind
* @Date: 2023-06-14 16:38:59
* @Last Modified by: SouthernWind
* @Last Modified time: 2023-06-14 16:39:32
*/
<template>
<div class="container" ref="container"></div>
</template>
<script setup>
import * as THREE from "three";
// 轨道
import {
OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import {
GLTFLoader } from "three/addons/loaders/GLTFLoader.js";
import {
GUI } from "three/addons/libs/lil-gui.module.min.js";
import {
ref, reactive, onMounted } from "vue";
// 三个必备的参数
let scene,camera,renderer,controls,mesh,material,group,texture,gui,textureCube;
onMounted(() => {
// 外层需要获取到dom元素以及浏览器宽高,来对画布设置长宽
// clientWidth等同于container.value.clientWidth
let container = document.querySelector(".container");
const {
clientWidth, clientHeight } = container;
console.log(clientHeight);
// 首先需要获取场景,这里公共方法放在init函数中
const init = () => {
scene = new THREE.Scene();
// 给相机设置一个背景
scene.background = new THREE.Color(0xaaaaaa);
// 透视投影相机PerspectiveCamera
// 支持的参数:fov, aspect, near, far
camera = new THREE.PerspectiveCamera(60,clientWidth / clientHeight,0.001,6000);
// 相机坐标
camera.position.set(30, 30, 30);
// 相机观察目标
camera.lookAt(scene.position);
// 渲染器
renderer = new THREE.WebGLRenderer({
antialias: true,
});
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
// 渲染多大的地方
renderer.setSize(clientWidth, clientHeight);
/* renderer.outputEncoding = THREE.sRGBEncoding; */
// const axesHelper = new THREE.AxesHelper(150);
// scene.add(axesHelper);
container.appendChild(renderer.domElement);
addBox();
console.log("查看当前屏幕设备像素比", window.devicePixelRatio);
};
init();
function addBox() {
gui = new GUI();
const geometry = new THREE.TorusKnotGeometry(10, 3, 100, 16);
const material = new THREE.MeshPhysicalMaterial({
color: 0x30cff8,
metalness: 0,
roughness: 0,
transmission: 0.5,
ior: 1.5,
});
const torusKnot = new THREE.Mesh(geometry, material);
scene.add(torusKnot);
gui.add(material, "transmission", 0, 1);
gui.add(material, "ior", 1, 2.333);
}
// 相机控件
const control = () => {
controls = new OrbitControls(camera, renderer.domElement);
controls.addEventListener("change", function () {
});
};
control();
// 光源
const linght = () => {
const pointLight = new THREE.PointLight(0xffffff, 1.0);
// pointLight.position.set(400, 0, 0);//点光源放在x轴上
pointLight.position.set(100, 60, 50); //设置光源的位置
// 光源和网格模型Mesh对应一样是三维场景的一部分,自然需要添加到三维场景中才能起作用。
scene.add(pointLight); // 添加光源到场景中
/* const pointLight = new THREE.AmbientLight(0xffffff, 1.0);
pointLight.position.set(150, 150, 150);
scene.add(pointLight); */
const pointLightHelper = new THREE.PointLightHelper(pointLight, 1);
scene.add(pointLightHelper);
};
linght();
const render = () => {
renderer.render(scene, camera);
requestAnimationFrame(render);
};
render();
window.addEventListener("resize", () => {
// 更新摄像头
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
});
</script>
<style>
.container {
width: 100%;
height: 100vh;
position: relative;
z-index: 1;
}
</style>