three.js加载和使用纹理-设置material.bumpMap属性使用凹凸贴图创建皱纹(vue中使用three.js74)

1.demo效果

在这里插入图片描述

2. 实现要点

2.1 创建地板

createFloor() {
  const publicPath = process.env.BASE_URL
  const floorTex = new THREE.TextureLoader().load(
    `${publicPath}textures/general/floor-wood.jpg`
  )
  const plane = new THREE.Mesh(
    new THREE.BoxGeometry(200, 100, 0.1, 30),
    new THREE.MeshPhongMaterial({
      color: 0x3c3c3c,
      map: floorTex
    })
  )
  plane.position.y = -7.5
  plane.rotation.x = -0.5 * Math.PI
  this.scene.add(plane)
}

2.2 创建凹凸贴图的物体

通过凹凸贴图可以实现材质表面不同深度的凹凸,使物体更有真实感,实现过程很简单
需要准备两个纹理贴图
一个用来设置material.map 属性,用作材质的普通贴图
一个用来设置material.bumpmap属性,用作材质的凹凸贴图
除此之外要想审查凹凸纹理效果material还有一个bumpScale属性要设置

createMesh(geom, imageFile, bump) {
  const publicPath = process.env.BASE_URL
  const texture = new THREE.TextureLoader().load(`${publicPath}textures/general/` + imageFile)
  geom.computeVertexNormals()
  const mat = new THREE.MeshPhongMaterial()
  mat.map = texture

  if (bump) {
    const bump = new THREE.TextureLoader().load(`${publicPath}textures/general/` + bump)
    mat.bumpMap = bump
    mat.bumpScale = 0.2
  }

  const mesh = new THREE.Mesh(geom, mat)
  return mesh
}
//创建带凹凸贴图的物体
this.cube2 = this.createMesh(
  new THREE.BoxGeometry(15, 15, 2),
  'stone.jpg',
  'stone-bump.jpg'
)
this.cube2.rotation.y = 0.5
this.cube2.position.x = -12
this.scene.add(this.cube2)

2.3 创建普通贴图的物体

//创建没有凹凸贴图的物体
this.cube1 = this.createMesh(
  new THREE.BoxGeometry(15, 15, 2),
  'stone.jpg'
)
this.cube1.rotation.y = -0.5
this.cube1.position.x = 12
this.scene.add(this.cube1)

3. demo代码

<template>
  <div>
    <div id="container" />
    <div class="controls-box">
      <section>
        <el-row>
          <el-checkbox v-model="properties.rotate">
            rotate
          </el-checkbox>
        </el-row>
        <el-row>
          <div v-for="(item,key) in properties" :key="key">
            <div v-if="item&&item.name!=undefined">
              <el-col :span="8">
                <span class="vertice-span">{{ item.name }}</span>
              </el-col>
              <el-col :span="13">
                <el-slider v-model="item.value" :min="item.min" :max="item.max" :step="item.step" :format-tooltip="formatTooltip" @change="propertiesChange" />
              </el-col>
              <el-col :span="3">
                <span class="vertice-span">{{ item.value }}</span>
              </el-col>
            </div>
          </div>
        </el-row>
        <el-row>
          <el-col :span="8" class="label-col">
            <label>texture</label>
          </el-col>
          <el-col :span="16">
            <el-select v-model="properties.textureType" placeholder="请选择" @change="propertiesChange">
              <el-option v-for="item in texturesOptions" :key="item.value" :label="item.label" :value="item.value" />
            </el-select>
          </el-col>
        </el-row>
      </section>
    </div>
  </div>
</template>

