<template>
<view class="content">
<view id="webgl" class="content"></view>
</view>
</template>
<script>
import * as THREE from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
export default {
data() {
return {
title: "Hello",
camera: null,
scene: null,
bulbLight: null,
hemiLight: null,
floorMat: null,
cubeMat: null,
ballMat: null,
renderer: null,
animateId: "",
};
},
onLoad() {},
mounted() {
this.init();
this.animate();
},
methods: {
init() {
const that = this;
const dom = document.getElementById("webgl");
console.log("dom", dom);
this.camera = new THREE.PerspectiveCamera(
50,
dom.offsetWidth / dom.offsetHeight,
0.1,
100
);
this.camera.position.set(-4, 4, -2);
this.scene = new THREE.Scene();
const axesHelper = new THREE.AxesHelper(5);
this.scene.add(axesHelper);
const bulbGeometry = new THREE.SphereGeometry(0.02, 16, 8);
this.bulbLight = new THREE.PointLight(0xffee88, 1, 100, 2);
const bulbMat = new THREE.MeshStandardMaterial({
emissive: 0xffffee,
emissiveIntensity: 1,
color: 0x000000,
});
this.bulbLight.add(new THREE.Mesh(bulbGeometry, bulbMat));
this.bulbLight.position.set(0, 2, 0);
this.bulbLight.power = 800;
this.bulbLight.castShadow = true;
this.scene.add(this.bulbLight);
const pointLightHelper = new THREE.PointLightHelper(this.bulbLight);
this.scene.add(pointLightHelper);
this.hemiLight = new THREE.HemisphereLight(0xddeeff, 0x0f0e0d, 0.02);
this.hemiLight.intensity = 50;
this.scene.add(this.hemiLight);
const HemisphereHelper = new THREE.HemisphereLightHelper(
this.hemiLight,
5
);
this.scene.add(HemisphereHelper);
this.floorMat = new THREE.MeshStandardMaterial({
roughness: 0.8,
color: 0xffffff,
metalness: 0.2,
bumpScale: 0.0005,
});
const textureLoader = new THREE.TextureLoader();
textureLoader.load("../../static/hardwood2_diffuse.jpg", function (map) {
map.wrapS = THREE.RepeatWrapping;
map.wrapT = THREE.RepeatWrapping;
map.anisotropy = 4;
map.repeat.set(10, 24);
map.colorSpace = THREE.SRGBColorSpace;
that.floorMat.map = map;
that.floorMat.needsUpdate = true;
});
textureLoader.load("../../static/hardwood2_bump.jpg", function (map) {
map.wrapS = THREE.RepeatWrapping;
map.wrapT = THREE.RepeatWrapping;
map.anisotropy = 4;
map.repeat.set(10, 24);
that.floorMat.bumpMap = map;
that.floorMat.needsUpdate = true;
});
textureLoader.load(
"../../static/hardwood2_roughness.jpg",
function (map) {
map.wrapS = THREE.RepeatWrapping;
map.wrapT = THREE.RepeatWrapping;
map.anisotropy = 4;
map.repeat.set(10, 24);
that.floorMat.roughnessMap = map;
that.floorMat.needsUpdate = true;
}
);
this.cubeMat = new THREE.MeshStandardMaterial({
roughness: 0.7,
color: 0xffffff,
bumpScale: 0.002,
metalness: 0.2,
});
textureLoader.load("../../static/brick_diffuse.jpg", function (map) {
map.wrapS = THREE.RepeatWrapping;
map.wrapT = THREE.RepeatWrapping;
map.anisotropy = 4;
map.repeat.set(1, 1);
map.colorSpace = THREE.SRGBColorSpace;
that.cubeMat.map = map;
that.cubeMat.needsUpdate = true;
});
textureLoader.load("../../static/brick_bump.jpg", function (map) {
map.wrapS = THREE.RepeatWrapping;
map.wrapT = THREE.RepeatWrapping;
map.anisotropy = 4;
map.repeat.set(1, 1);
that.cubeMat.bumpMap = map;
that.cubeMat.needsUpdate = true;
});
this.ballMat = new THREE.MeshStandardMaterial({
color: 0xffffff,
roughness: 0.5,
metalness: 1.0,
});
textureLoader.load("../../static/earth_atmos_2048.jpg", function (map) {
map.anisotropy = 4;
map.colorSpace = THREE.SRGBColorSpace;
that.ballMat.map = map;
that.ballMat.needsUpdate = true;
});
textureLoader.load(
"../../static/earth_specular_2048.jpg",
function (map) {
map.anisotropy = 4;
map.colorSpace = THREE.SRGBColorSpace;
that.ballMat.metalnessMap = map;
that.ballMat.needsUpdate = true;
}
);
const floorGeometry = new THREE.PlaneGeometry(20, 20);
const floorMesh = new THREE.Mesh(floorGeometry, this.floorMat);
floorMesh.receiveShadow = true;
floorMesh.rotation.x = -Math.PI / 2.0;
this.scene.add(floorMesh);
const ballGeometry = new THREE.SphereGeometry(0.25, 32, 32);
const ballMesh = new THREE.Mesh(ballGeometry, this.ballMat);
ballMesh.position.set(1, 0.25, 1);
ballMesh.rotation.y = Math.PI;
ballMesh.castShadow = true;
this.scene.add(ballMesh);
const boxGeometry = new THREE.BoxGeometry(0.5, 0.5, 0.5);
const boxMesh = new THREE.Mesh(boxGeometry, this.cubeMat);
boxMesh.position.set(-0.5, 0.25, -1);
boxMesh.castShadow = true;
this.scene.add(boxMesh);
const boxMesh2 = new THREE.Mesh(boxGeometry, this.cubeMat);
boxMesh2.position.set(0, 0.25, -5);
boxMesh2.castShadow = true;
this.scene.add(boxMesh2);
const boxMesh3 = new THREE.Mesh(boxGeometry, this.cubeMat);
boxMesh3.position.set(7, 0.25, 0);
boxMesh3.castShadow = true;
this.scene.add(boxMesh3);
this.renderer = new THREE.WebGLRenderer();
this.renderer.shadowMap.enabled = true;
this.renderer.toneMapping = THREE.ReinhardToneMapping;
this.renderer.setPixelRatio(window.devicePixelRatio);
this.renderer.setSize(dom.offsetWidth, dom.offsetHeight);
dom.appendChild(this.renderer.domElement);
const controls = new OrbitControls(this.camera, this.renderer.domElement);
controls.minDistance = 1;
controls.maxDistance = 20;
},
animate() {
this.animateId = requestAnimationFrame(this.animate);
this.render();
},
cancelAnimate() {
cancelAnimationFrame(this.animateId);
},
render() {
this.renderer.toneMappingExposure = Math.pow(0.68, 5.0);
const time = Date.now() * 0.0005;
this.bulbLight.position.y = Math.cos(time) * 0.75 + 1.25;
this.renderer.render(this.scene, this.camera);
},
},
};
</script>
<style>
.content {
height: 750rpx;
width: 100%;
margin: 0 auto;
}
.logo {
height: 200rpx;
width: 200rpx;
margin: 200rpx auto 50rpx auto;
}
.text-area {
display: flex;
justify-content: center;
}
.title {
font-size: 36rpx;
color: #8f8f94;
}
</style>