Three.js —— Doze, camada de verniz MeshPhysicalMaterial, rugosidade, transmitância do material físico e índice de refração (com código no final)

Teste de função do mapa ambiental

MeshPhysicalMaterialCamada de verniz

MeshPhysicalMaterialAmbos MeshStandarMaterialsão materiais PBR com atributos de metalicidade metalnesse 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.roughnessMeshPhysicalMaterialMeshStandarMaterial

Propriedades da camada de verniz.clearcoat

O atributo da camada de verniz .clearcoatpode ser usado para simular uma camada de molde transparente escovada na superfície do objeto. .clearcoatO 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. MeshPhysicalMaterialEle 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 .clearcoate 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 .transmissiono 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:
Adicione a descrição da imagem

í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);

Adicione a descrição da imagem

Analisar material gltf

Geralmente, o material de malha padrão é usado por padrão MeshStandardMaterial. Se alguns materiais gltf tiverem atributos como .clearcoat, .transmissionetc., e o material de malha padrão MeshStandardMaterialnão puder ser expresso, o material de malha física será usado MeshPhysicalMaterialpara 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>

Acho que você gosta

Origin blog.csdn.net/nanchen_J/article/details/131759442
Recomendado
Clasificación