<script>
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
export default {
  data() {
    return {
      texturesOptions: [
        {
          value: 'stone',
          label: 'stone'
        },
        {
          value: 'weave',
          label: 'weave'
        }
      ],
      properties: {
        bumpScale: {
          name: 'bumpScale',
          value: 0.2,
          min: -2,
          max: 2,
          step: 0.1
        },
        textureType: 'stone',
        rotate: false
      },
      cube1: null,
      cube2: null,
      camera: null,
      scene: null,
      renderer: null,
      controls: null
    }
  },
  mounted() {
    this.init()
  },
  methods: {
    formatTooltip(val) {
      return val
    },

    // 初始化
    init() {
      this.createScene() // 创建场景
      this.createModels() // 创建模型
      this.createLight() // 创建光源
      this.createCamera() // 创建相机
      this.createRender() // 创建渲染器
      this.createControls() // 创建控件对象
      this.render() // 渲染
    },
    // 创建场景
    createScene() {
      this.scene = new THREE.Scene()
    },
    // 创建模型
    createModels() {
      //创建没有凹凸贴图的物体
      this.cube1 = this.createMesh(
        new THREE.BoxGeometry(15, 15, 2),
        'stone.jpg'
      )
      this.cube1.rotation.y = -0.5
      this.cube1.position.x = 12
      this.scene.add(this.cube1)

      //创建带凹凸贴图的物体
      this.cube2 = this.createMesh(
        new THREE.BoxGeometry(15, 15, 2),
        'stone.jpg',
        'stone-bump.jpg'
      )
      this.cube2.rotation.y = 0.5
      this.cube2.position.x = -12
      this.scene.add(this.cube2)
      // console.log(this.cube2.geometry.faceVertexUvs)

      this.createFloor()
    },
    createMesh(geom, imageFile, bump) {
      const publicPath = process.env.BASE_URL
      const texture = new THREE.TextureLoader().load(
        `${publicPath}textures/general/` + imageFile
      )
      geom.computeVertexNormals()
      const mat = new THREE.MeshPhongMaterial()
      mat.map = texture

      if (bump) {
        const bump = new THREE.TextureLoader().load(
          `${publicPath}textures/general/` + bump
        )
        mat.bumpMap = bump
        mat.bumpScale = 0.2
      }

      const mesh = new THREE.Mesh(geom, mat)
      return mesh
    },
    createFloor() {
      const publicPath = process.env.BASE_URL
      const floorTex = new THREE.TextureLoader().load(
        `${publicPath}textures/general/floor-wood.jpg`
      )
      const plane = new THREE.Mesh(
        new THREE.BoxGeometry(200, 100, 0.1, 30),
        new THREE.MeshPhongMaterial({
          color: 0x3c3c3c,
          map: floorTex
        })
      )
      plane.position.y = -7.5
      plane.rotation.x = -0.5 * Math.PI
      this.scene.add(plane)
    },
    // 创建光源
    createLight() {
      // 环境光
      const ambientLight = new THREE.AmbientLight(0x242424, 0.1) // 创建环境光
      this.scene.add(ambientLight) // 将环境光添加到场景

      const spotLight = new THREE.SpotLight(0xffffff) // 创建聚光灯
      spotLight.position.set(0, 30, 30)
      spotLight.intensity = 1.2
      this.scene.add(spotLight)
    },
    // 创建相机
    createCamera() {
      const element = document.getElementById('container')
      const width = element.clientWidth // 窗口宽度
      const height = element.clientHeight // 窗口高度
      const k = width / height // 窗口宽高比
      // PerspectiveCamera( fov, aspect, near, far )
      this.camera = new THREE.PerspectiveCamera(45, k, 0.1, 1000)
      this.camera.position.set(0, 12, 38) // 设置相机位置

      this.camera.lookAt(new THREE.Vector3(0, 0, 0)) // 设置相机方向
      this.scene.add(this.camera)
    },
    // 创建渲染器
    createRender() {
      const element = document.getElementById('container')
      this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true })
      this.renderer.setSize(element.clientWidth, element.clientHeight) // 设置渲染区域尺寸
      // this.renderer.shadowMap.enabled = true // 显示阴影
      // this.renderer.shadowMap.type = THREE.PCFSoftShadowMap
      this.renderer.setClearColor(0xeeeeee, 1) // 设置背景颜色
      element.appendChild(this.renderer.domElement)
    },

    propertiesChange() {
      const publicPath = process.env.BASE_URL
      const texture = new THREE.TextureLoader().load(
        `${publicPath}textures/general/` + this.properties.textureType + '.jpg'
      )
      this.cube1.material.map = texture
      this.cube2.material.map = texture

      const bump = new THREE.TextureLoader().load(
        `${publicPath}textures/general/` +
          this.properties.textureType +
          '-bump.jpg'
      )
      this.cube2.material.bumpMap = bump

      this.cube2.material.bumpScale = this.properties.bumpScale.value
    },

    updateRotation() {
      if (this.properties.rotate) {
        this.cube1.rotation.y += 0.01
        this.cube2.rotation.y -= 0.01
      }
    },

    render() {
      this.updateRotation()
      this.renderer.render(this.scene, this.camera)
      requestAnimationFrame(this.render)
    },
    // 创建控件对象
    createControls() {
      this.controls = new OrbitControls(this.camera, this.renderer.domElement)
    }
  }
}
</script>

