preface
I started to contact Webgl as a graduate student, and I have been working on Webgl since then. During combined with Cesium, or Threejs have done many projects, but has always been their learning, and the related knowledge of writing, no reflect on this is not good for yourself for the accumulation of knowledge and consolidate, so from this, I will be coming to the past and learn the knowledge of an original article summarizes and output.
This article requires some understanding of Threejs.
This is my first real tech blog, so please forgive me for a lot of mistakes.
The effect
To prepare
Floor data, including floor point coordinates, side maps, and top maps
Where floor represents the number of floors, and Geometry is the polygonal point sequence for constructing floors.
The specific implementation
The steps to realize the lighting and heating of the floor are as follows: First, the floor is constructed, including the side of the floor and the roof; The side structure of the floor is relatively simple, that is, by adding different heights to the sequence of points on the ground to build the sides of different levels; The top surface is constructed by calculating vertex indexes, texture coordinates, and so on from a sequence of points. Then, according to the date, calculate the light duration of the day, sunrise and sunset time (you can Google related information), according to the sunrise and sunset time to get the position of the sun, according to the rays to calculate the daylight duration of the floor. Finally, render different colors for each floor according to the length of daylight.
The main points of
- The daylight duration of each floor is determined from the beginning, so it can be calculated and recorded on the objects of each floor at the time of initialization.
- You can set a precision to calculate the sunshine duration. I chose 40 minutes to calculate the sunshine duration.
- Building floors does not share points, making it easier to render colors on different surfaces
Code snippet
// 16*2.5 const delta = 16; for (let i = startIndex; i < endIndex; i += delta) { const sunPosition = new THREE.Vector3(points[i * 3], points[i * 3 + 1], points[i * 3 + 2]); const {array} = floorObj.geometry.attributes.position; for (let j = 6, length = array.length; j < length; J += 12) {// - let leftBottom, leftTop, rightBottom, rightTop; leftBottom = new THREE.Vector3(array[j], array[j + 1], array[j + 2]); leftTop = new THREE.Vector3(array[j + 3], array[j + 4], array[j + 5]); if (j < length - 12) { rightBottom = new THREE.Vector3(array[j + 6], array[j + 7], array[j + 8]); rightTop = new THREE.Vector3(array[j + 9], array[j + 10], array[j + 11]); } else { rightBottom = new THREE.Vector3(array[0], array[1], array[2]); rightTop = new THREE.Vector3(array[3], array[4], array[5]); } // - Const center = this.calFaceCenter({leftBottom, leftTop, rightBottom, RightTop}). Add (new THREE.Vector3(0, floorHeight * 0.25, 0)); Const normal = originPoint.clone().sub(sunPosition.clone()).normalize(); const origin = (center.clone()).sub(normal.clone().multiplyScalar(100)); const faceNormal = this.getFaceNormal([leftTop, rightTop, rightBottom]); If (normal.dot(faceNormal) > 0) continue; threeNode.raycaster.set(origin, normal); const intersects = threeNode.raycaster.intersectObjects(resultArr, false); // - If it intersects the object of the plane according to the central ray of the plane, Then sunshine if (intersects. Length > 0 && Intersects [0]. Object === floorObj) {const {faceIndex} = Intersects [0]; / / - if the intersection of a plane just for calculating surface, the surface of a sunshine if (faceIndex = = = (j / 3) | | faceIndex = = = (j / 3 + 1)) {if (floorObj.userData.sunFace[faceIndex] ! = = undefined) floorObj. UserData. SunFace [faceIndex] + = delta * 2.5; The else floorObj. UserData. SunFace [faceIndex] = delta * 2.5; }}}}Copy the code