2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > Three.js 点击模型 高亮发光模型外轮廓

Three.js 点击模型 高亮发光模型外轮廓

时间:2018-12-06 13:51:53

相关推荐

Three.js 点击模型 高亮发光模型外轮廓

最近在开发一个功能,在三维场景里有很多模型,需要点击模型,高亮对应的模型,代表选中了该模型。做起来还是稍微麻烦一些的。

具体效果

实现流程

主要的流程还是,

关键代码

在Vue项目中,所以参考时需要注意下:

鼠标点击模型

import * as THREE from 'three'//添加监听window.addEventListener('click',event=>{this.clickEvent(event)}) clickEvent(event){//获取在射线上的接触点//获取鼠标坐标let mouse=new THREE.Vector2();let raycaster=new THREE.Raycaster();mouse.x=(event.clientX/window.innerWidth)*2-1;mouse.y=-(event.clientY/window.innerHeight)*2+1;raycaster.setFromCamera(mouse, this.camera);let intersects = raycaster.intersectObjects(this.scene.children);if(intersects&&intersects.length>0){console.log("点击模型")}},;

高亮发光模型外轮廓

import {EffectComposer } from "three/examples/jsm/postprocessing/EffectComposer.js"import {RenderPass } from "three/examples/jsm/postprocessing/RenderPass.js"import {OutlinePass } from "three/examples/jsm/postprocessing/OutlinePass.js"import {ShaderPass } from "three/examples/jsm/postprocessing/ShaderPass.js"import {FXAAShader } from "three/examples/jsm/shaders/FXAAShader.js"//渲染场景let animate = () =>{requestAnimationFrame(animate);//渲染外发光renderer.render(scene, camera);if (poser) {poser.render()}};animate();//高亮显示模型(呼吸灯)outlineObj (selectedObjects) {// 创建一个EffectComposer(效果组合器)对象,然后在该对象上添加后期处理通道。poser = new EffectComposer(this.renderer)// 新建一个场景通道 为了覆盖到原理来的场景上this.renderPass = new RenderPass(this.scene, this.camera)poser.addPass(this.renderPass);// 物体边缘发光通道this.outlinePass = new OutlinePass(new THREE.Vector2(window.innerWidth, window.innerHeight), this.scene, this.camera, selectedObjects)this.outlinePass.selectedObjects = selectedObjectsthis.outlinePass.edgeStrength = 15.0 // 边框的亮度this.outlinePass.edgeGlow = 2// 光晕[0,1]this.outlinePass.usePatternTexture = false // 是否使用父级的材质this.outlinePass.edgeThickness = 1.0 // 边框宽度this.outlinePass.downSampleRatio = 1 // 边框弯曲度this.outlinePass.pulsePeriod = 5 // 呼吸闪烁的速度this.outlinePass.visibleEdgeColor.set(parseInt(0xff0000)) // 呼吸显示的颜色this.outlinePass.hiddenEdgeColor = new THREE.Color(0, 0, 0) // 呼吸消失的颜色this.outlinePass.clear = poser.addPass(this.outlinePass)// 自定义的着色器通道 作为参数let effectFXAA = new ShaderPass(FXAAShader)effectFXAA.uniforms.resolution.value.set(1 / window.innerWidth, 1 / window.innerHeight)effectFXAA.renderToScreen = poser.addPass(effectFXAA)},

完整代码

