UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

150 lines (117 loc) 4.79 kB
import { Box3, InstancedBufferAttribute, InstancedBufferGeometry, OctahedronBufferGeometry, ShaderMaterial, Sphere } from "three"; import { BinaryDataType } from "../../../../../../../core/binary/type/BinaryDataType.js"; import { AABB3 } from "../../../../../../../core/geom/3d/aabb/AABB3.js"; import { aabb3_from_v3_array } from "../../../../../../../core/geom/3d/aabb/aabb3_from_v3_array.js"; import { v3_length } from "../../../../../../../core/geom/vec3/v3_length.js"; import Entity from "../../../../../../ecs/Entity.js"; import { Transform } from "../../../../../../ecs/transform/Transform.js"; import { ShadedGeometry } from "../../../../../ecs/mesh-v2/ShadedGeometry.js"; import { ShadedGeometryFlags } from "../../../../../ecs/mesh-v2/ShadedGeometryFlags.js"; import { AttributeSpec } from "../../../../../geometry/AttributeSpec.js"; import { geometry_copy } from "../../../../../geometry/instancing/geometry_copy.js"; import { AttributeDataTexture } from "../../../../../texture/AttributeDataTexture.js"; import { makeOctahedralDepthAtlas } from "../../../../gi/material/makeOctahedralDepthAtlas.js"; import { octahedral_depth_to_atlas, vector_buffer_to_attribute_texture } from "../../../probe_volume_to_textures.js"; import fragment from './visualise.frag.glsl' import vertex from './visualise.vert.glsl' /** * * @param {LightProbeVolume} lpv */ function makeMaterial(lpv) { const depth_atlas = makeOctahedralDepthAtlas(); const positions = new AttributeDataTexture( AttributeSpec.fromJSON({ name: "positions", type: BinaryDataType.Float32, itemSize: 3, normalized: false }), 256, 1 ); vector_buffer_to_attribute_texture(positions, lpv.points, lpv.count, 3); octahedral_depth_to_atlas(lpv, depth_atlas.image.data, depth_atlas.image.width); const material = new ShaderMaterial({ fragmentShader: [fragment].join('\n'), vertexShader: vertex, lights: false, uniforms: { lpv_t_probe_positions: { value: positions.texture }, lpv_t_probe_depth: { value: depth_atlas }, lpv_u_probe_depth_resolution:{ value: lpv.depth_map_resolution } } }); return material; } /** * * @param {THREE.BufferGeometry} geometry * @param {AABB3} bounds */ function buffer_geometry_set_bounds_by_aabb3(geometry, bounds) { geometry.boundingBox = new Box3() geometry.boundingSphere = new Sphere() geometry.boundingBox.min.set(bounds.x0, bounds.y0, bounds.z0); geometry.boundingBox.max.set(bounds.x1, bounds.y1, bounds.z1); bounds.getCenter(geometry.boundingSphere.center); geometry.boundingSphere.radius = v3_length(bounds.getHalfExtentsX(), bounds.getHalfExtentsY(), bounds.getHalfExtentsZ()); } export class VLPDepthMapVisualisation { /** * @type {LightProbeVolume} */ #volume set volume(lpv) { this.#volume = lpv; } /** * * @param {LightProbeVolume} lpv * @returns {VLPDepthMapVisualisation} */ static from(lpv) { const r = new VLPDepthMapVisualisation(); r.volume = lpv; return r; } build() { const geometry = new InstancedBufferGeometry(); const volume = this.#volume; geometry.instanceCount = volume.count; geometry_copy(geometry, new OctahedronBufferGeometry(0.4, 4)); const positions_attribute = new InstancedBufferAttribute(new Float32Array(volume.points), 3); geometry.setAttribute("instancePosition", positions_attribute); const bounds = new AABB3(); aabb3_from_v3_array(bounds, volume.points, volume.points.length); const instance_bounds = new AABB3(); const geo_position_data = geometry.getAttribute('position').array; aabb3_from_v3_array(instance_bounds, geo_position_data, geo_position_data.length); // extend by bounds of a single instance bounds.x0 += instance_bounds.x0; bounds.y0 += instance_bounds.y0; bounds.z0 += instance_bounds.z0; bounds.x1 += instance_bounds.x1; bounds.y1 += instance_bounds.y1; bounds.z1 += instance_bounds.z1; buffer_geometry_set_bounds_by_aabb3(geometry, bounds); const sg = ShadedGeometry.from(geometry, makeMaterial(volume)); sg.setFlag(ShadedGeometryFlags.DrawMethodLocked); const entity = new Entity(); entity.add(new Transform()); entity.add(sg); return entity; } }