<style>
#container {
  position: absolute;
  width: 100%;
  height: 100%;
}
.controls-box {
  position: absolute;
  right: 5px;
  top: 5px;
  width: 300px;
  padding: 10px;
  background-color: #fff;
  border: 1px solid #c3c3c3;
}
.label-col {
  padding: 8px 5px;
}

.vertice-span {
  line-height: 38px;
  padding: 0 2px 0 10px;
}
</style>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Create and animate stunning 3D graphics using the open source Three.js JavaScript library Overview Create and animate beautiful 3D graphics directly in the browser using JavaScript without the need to learn WebGL Learn how to enhance your 3D graphics with light sources, shadows, and advanced materials and textures Each subject is explained using extensive examples that you can directly use and adapt for your own purposes In Detail Three.js is a JavaScript 3D library that offers a wide range of features for creating and displaying stunning 3D computer graphics on a web browser in an intuitive manner using JavaScript without having to deal with the complexity of a WebGL low-level API. Even though WebGL makes it possible to create 3D graphics in the browser without having to use plugins, programming WebGL, however, is hard and complex. This book shows you how Three.js allows you to be independent of browser plugins. If you are an experienced web designer who wants to set the tone for an immersive design environment in your applications then this book is for you. "Learning Three.js: The JavaScript 3D Library for WebGL" is a practical, example-rich book that will help you to master all the features of Three.js. With this book, you’ll learn how to create and animate gorgeous looking 3D scenes directly in your browser utilizing the full potential of WebGL and modern browsers without having to learn WebGL. "Learning Three.js: The JavaScript 3D Library for WebGL" starts by going over the basic concepts and building blocks used in Three.js. From there on, it will expand on these subjects using extensive examples and code samples. This will allow you to learn everything you need to know about Three.js in an easy and interactive manner. Besides the basic concepts, this book will show you how you can create realistic looking 3D objects using materials and textures as well as how to load them from externally created models. You’ll learn how to easily control the camera using the Three.js build-in camera controls so you can fly or walk around the 3D scene you have created. You will also learn how to use morph and bones-based animation and how to add physics to your scene. What you will learn from this book Create standard HTML skeleton and render loops for your Three.js projects Learn how to use the different geometries that are provided by Three.js Apply realistic lighting and shadows to the 3D objects you have created Learn how the different types of materials in Three.js work and how they interact with your 3D objects and the rest of the environment Use the different camera controls provided by Three.js to effortlessly navigate around your 3D scene Work with a particle system to create snow, rain, and galaxy-like effects Import and animate models from external formats such as OBJ, STL, Collada, and much more Create and run animations using either morph targets or bones animations Use advanced textures on materials to create realistic looking 3D objects using bump maps, normal maps, specular maps, and light maps Change the output of Three.js rendered using one of its post processing options Interact directly with WebGL by creating custom vertex and fragment shaders Apply physics to your 3D objects using the Physijs JavaScript library

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值