<template><div id="app"><div id="map"></div></div></template><script>import {Scene,PerspectiveCamera,WebGLRenderer,DirectionalLight,MeshBasicMaterial,Mesh,TextureLoader,CylinderGeometry,RepeatWrapping} from 'three';import {OBJLoader} from "@/lib/OBJLoader"import * as THREE from 'three'import {EffectComposer } from "three/examples/jsm/postprocessing/EffectComposer.js"import {RenderPass } from "three/examples/jsm/postprocessing/RenderPass.js"import {OutlinePass } from "three/examples/jsm/postprocessing/OutlinePass.js"import {ShaderPass } from "three/examples/jsm/postprocessing/ShaderPass.js"import {FXAAShader } from "three/examples/jsm/shaders/FXAAShader.js"import {OrbitControls } from "three/examples/jsm/controls/OrbitControls.js"export default {name: 'App',components: {},data(){return{baseY:-20,composer: null,outlinePass: null,renderPass: null,}},mounted() {let scene = new Scene();let camera = new PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);// fov — 摄像机视锥体垂直视野角度// aspect — 摄像机视锥体长宽比// near — 摄像机视锥体近端面// far — 摄像机视锥体远端面let renderer = new WebGLRenderer();renderer.setSize(window.innerWidth, window.innerHeight);let app = document.getElementById("map")app.appendChild(renderer.domElement);//加载场景控制插件let controls = new OrbitControls(camera, renderer.domElement);controls.enableDamping = true;controls.enableZoom = true;controls.autoRotate = false;controls.autoRotateSpeed = 3;controls.enablePan = true;controls.enableKeys = true;controls.keyPanSpeed = 7;controls.keys = {LEFT: 37,UP: 38,RIGHT: 39,BOTTOM: 40}this.controls = controls;//添加一个光源let light = new DirectionalLight(0xffffff);//光源颜色light.position.set(200, 100, 1305);//光源位置scene.add(light);//光源添加到场景中camera.position.y = 30;camera.position.z = 100;this.scene=scene;this.camera=camera;this.renderer=renderer;window.addEventListener('click',event=>{this.clickEvent(event)});this.addBottom(scene)//渲染场景let animate = () =>{requestAnimationFrame(animate);//渲染外发光renderer.render(scene, camera);if (poser) {poser.render()}};animate();},methods: {clickEvent(event){//获取在射线上的接触点//获取鼠标坐标let mouse=new THREE.Vector2();let raycaster=new THREE.Raycaster();mouse.x=(event.clientX/window.innerWidth)*2-1;mouse.y=-(event.clientY/window.innerHeight)*2+1;raycaster.setFromCamera(mouse, this.camera);let intersects = raycaster.intersectObjects(this.scene.children);if(intersects&&intersects.length>0){this.outlineObj([intersects[0].object])}},//高亮显示模型(呼吸灯)outlineObj (selectedObjects) {// 创建一个EffectComposer(效果组合器)对象,然后在该对象上添加后期处理通道。poser = new EffectComposer(this.renderer)// 新建一个场景通道 为了覆盖到原理来的场景上this.renderPass = new RenderPass(this.scene, this.camera)poser.addPass(this.renderPass);// 物体边缘发光通道this.outlinePass = new OutlinePass(new THREE.Vector2(window.innerWidth, window.innerHeight), this.scene, this.camera, selectedObjects)this.outlinePass.selectedObjects = selectedObjectsthis.outlinePass.edgeStrength = 15.0 // 边框的亮度this.outlinePass.edgeGlow = 2// 光晕[0,1]this.outlinePass.usePatternTexture = false // 是否使用父级的材质this.outlinePass.edgeThickness = 1.0 // 边框宽度this.outlinePass.downSampleRatio = 1 // 边框弯曲度this.outlinePass.pulsePeriod = 5 // 呼吸闪烁的速度this.outlinePass.visibleEdgeColor.set(parseInt(0xff0000)) // 呼吸显示的颜色this.outlinePass.hiddenEdgeColor = new THREE.Color(0, 0, 0) // 呼吸消失的颜色this.outlinePass.clear = poser.addPass(this.outlinePass)// 自定义的着色器通道 作为参数let effectFXAA = new ShaderPass(FXAAShader)effectFXAA.uniforms.resolution.value.set(1 / window.innerWidth, 1 / window.innerHeight)effectFXAA.renderToScreen = poser.addPass(effectFXAA)},addBottom(scene) {let loader = new TextureLoader()let texture = loader.load('./bottom.jpg', function (texture) {texture.wrapS = texture.wrapT = RepeatWrapping;texture.offset.set(0, 0);texture.repeat.set(1.57, 1);});let material = new MeshBasicMaterial({map: texture // 通过map 属性引入图片})let bar = new CylinderGeometry(20, 20, 20, 40, 40, false);// THREE.CylinderGeometry(radiusTop, radiusBottom, height, radiusSegments, heightSegments, openEnded)// radiusTop:顶面的半径;// radiusBottom:底面的半径;// height:是圆柱体的高度;// radiusSegments:两底面的分段切片;// heightSegments:侧面的分段切片;// openEnded:是一个布尔值,表示是否没有顶面和底面,缺省值为false,表示有顶面和底面。let cubeBar = new Mesh(bar, material);cubeBar.position.x = 0cubeBar.position.y = this.baseYscene.add(cubeBar);},}}</script><style>body, html, #app {width: 100%;height: 100%;padding: 0;margin: 0;overflow: hidden;}#map {width: 100%;height: 100%;position: absolute;left: 0;top: 0;z-index: 1;}</style>

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。