演示地址:https://capricorncd.github.io/blog/dist/three/index.html#/ClockObj
源码:https://github.com/capricorncd/blog/tree/master/demos/three
C4D文件:clock(R21.207).c4d https://github.com/capricorncd/blog/tree/master/c4d
流程
- C4D建模
- 导出
.obj
文件 - js实现(Three.js),此例开发环境应用的Webpack+React
一、C4D建模
这里B站有视频教程,这里就不赘述。
在线视频教程:https://www.bilibili.com/video/BV177411P7d1?p=3
建模时留神须要留神的中央:
- 建模:不能应用面(Disc)建模,在浏览器中不会显示,需改用圆柱体(Cylinder)。
- 贴图:需给每个几何体贴图,不能应用分组贴图。在Three.js中分组贴图不能与单个几何体绑定,顾浏览器中不会显示贴图。
二、导出.obj
文件
C4D中实现建模和贴图后,就能够导出.obj文件。
# 工具栏file -> Export -> Wavefront OBJ(*.obj)
其余导出选项默认即可。导出obj文件的同时,会导出一个同名贴图.mtl文件。
三、js实现
# "three": "^0.120.1"npm i -S three# oryarn add three
src/components/ClockObj/core.js
import { AmbientLight, DirectionalLight, PerspectiveCamera, Scene, WebGLRenderer} from 'three'import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader'import { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader'import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'let scene, renderer/** * 加载贴图和模型对象文件 * load resource * @returns {Promise<unknown>} */ function loadResource() { return new Promise((resolve, reject) => { const objLoader = new OBJLoader() const mtlLoader = new MTLLoader() // 加载贴图文件 mtlLoader.load('static/clock.mtl', mtl => { // 加载对象前,先设置贴图数据 objLoader.setMaterials(mtl) // 加载对象文件 objLoader.load('static/clock.obj', res => { resolve(res) }, undefined, reject) }, undefined, reject) })}/** * 初始化 */function _init(el, obj) { // 获取容器尺寸, // 如果时window对象,请应用window.innerWidth, window.innerHeight const width = el.offsetWidth const height = el.offsetHeight // 创立场景 scene = new Scene() // 将加载实现的模型对象,增加到场景中 scene.add(obj) // 创立环境光 const ambientLight = new AmbientLight(0x666666) ambientLight.position.set(100, -100, -200) scene.add(ambientLight) // 创立平行光 const light = new DirectionalLight(0xcccccc, 1) light.position.set(2000, 1000, 1000) scene.add(light) // 创立摄像机 const camera = new PerspectiveCamera(45, width / height, 1, 80000) camera.position.set(-150, -50, 300) // 创立renderer renderer = new WebGLRenderer({ // 打消锯齿 antialias: true }) // 设置渲染区域尺寸 renderer.setSize(width, height) // 设置背景色彩 renderer.setClearColor(COLORS.black, 1) // 将场景Canvas DOM元素,增加至父元素中 el.appendChild(renderer.domElement) // 创立场景鼠标管制实例, // 能够对页面上的模型对象进行旋转/缩放等操作 const orbitControls = new OrbitControls(camera, el) orbitControls.addEventListener('change', render) // 执行渲染,指定场景和相机作为参数 function render() { renderer.render(scene, camera) } render()}/** * 导出初始化办法 */export function init(el) { loadResource().then(res => { _init(el, res) }).catch(console.error)}/** * destroy */export function destroy() { if (!scene || !renderer) return scene.remove() renderer.dispose() scene = null renderer = null}
src/components/ClockObj/index.jsx
import React, { useEffect } from 'react'import { destroy, init } from './core'function ClockObjDemo() { useEffect(() => { const el = document.querySelector('.clock-demo-el-hook') init(el) return () => { destroy() } }, []) return <main className="clock-demo-el-hook"/>}export default ClockObjDemo
备注
建模贴图未应用图片等内部文件,可能还有其余的坑,当前遇到了再补上。