three.js 各种模型阴影效果渲染

three.js 阴影渲染

学习three.js的时候,发现有些时候场景需要为建筑添加阴影效果,然鹅threejs默认是把阴影效果关闭了的,倒腾了一下,总结开启阴影的四部曲:

  1. 光源要能照出阴影
      // 平行光   DirectionalLight第二个参数为光照强度 范围 0-1 不写默认为1
      const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5)
      directionalLight.position.set(10, 10, 10) // 平行光相对物体投射的源头位置
      directionalLight.castShadow = true // 开启平行光产生阴影的效果 默认是false
      directionalLight.target = this.cube // 光线投射的目标
      this.scene.add(directionalLight)
  1. 物体要能产生阴影
      // 立方体
      const geometry = new THREE.SphereGeometry(1, 32, 32)
      // 材质
      const material = new THREE.MeshStandardMaterial({
        color: '#000000'
      })
      this.cube = new THREE.Mesh(geometry, material) // 生成网格
      this.cube.castShadow = true // 对象是否渲染到阴影贴图中,默认值为false
      this.cube.position.y = 3 // 设置物体位置
      this.scene.add(this.cube)
  1. 要有个能接受阴影的面
      // 创建一个接受阴影的平面
      const planeGeometry = new THREE.PlaneBufferGeometry(20, 20, 32, 32)
      const planeMaterial = new THREE.MeshStandardMaterial({
        color: '#ffffff'
      })
      const plane = new THREE.Mesh(planeGeometry, planeMaterial)
      plane.rotation.x = -Math.PI / 2
      plane.receiveShadow = true // 开启平面接受投射阴影的效果
      this.scene.add(plane)
  1. 渲染器能渲染阴影效果
      // 渲染函数
      this.renderer = new THREE.WebGLRenderer({
        antialias: true // 是否执行抗锯齿
      })
      // 开启渲染器渲染阴影的效果
      this.renderer.shadowMap.enabled = true
      this.renderer.shadowMap.type = THREE.PFCSoftShadowMap // 阴影类型
      this.renderer.setSize(this.$refs.container.clientWidth, this.$refs.container.clientHeight)
      this.$refs.container.appendChild(this.renderer.domElement)

有了上面这四步,基本能渲染出物体的阴影效果。

下面上完整的代码


<template>
  <div class="practice">
    <div id="container" ref="container"></div>
  </div>
</template>

<script>
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'

export default {
  components: {},

  data () {
    return {
      scene: null,
      camera: null,
      renderer: null,
      cube: null,
      controls: null
    }
  },

  mounted () {
    this.init()
    this.animate()
  },

  methods: {
    init () {
      // 场景
      this.scene = new THREE.Scene()

      // 背景
      this.scene.background = new THREE.Color(0xaaaaaa)

      // 透视摄像机
      this.camera = new THREE.PerspectiveCamera(90, this.$refs.container.clientWidth / this.$refs.container.clientHeight, 0.1, 1000)
      this.camera.position.set(5, 5, 0)
      this.camera.lookAt(0, 0, 0)

      // 渲染函数
      this.renderer = new THREE.WebGLRenderer({
        antialias: true // 是否执行抗锯齿
      })
      // 开启渲染器渲染阴影的效果
      this.renderer.shadowMap.enabled = true
      this.renderer.shadowMap.type = THREE.PFCSoftShadowMap // 阴影的类型
      this.renderer.setSize(this.$refs.container.clientWidth, this.$refs.container.clientHeight)
      this.$refs.container.appendChild(this.renderer.domElement)

      // 相机控制器
      this.controls = new OrbitControls(this.camera, this.renderer.domElement)

      // 立方体
      const geometry = new THREE.SphereGeometry(1, 32, 32)
      // 材质
      const material = new THREE.MeshStandardMaterial({
        color: '#000000'
      })
      this.cube = new THREE.Mesh(geometry, material) // 生成网格
      this.cube.castShadow = true // 对象是否渲染到阴影贴图中,默认值为false
      this.cube.position.y = 3 // 设置物体位置
      this.scene.add(this.cube)

      // // 环境光  AmbientLight第二个参数为光照强度 范围 0-1 不写默认为1
      const light = new THREE.AmbientLight(0xffffff, 0.5)
      this.scene.add(light)

      // 平行光   DirectionalLight第二个参数为光照强度 范围 0-1 不写默认为1
      const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5)
      directionalLight.position.set(10, 10, 10) // 平行光相对物体投射的源头位置
      directionalLight.castShadow = true // 开启平行光产生阴影的效果 默认是false
      directionalLight.target = this.cube // 光线投射的目标
      this.scene.add(directionalLight)

      // 创建一个接受阴影的平面
      const planeGeometry = new THREE.PlaneBufferGeometry(20, 20, 32, 32)
      const planeMaterial = new THREE.MeshStandardMaterial({
        color: '#ffffff'
      })
      const plane = new THREE.Mesh(planeGeometry, planeMaterial)
      plane.rotation.x = -Math.PI / 2
      plane.receiveShadow = true // 开启平面接受投射阴影的效果
      this.scene.add(plane)
    },

    animate () {
      // 实时渲染动画,页面切换离开会停下,性能比较好
      requestAnimationFrame(this.animate)
      this.controls.update()
      this.renderer.render(this.scene, this.camera)
    }
  }
}
</script>

<style scoped lang='less'>
.practice{
  #container{
    height: 700px;
  }
}
</style>

下面是运行效果
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值