ITPub博客

首页 > 数据库 > 数据库开发技术 > 【33】three.js实战—法线贴图应用

【33】three.js实战—法线贴图应用

原创 数据库开发技术 作者:小南瓜开发平台 时间:2023-04-16 00:01:00 0 删除 编辑

贴图材质网:

http://www.poliigon.com/textures

https://3dtextures.me/

https://www.arroway-textures.ch/



<template>  <div class="container" ref="container">
</div></template>
<script >import * as THREE from "three";import { ref } from "vue";//添加一个轨道控制器import { OrbitControls} from "three/examples/jsm/controls/OrbitControls";//导入动画库import gsap from "gsap";//导入dat.guiimport * as dat from "dat.gui";

export default { name: 'App', data() { return { renderer: null, scene: null, camera: null, cube: null, clock: null, animate1: null, controls: null, gui: null } }, mounted() { //1.创建场景
const scene = new THREE.Scene();
//2.创建相机(透视相机) /** * 构造器 * PerspectiveCamera( fov : Number, aspect : Number, near : Number, far : Number ) * fov — 摄像机视锥体垂直视野角度 * aspect — 摄像机视锥体长宽比 * near — 摄像机视锥体近端面 * far — 摄像机视锥体远端面 */ const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); //设置相机位置:x,y,z轴位置 camera.position.set(0,0,10); //添加相机到场景中 scene.add(camera); this.scene=scene;this.camera=camera;
//导入纹理 const textureLoader = new THREE.TextureLoader(); const doorColorTexture = textureLoader.load("static/textures/door/color.jpg"); const doorAplhaTexture = textureLoader.load("static/textures/door/alpha.jpg") //环境遮挡贴图 const doorAoTexture = textureLoader.load('static/textures/door/ambientOcclusion.jpg'); //导入置换贴图 const doorHeightTexture = textureLoader.load('static/textures/door/height.jpg');
//导入粗糙度贴图 const RoughnessTexture = textureLoader.load('static/textures/door/roughness.jpg');
//导入金属度贴图 const MetalnessTexture = textureLoader.load('static/textures/door/metalness.jpg');
//导入法线贴图 const normalTexture = textureLoader.load('static/textures/door/normal.jpg');
//当一个纹素覆盖小于一个像素时 // texture.minFilter = THREE.LinearFilter; // texture.magFilter = THREE.LinearFilter;
//添加物体 const cubeGeometry = new THREE.BoxBufferGeometry(1,1,1,100,100); //材质 const material = new THREE.MeshStandardMaterial({ color: "#ffff00", map: doorColorTexture, alphaMap: doorAplhaTexture,//用于实现贴图的混合效果,其实AlphaMap跟黑白色的光照贴图差不 transparent: true, aoMap: doorAoTexture, aoMapIntensity: 1,//设置强度 side: THREE.DoubleSide,//设置双面渲染 displacementMap: doorHeightTexture, displacementScale: 0.1, roughness: 1,//设置粗糙度,0:光滑,1:非常粗糙 roughnessMap: RoughnessTexture,//设置粗糙度贴图 metalness: 1,//金属度 metalnessMap: MetalnessTexture,//金属贴图 normalMap: normalTexture,//法向贴图 });
const cube = new THREE.Mesh(cubeGeometry,material);
//给cube添加第二组uv cubeGeometry.setAttribute('uv2',new THREE.BufferAttribute(cubeGeometry.attributes.uv.array,2));
//将几何体添加到场景中 scene.add(cube);
//添加平面 const planGeometry = new THREE.PlaneBufferGeometry(1,1,200,200); const plane = new THREE.Mesh( planGeometry, material ); plane.position.set(1,0,0); scene.add(plane);
//给平面设置第二组uv贴图 planGeometry.setAttribute('uv2',new THREE.BufferAttribute(planGeometry.attributes.uv.array,2) );


//标准材质必须要有光 //添加灯光 //环境光 const light = new THREE.AmbientLight(0xffffff,0.5);//0.1强度 scene.add(light);
//直线光源 const directionalLight = new THREE.DirectionalLight; directionalLight.position.set(10,10,10); scene.add(directionalLight);



//4.初始化渲染器 const renderer = new THREE.WebGLRenderer(); //设置渲染器的尺寸大小 renderer.setSize(window.innerWidth,window.innerHeight); this.renderer=renderer; //将webgl渲染的canvas内容添加到div //document.body.append(renderer.domElement); this.$refs['container'].appendChild(renderer.domElement);

//使用渲染器,通过相机将场景渲染进来 renderer.render(scene,camera);
//5.创建轨道控制器 const controls = new OrbitControls(camera,renderer.domElement); //设置控制器阻尼,让控制器更有真实效果,必须在动画循环调用update controls.enableDamping = true; this.controls=controls;
//6.添加坐标轴辅助器 //size -- (可选的) 表示代表轴的线段长度. 默认为 1. const axesHelper = new THREE.AxesHelper( 5 ); scene.add( axesHelper );
//双击控制屏幕进入全屏、退出全屏 window.addEventListener("dblclick",()=>{ const fullScreenElement =document.fullscreenElement;
if(!fullScreenElement){ //让画布对象全屏 this.renderer.domElement.requestFullscreen(); }else{ //退出全屏,使用document对象 document.exitFullscreen(); }
})
//监听画面变化,更新渲染画面 window.addEventListener("resize",()=>{ console.log("画面变化了"); //更新摄像头 this.camera.aspect = window.innerWidth /window.innerHeight; //更新摄像机的投影矩阵 this.camera.updateProjectionMatrix(); //更新渲染器 this.renderer.setSize(window.innerWidth,window.innerHeight); //设置渲染器的像素比 this.renderer.setPixelRatio(window.devicePixelRatio);
})
this.renders(); }, methods: { renders(){

this.controls.update(); this.renderer.render(this.scene,this.camera); // requestAnimationFrame(this.renders());//此行代码会出现threejs requestAnimationFrame 导致的call stack超出上限的问题 requestAnimationFrame(this.renders.bind(this));
},
}}</script>
<style> *{ margin: 0; padding: 0; }.container{ height: 100vh; width: 100vw; background-color: #f0f0f0;}</style>


原文作者:小南瓜开发平台;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2020-08-21

  • 博文量
    209
  • 访问量
    89535