You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
iot/projects/StudyCenter/wwwroot/lib/three.js/examples/webgl_sprites_nodes.html

258 lines
6.8 KiB

<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - sprites nodes</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
color: #fff;
font-family:Monospace;
font-size:13px;
margin: 0px;
text-align:center;
overflow: hidden;
}
#info {
color: #fff;
position: absolute;
top: 10px;
width: 100%;
text-align: center;
display:block;
}
a { color: white; }
</style>
</head>
<body>
<div id="container"></div>
<div id="info">
<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - Node-Based Sprites
</div>
<script src="../build/three.js"></script>
<script src='js/geometries/TeapotBufferGeometry.js'></script>
<script src="js/controls/OrbitControls.js"></script>
<script src="js/libs/dat.gui.min.js"></script>
<script type="module">
import './js/nodes/THREE.Nodes.js';
import './js/loaders/NodeMaterialLoader.js';
var container = document.getElementById( 'container' );
var renderer, scene, camera, clock = new THREE.Clock(), fov = 50;
var frame = new THREE.NodeFrame();
var sprite1, sprite2, sprite3;
var walkingManTexture, walkingManTextureURL;
var library = {};
var controls;
window.addEventListener( 'load', init );
function init() {
//
// Renderer / Controls
//
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
scene = new THREE.Scene();
scene.fog = new THREE.Fog( 0x0000FF, 70, 150 );
camera = new THREE.PerspectiveCamera( fov, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.z = 100;
camera.target = new THREE.Vector3();
controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.minDistance = 50;
controls.maxDistance = 200;
//
// SpriteNode
//
// https://openclipart.org/detail/239883/walking-man-sprite-sheet
walkingManTextureURL = "textures/WalkingManSpriteSheet.png";
walkingManTexture = new THREE.TextureLoader().load( walkingManTextureURL );
walkingManTexture.wrapS = walkingManTexture.wrapT = THREE.RepeatWrapping;
library[ walkingManTextureURL ] = walkingManTexture;
// horizontal sprite-sheet animator
function createHorizontalSpriteSheetNode( hCount, speed ) {
var speed = new THREE.Vector2Node( speed, 0 ); // frame per second
var scale = new THREE.Vector2Node( 1 / hCount, 1 ); // 8 horizontal images in sprite-sheet
var uvTimer = new THREE.OperatorNode(
new THREE.TimerNode(),
speed,
THREE.OperatorNode.MUL
);
var uvIntegerTimer = new THREE.Math1Node(
uvTimer,
THREE.Math1Node.FLOOR
);
var uvFrameOffset = new THREE.OperatorNode(
uvIntegerTimer,
scale,
THREE.OperatorNode.MUL
);
var uvScale = new THREE.OperatorNode(
new THREE.UVNode(),
scale,
THREE.OperatorNode.MUL
);
var uvFrame = new THREE.OperatorNode(
uvScale,
uvFrameOffset,
THREE.OperatorNode.ADD
);
return uvFrame;
}
// sprites
var spriteWidth = 20,
spriteHeight = 20;
scene.add( sprite1 = new THREE.Sprite( new THREE.SpriteNodeMaterial() ) );
sprite1.scale.x = spriteWidth;
sprite1.scale.y = spriteHeight;
sprite1.material.color = new THREE.TextureNode( walkingManTexture );
sprite1.material.color.uv = createHorizontalSpriteSheetNode( 8, 10 );
scene.add( sprite2 = new THREE.Sprite( new THREE.SpriteNodeMaterial() ) );
sprite2.position.x = 30;
sprite2.scale.x = spriteWidth;
sprite2.scale.y = spriteHeight;
sprite2.material.color = new THREE.TextureNode( walkingManTexture );
sprite2.material.color.uv = createHorizontalSpriteSheetNode( 8, 30 );
sprite2.material.color = new THREE.Math1Node( sprite2.material.color, THREE.Math1Node.INVERT );
sprite2.material.spherical = false; // look at camera horizontally only, very used in vegetation
// horizontal zigzag sprite
sprite2.material.position = new THREE.OperatorNode(
new THREE.OperatorNode(
new THREE.Math1Node( new THREE.TimerNode( 3 ), THREE.Math1Node.SIN ), // 3 is speed (time scale)
new THREE.Vector2Node( .3, 0 ), // horizontal scale (position)
THREE.OperatorNode.MUL
),
new THREE.PositionNode(),
THREE.OperatorNode.ADD
);
var sineWaveFunction = new THREE.FunctionNode( [
// https://stackoverflow.com/questions/36174431/how-to-make-a-wave-warp-effect-in-shader
"vec2 sineWave(vec2 uv, vec2 phase) {",
// wave distortion
" float x = sin( 25.0*uv.y + 30.0*uv.x + 6.28*phase.x) * 0.01;",
" float y = sin( 25.0*uv.y + 30.0*uv.x + 6.28*phase.y) * 0.03;",
" return vec2(uv.x+x, uv.y+y);",
"}"
].join( "\n" ) );
scene.add( sprite3 = new THREE.Sprite( new THREE.SpriteNodeMaterial() ) );
sprite3.position.x = - 30;
sprite3.scale.x = spriteWidth;
sprite3.scale.y = spriteHeight;
sprite3.material.color = new THREE.TextureNode( walkingManTexture );
sprite3.material.color.uv = new THREE.FunctionCallNode( sineWaveFunction, {
"uv": createHorizontalSpriteSheetNode( 8, 10 ),
"phase": new THREE.TimerNode()
} );
sprite3.material.fog = true;
//
// Test serialization
//
spriteToJSON( sprite1 );
spriteToJSON( sprite2 );
spriteToJSON( sprite3 );
//
// Events
//
window.addEventListener( 'resize', onWindowResize, false );
onWindowResize();
animate();
}
function spriteToJSON( sprite ) {
// serialize
var json = sprite.material.toJSON();
// replace uuid to url (facilitates the load of textures using url otherside uuid)
THREE.NodeMaterialLoaderUtils.replaceUUID( json, walkingManTexture, walkingManTextureURL );
// deserialize
var material = new THREE.NodeMaterialLoader( null, library ).parse( json );
// replace material
sprite.material.dispose();
sprite.material = material;
}
function onWindowResize() {
var width = window.innerWidth, height = window.innerHeight;
camera.aspect = width / height;
camera.updateProjectionMatrix();
renderer.setSize( width, height );
}
function animate() {
var delta = clock.getDelta();
// update material animation and/or gpu calcs (pre-renderer)
frame.update( delta )
.updateNode( sprite1.material )
.updateNode( sprite2.material )
.updateNode( sprite3.material );
// rotate sprite
sprite3.rotation.z -= Math.PI * .005;
renderer.render( scene, camera );
requestAnimationFrame( animate );
}
</script>
</body>
</html>