Init Commit

This commit is contained in:
2026-05-26 08:27:41 +08:00
commit 83647f6e77
20 changed files with 367 additions and 0 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 589 KiB

+21
View File
@@ -0,0 +1,21 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Mabulig Web App</title>
<script type="importmap">
{
"imports": {
"three": "https://cdn.jsdelivr.net/npm/three@v0.184.0/build/three.module.js",
"three/addons/": "https://cdn.jsdelivr.net/npm/three@v0.184.0/examples/jsm/"
}
}
</script>
<style>
body { margin: 0; }
</style>
</head>
<body>
<script type="module" src="/main.js"></script>
</body>
</html>
+228
View File
@@ -0,0 +1,228 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - GLTFloader</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<link type="text/css" rel="stylesheet" href="main.css">
</head>
<body>
<div id="info">
<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - GLTFLoader<br />
<a href="https://hdrihaven.com/hdri/?h=royal_esplanade" target="_blank" rel="noopener">Royal Esplanade</a> from <a href="https://hdrihaven.com/" target="_blank" rel="noopener">HDRI Haven</a>
</div>
<script type="importmap">
{
"imports": {
"three": "../build/three.module.js",
"three/addons/": "./jsm/"
}
}
</script>
<script type="module">
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { UltraHDRLoader } from 'three/addons/loaders/UltraHDRLoader.js';
import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
let camera, scene, renderer, controls;
let currentModel, mixer;
let currentLoadId = 0;
const timer = new THREE.Timer();
init();
function init() {
const container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.25, 20 );
camera.position.set( - 1.8, 0.6, 2.7 );
scene = new THREE.Scene();
new UltraHDRLoader()
.setPath( 'textures/equirectangular/' )
.load( 'royal_esplanade_2k.hdr.jpg', function ( texture ) {
texture.mapping = THREE.EquirectangularReflectionMapping;
scene.background = texture;
scene.environment = texture;
render();
// model
fetch( 'https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/model-index.json' )
.then( response => response.json() )
.then( models => {
const gui = new GUI();
const modelNames = models.map( m => m.name );
const params = { model: 'DamagedHelmet' };
if ( ! modelNames.includes( params.model ) && modelNames.length > 0 ) {
params.model = modelNames[ 0 ];
}
gui.add( params, 'model', modelNames ).onChange( name => {
const modelInfo = models.find( m => m.name === name );
loadModel( modelInfo );
} );
gui.add( scene, 'backgroundBlurriness', 0, 1 );
const initialModel = models.find( m => m.name === params.model );
if ( initialModel ) loadModel( initialModel );
} );
} );
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setAnimationLoop( render );
renderer.toneMapping = THREE.ACESFilmicToneMapping;
container.appendChild( renderer.domElement );
controls = new OrbitControls( camera, renderer.domElement );
controls.enableDamping = true;
controls.minDistance = 2;
controls.maxDistance = 10;
controls.target.set( 0, 0, - 0.2 );
controls.update();
window.addEventListener( 'resize', onWindowResize );
}
function loadModel( modelInfo ) {
const variants = modelInfo.variants;
const variant = variants[ 'glTF-Binary' ] || variants[ 'glTF' ];
const url = `https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/${ modelInfo.name }/${ variant.endsWith( '.glb' ) ? 'glTF-Binary' : 'glTF' }/${ variant }`;
if ( currentModel ) {
scene.remove( currentModel );
currentModel = null;
}
if ( mixer ) {
mixer.stopAllAction();
mixer = null;
}
const loadId = ++ currentLoadId;
const loader = new GLTFLoader();
loader.load( url, async function ( gltf ) {
if ( loadId !== currentLoadId ) return;
currentModel = gltf.scene;
// wait until the model can be added to the scene without blocking due to shader compilation
await renderer.compileAsync( currentModel, camera, scene );
if ( loadId !== currentLoadId ) return;
scene.add( currentModel );
fitCameraToSelection( camera, controls, currentModel );
// animations
if ( gltf.animations.length > 0 ) {
mixer = new THREE.AnimationMixer( currentModel );
for ( const animation of gltf.animations ) {
mixer.clipAction( animation ).play();
}
}
} );
}
function fitCameraToSelection( camera, controls, selection, fitOffset = 1.3 ) {
const box = new THREE.Box3();
box.setFromObject( selection );
const size = box.getSize( new THREE.Vector3() );
const center = box.getCenter( new THREE.Vector3() );
const maxSize = Math.max( size.x, size.y, size.z );
const fitHeightDistance = maxSize / ( 2 * Math.atan( Math.PI * camera.fov / 360 ) );
// const fitWidthDistance = fitHeightDistance / camera.aspect;
// const distance = fitOffset * Math.max( fitHeightDistance, fitWidthDistance );
const distance = fitOffset * fitHeightDistance;
const direction = controls.target.clone().sub( camera.position ).normalize().multiplyScalar( distance );
controls.maxDistance = distance * 10;
controls.minDistance = distance / 10;
controls.target.copy( center );
camera.near = distance / 100;
camera.far = distance * 100;
camera.updateProjectionMatrix();
camera.position.copy( controls.target ).sub( direction );
controls.update();
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
render();
}
//
function render() {
timer.update();
controls.update();
if ( mixer ) mixer.update( timer.getDelta() );
renderer.render( scene, camera );
}
</script>
</body>
</html>
+118
View File
@@ -0,0 +1,118 @@
import * as THREE from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { UltraHDRLoader } from 'three/addons/loaders/UltraHDRLoader.js';
import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
const scene = new THREE.Scene();
const sizes = {
width: window.innerWidth,
height: window.innerHeight,
}
//console.log(sizes.width + "x" + sizes.height);
//RENDERER
const renderer = new THREE.WebGLRenderer({antialias:true});
renderer.setSize( sizes.width, sizes.height );
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = 1.5;
renderer.outputColorSpace = THREE.SRGBColorSpace;
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFShadowMap;
document.body.appendChild( renderer.domElement );
//CAMERA
const camera = new THREE.PerspectiveCamera( 65, sizes.width / sizes.height, 0.1, 1000 );
camera.position.x = 0;
camera.position.y = 2;
camera.position.z = 7.5;
const controls = new OrbitControls( camera, renderer.domElement );
controls.enableDamping = true;
controls.dampingFactor = 0.05; // Friction
controls.screenSpacePanning = false; // Vertical panning along screen
controls.update();
//RESIZING
function handleResize(){
sizes.width = window.innerWidth;
sizes.height = window.innerHeight;
camera.aspect = sizes.width/sizes.height;
camera.updateProjectionMatrix();
renderer.setSize( sizes.width, sizes.height );
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
}
window.addEventListener("resize", handleResize);
//MODEL LOADER
let core_logo_mesh;
const loader = new GLTFLoader();
loader.load( 'models/MBS-2408 Oreophryne anulata.glb', function ( glb ) {
core_logo_mesh = glb.scene;
scene.add( glb.scene );
}, undefined, function ( error ) {
console.error( error );
} );
//ENVIRONMENT
const env_loader = new UltraHDRLoader();
const env_texture = await env_loader.loadAsync( 'assets/studio_small_08_4k.jpg' );
env_texture.mapping = THREE.EquirectangularReflectionMapping;
scene.background = new THREE.Color(0xe6e6e6);
// scene.background = env_texture;
// scene.backgroundBlurriness = 0.5;
scene.environment = env_texture;
// console.log(scene.environment);
//LIGHTS
const ambient_light = new THREE.AmbientLight( 0xFFFFFF , 0.1); // soft white light
scene.add( ambient_light );
const sun = new THREE.DirectionalLight( 0xFFFFFF, 0.5);
sun.castShadow = true;
scene.add( sun );
// const helper = new THREE.DirectionalLightHelper( sun, 5 );
// scene.add( helper );
//EFFECTS PASS
// const composer = new EffectComposer( renderer );
// const renderPass = new RenderPass(scene, camera);
// composer.addPass(renderPass);
// const bloomPass = new UnrealBloomPass(
// new THREE.Vector2(sizes.width, sizes.height),
// 0.35, // strength
// 1, // radius
// 1 // threshold
// );
// composer.addPass(bloomPass);
renderer.setAnimationLoop( animate );
function animate( time ) {
//cube.rotation.x = time / 2000;
//cube.rotation.y = time / 1000;
controls.update();
//core_logo_mesh.rotation.y = time / 1000;
renderer.render( scene, camera );
//console.log(camera.position);
// if (core_logo_mesh){
// core_logo_mesh.rotation.y = time / 1500;
// }
//composer.render();
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.