1.实例演示
微信小程序集成Three.js,各种光源效果演示
2.源码
(1)引入three.js库文件
import * as THREE from '../../libs/three.weapp.js'
import {
OrbitControls
} from '../../jsm/controls/OrbitControls'
const app = getApp()
库文件下载及配置看这里https://blog.csdn.net/weixin_39318421/article/details/128468409?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22128468409%22%2C%22source%22%3A%22weixin_39318421%22%7D
(2)默认环境光场景
这个场景只加入了简单的环境光,AmbientLight的光线没有特定的来源,而且这个光源也不会影响阴影的生成。在使用其他光源的同时使用AmbientLight,目的是弱化阴影或添加一些颜色。
initScene1() {
wx.createSelectorQuery()
.select('#webgl')
.node()
.exec((res) => {
let canvasId = String(res[0].node.id)
const canvas = THREE.global.registerCanvas(canvasId, res[0].node)
this.setData({
canvasId: canvasId
})
//相机
const camera = new THREE.PerspectiveCamera(70, canvas.width / canvas.height, 1, 1000);
//场景
const scene = new THREE.Scene();
scene.background = new THREE.Color(0xffffff);
const renderer = new THREE.WebGLRenderer({
antialias: true
});
camera.position.set(30, 40, 50);
//控制器
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.update();
//加入环境光
let ambiColor = "#cccccc";
let ambientLight = new THREE.AmbientLight(ambiColor);
scene.add(ambientLight)
//球体
const sphereGeometry = new THREE.SphereGeometry(4, 20, 20)
const sphereMaterial = new THREE.MeshLambertMaterial({
color: 0x7777ff
})
const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial)
sphere.position.y = 10
sphere.position.z = 10
//设置球体投射阴影
sphere.castShadow = true
scene.add(sphere)
//正方体1
const geometry = new THREE.BoxBufferGeometry(10, 10, 10);
const material = new THREE.MeshLambertMaterial({
color: 0x2a5a5
});
const mesh1 = new THREE.Mesh(geometry, material);
mesh1.position.x = 15
mesh1.name = 'ms1'
//设置正方体投射阴影
mesh1.castShadow = true;
scene.add(mesh1);
//平面
const planeGeometry = new THREE.PlaneGeometry(200, 150, 5, 5);
const planeMaterial = new THREE.MeshBasicMaterial({
color: 0xa8a8a8,
});
planeMaterial.side = THREE.DoubleSide;
const plane = new THREE.Mesh(planeGeometry, planeMaterial)
plane.rotation.x = Math.PI / 2
plane.position.y = -5
//设置平面接收阴影
plane.receiveShadow = true;
scene.add(plane)
//辅助线
const axesHelper = new THREE.AxesHelper(500);
scene.add(axesHelper)
renderer.setPixelRatio(wx.getSystemInfoSync().pixelRatio);
//渲染器使能阴影渲染
renderer.shadowMap.enabled = true
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.setSize(canvas.width, canvas.height);
function render() {
canvas.requestAnimationFrame(render);
//更新控制器
controls.update();
renderer.render(scene, camera);
}
render()
})
},
(3)采用点光源的场景
点光源,PointLight,照射所有方向的光源。
initScene2() {
wx.createSelectorQuery()
.select('#webgl')
.node()
.exec((res) => {
let canvasId = String(res[0].node.id)
const canvas = THREE.global.registerCanvas(canvasId, res[0].node)
this.setData({
canvasId: canvasId
})
//相机
const camera = new THREE.PerspectiveCamera(70, canvas.width / canvas.height, 1, 1000);
//场景
const scene = new THREE.Scene();
scene.background = new THREE.Color(0xffffff);
const renderer = new THREE.WebGLRenderer({
antialias: true
});
camera.position.set(30, 40, 50);
//控制器
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.update();
//加入点光源
let pointColor = "#ccffcc";
let pointLight = new THREE.PointLight(pointColor);
//设置点光源的位置
pointLight.position.set(0, 30, 0)
scene.add(pointLight)
//球体
const sphereGeometry = new THREE.SphereGeometry(4, 20, 20)
const sphereMaterial = new THREE.MeshLambertMaterial({
color: 0x7777ff
})
const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial)
sphere.position.y = 10
sphere.position.z = 10
//设置球体投射阴影
sphere.castShadow = true
scene.add(sphere)
//正方体1
const geometry = new THREE.BoxBufferGeometry(10, 10, 10);
const material = new THREE.MeshLambertMaterial({
color: 0x2a5a5
});
const mesh1 = new THREE.Mesh(geometry, material);
mesh1.position.x = 15
mesh1.name = 'ms1'
//设置正方体投射阴影
mesh1.castShadow = true;
scene.add(mesh1);
//平面
const planeGeometry = new THREE.PlaneGeometry(200, 150, 20, 20);
const planeMaterial = new THREE.MeshLambertMaterial({
color: 0x7777ff
});
planeMaterial.side = THREE.DoubleSide;
const plane = new THREE.Mesh(planeGeometry, planeMaterial)
plane.rotation.x = Math.PI / 2
plane.position.y = -5
//设置平面接收阴影
plane.receiveShadow = true;
scene.add(plane)
//辅助线
const axesHelper = new THREE.AxesHelper(500);
scene.add(axesHelper)
renderer.setPixelRatio(wx.getSystemInfoSync().pixelRatio);
//渲染器使能阴影渲染
renderer.shadowMap.enabled = true
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.setSize(canvas.width, canvas.height);
function render() {
canvas.requestAnimationFrame(render);
//更新控制器
controls.update();
renderer.render(scene, camera);
}
render()
})
},
(4)采用锥形光源场景
锥形光-SpotLight(聚光灯光源),通过设置target属性来确定要照射的对象
initScene3() {
wx.createSelectorQuery()
.select('#webgl')
.node()
.exec((res) => {
let canvasId = String(res[0].node.id)
const canvas = THREE.global.registerCanvas(canvasId, res[0].node)
this.setData({
canvasId: canvasId
})
//相机
const camera = new THREE.PerspectiveCamera(70, canvas.width / canvas.height, 1, 1000);
//场景
const scene = new THREE.Scene();
scene.background = new THREE.Color(0xffffff);
const renderer = new THREE.WebGLRenderer({
antialias: true
});
camera.position.set(30, 40, 50);
//控制器
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.update();
//添加灯光
const spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(-40, 60, -10)
//设置点光源投射阴影
spotLight.castShadow = true;
spotLight.target = plane;
//设置投影显示的像素
spotLight.shadow.mapSize.width = 1024
spotLight.shadow.mapSize.height = 1024
scene.add(spotLight)
//球体
const sphereGeometry = new THREE.SphereGeometry(4, 20, 20)
const sphereMaterial = new THREE.MeshLambertMaterial({
color: 0x7777ff
})
const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial)
sphere.position.y = 10
sphere.position.z = 10
//设置球体投射阴影
sphere.castShadow = true
scene.add(sphere)
//正方体1
const geometry = new THREE.BoxBufferGeometry(10, 10, 10);
const material = new THREE.MeshLambertMaterial({
color: 0x2a5a5
});
const mesh1 = new THREE.Mesh(geometry, material);
mesh1.position.x = 15
mesh1.name = 'ms1'
//设置正方体投射阴影
mesh1.castShadow = true;
scene.add(mesh1);
//平面
const planeGeometry = new THREE.PlaneGeometry(200, 150, 20, 20);
const planeMaterial = new THREE.MeshLambertMaterial({
color: 0x7777ff
});
planeMaterial.side = THREE.DoubleSide;
const plane = new THREE.Mesh(planeGeometry, planeMaterial)
plane.rotation.x = Math.PI / 2
plane.position.y = -5
//设置平面接收阴影
plane.receiveShadow = true;
scene.add(plane)
//辅助线
const axesHelper = new THREE.AxesHelper(500);
scene.add(axesHelper)
renderer.setPixelRatio(wx.getSystemInfoSync().pixelRatio);
//渲染器使能阴影渲染
//renderer.shadowMap.enabled = true
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.setSize(canvas.width, canvas.height);
function render() {
canvas.requestAnimationFrame(render);
//更新控制器
controls.update();
renderer.render(scene, camera);
}
render()
})
}
(5)区域光场景
区域光源--RectAreaLight--可定义为一个发光矩形的光源
initScene5() {
wx.createSelectorQuery()
.select('#webgl')
.node()
.exec((res) => {
let canvasId = String(res[0].node.id)
const canvas = THREE.global.registerCanvas(canvasId, res[0].node)
this.setData({
canvasId: canvasId
})
//相机
const camera = new THREE.PerspectiveCamera(70, canvas.width / canvas.height, 1, 1000);
//场景
const scene = new THREE.Scene();
scene.background = new THREE.Color(0xffffff);
const renderer = new THREE.WebGLRenderer({
antialias: true
});
camera.position.set(30, 40, 50);
//控制器
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.update();
// 地面
var planeGeometry = new THREE.PlaneGeometry(70, 70, 1, 1);
var planeMaterial = new THREE.MeshStandardMaterial({
roughness: 0.044676705160855, // calculated from shininess = 1000
metalness: 0.0
});
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
// plane.receiveShadow = true;
// rotate and position the plane
plane.rotation.x = -0.5 * Math.PI;
plane.position.x = 0;
plane.position.y = 0;
plane.position.z = 0;
// add the plane to the scene
scene.add(plane);
//光线
var spotLight0 = new THREE.SpotLight(0xcccccc);
spotLight0.position.set(-40, 60, -10);
spotLight0.intensity = 0.1;
spotLight0.lookAt(plane);
scene.add(spotLight0);
var areaLight1 = new THREE.RectAreaLight(0xff0000, 500, 4, 10);
areaLight1.position.set(-10, 10, 35);
scene.add(areaLight1);
var areaLight2 = new THREE.RectAreaLight(0x00ff00, 500, 4, 10);
areaLight2.position.set(0, 10, 35);
scene.add(areaLight2);
var areaLight3 = new THREE.RectAreaLight(0x0000ff, 500, 4, 10);
areaLight3.position.set(10, 10, 35);
scene.add(areaLight3);
var planeGeometry1 = new THREE.BoxGeometry(4, 10, 0);
var planeGeometry1Mat = new THREE.MeshBasicMaterial({
color: 0xff0000
});
var plane1 = new THREE.Mesh(planeGeometry1, planeGeometry1Mat);
plane1.position.copy(areaLight1.position);
scene.add(plane1);
var planeGeometry2 = new THREE.BoxGeometry(4, 10, 0);
var planeGeometry2Mat = new THREE.MeshBasicMaterial({
color: 0x00ff00,
});
var plane2 = new THREE.Mesh(planeGeometry2, planeGeometry2Mat);
plane2.position.copy(areaLight2.position);
scene.add(plane2);
var planeGeometry3 = new THREE.BoxGeometry(4, 10, 0);
var planeGeometry3Mat = new THREE.MeshBasicMaterial({
color: 0x0000ff
});
var plane3 = new THREE.Mesh(planeGeometry3, planeGeometry3Mat);
plane3.position.copy(areaLight3.position);
scene.add(plane3);
//辅助线
const axesHelper = new THREE.AxesHelper(500);
scene.add(axesHelper)
renderer.setPixelRatio(wx.getSystemInfoSync().pixelRatio);
//渲染器使能阴影渲染
renderer.shadowMap.enabled = true
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.setSize(canvas.width, canvas.height);
function render() {
canvas.requestAnimationFrame(render);
//更新控制器
controls.update();
renderer.render(scene, camera);
}
render()
})
},
其他的代码就是按钮演示视频中按钮的点击事件函数,点击按钮后渲染不同的场景,这里不做过多赘述。
3.实例小程序
场景演示->Three.js中的各种光源