Files
apt-nl-map/static/Magic4/js/three.js-dev/examples/webgl_materials_compile.html

232 lines
4.9 KiB
HTML
Raw Normal View History

2024-12-04 10:21:04 +08:00
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - node material</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">
<style>
#waitScreen {
color: #fff;
position: absolute;
top: 50%;
left: 50%;
margin-top: -50px;
margin-left: -50px;
width: 100px;
height: 100px;
}
.hide {
display:none;
}
</style>
</head>
<body>
<div id="container"></div>
<div id="info">
<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - Node-Based Material
<br /><span class="button" id="preload">change preload</span>
</div>
<div id="waitScreen">
Loading ...
</div>
<script type="module">
import * as THREE from '../build/three.module.js';
import { OrbitControls } from './jsm/controls/OrbitControls.js';
import { TeapotGeometry } from './jsm/geometries/TeapotGeometry.js';
import {
NodeFrame,
FloatNode,
ColorNode,
ConstNode,
ExpressionNode,
MathNode,
OperatorNode,
TimerNode,
PhongNodeMaterial
} from './jsm/nodes/Nodes.js';
const container = document.getElementById( 'container' );
let renderer, scene, camera;
const clock = new THREE.Clock(), fov = 50;
const frame = new NodeFrame();
let teapot;
let controls;
const meshes = [];
document.getElementById( "preload" ).addEventListener( 'click', function () {
const hash = document.location.hash.substr( 1 );
if ( hash.length === 0 ) {
window.location.hash = "#NoPreLoad";
} else {
window.location.hash = "";
}
location.reload( true );
} );
window.addEventListener( 'load', init );
function init() {
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( fov, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.x = 0;
camera.position.z = - 300;
camera.position.y = 200;
controls = new OrbitControls( camera, renderer.domElement );
controls.minDistance = 50;
controls.maxDistance = 400;
scene.add( new THREE.AmbientLight( 0x464646 ) );
const light1 = new THREE.DirectionalLight( 0xffddcc, 1 );
light1.position.set( 1, 0.75, 0.5 );
scene.add( light1 );
const light2 = new THREE.DirectionalLight( 0xccccff, 1 );
light2.position.set( - 1, 0.75, - 0.5 );
scene.add( light2 );
teapot = new TeapotGeometry( 15, 18 );
const itemsonrow = 10;
for ( let i = 0; i < itemsonrow * itemsonrow; i ++ ) {
const mesh = new THREE.Mesh( teapot );
mesh.position.x = 50 * ( i % itemsonrow ) - 50 * itemsonrow / 2;
mesh.position.z = 50 * Math.floor( i / itemsonrow ) - 150;
updateMaterial( mesh );
scene.add( mesh );
meshes.push( mesh );
}
window.addEventListener( 'resize', onWindowResize );
const hash = document.location.hash.substr( 1 );
if ( hash.length === 0 ) {
renderer.compile( scene, camera );
}
document.getElementById( "waitScreen" ).className = "hide";
setTimeout( function () {
onWindowResize();
animate();
}, 1 );
}
function updateMaterial( mesh ) {
if ( mesh.material ) mesh.material.dispose();
const mtl = new PhongNodeMaterial();
const time = new TimerNode();
const speed = new FloatNode( Math.random() );
const color = new ColorNode( Math.random() * 0xFFFFFF );
const timeSpeed = new OperatorNode(
time,
speed,
OperatorNode.MUL
);
const sinCycleInSecs = new OperatorNode(
timeSpeed,
new ConstNode( ConstNode.PI2 ),
OperatorNode.MUL
);
const cycle = new MathNode( sinCycleInSecs, MathNode.SIN );
const cycleColor = new OperatorNode(
cycle,
color,
OperatorNode.MUL
);
const cos = new MathNode( cycleColor, MathNode.SIN );
mtl.color = new ColorNode( 0 );
mtl.emissive = cos;
const transformer = new ExpressionNode( "position + 0.0 * " + Math.random(), "vec3", [ ] );
mtl.transform = transformer;
// build shader ( ignore auto build )
mtl.build();
// set material
mesh.material = mtl;
}
function onWindowResize() {
const width = window.innerWidth, height = window.innerHeight;
camera.aspect = width / height;
camera.updateProjectionMatrix();
renderer.setSize( width, height );
}
function animate() {
const delta = clock.getDelta();
frame.update( delta );
for ( let i = 0; i < meshes.length; i ++ ) {
const mesh = meshes[ i ];
frame.updateNode( mesh.material );
}
renderer.render( scene, camera );
requestAnimationFrame( animate );
}
</script>
</body>
</html>