샘플 리스트
<!DOCTYPE html> <html lang="en"> <head> <title>three.js webgl - materials - custom blending</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 { margin: 0px; background-color: #111; overflow: hidden; font-family: arial; } .menu { color: #fff; font-weight: bold; font-size: 12px; z-index: 100; width: 75px; position: absolute; top: 0px; padding: 16px; } .menu img, .menu canvas { width: 75px; margin: 10px 0 } #images { background: rgba(0,0,0,0); left: 0px; } #backgrounds { background: rgba(0,0,0,0.0); left: 107px; } #labels { background: rgba(0,0,0,0.75); left: 214px; width: 100px } .lbl { color: #fff; z-index: 150; float:left; padding: 0.25em; width: 75px; display: block } #lbl_dst { background:#800; } #lbl_src { background:green; } .btn { background: darkorange; width: 100px; cursor: pointer } #btn_sub { background: transparent } #btn_rsub { background: transparent } #btn_pre { background: transparent } #btn_rsub, #btn_nopre { margin-bottom: 2em } </style> </head> <body> <div style="background:rgb(255, 255, 255); bottom : 10px; left: 10px; width:256px; height:256px; position: absolute;"> <canvas id="debugimage" style="width:100%;height:100%;"></canvas> </div> <canvas id="bgcanvas"></canvas> <div id="images" class="menu"> Foreground <a id="img_0" href="#"><img src="textures/sprite0.png" /></a> </div> <div id="backgrounds" class="menu"> Background <a id="bg_0" href="#"><img src="textures/a.jpg" /></a> <a id="bg_1" href="#"><img src="textures/a.jpg" /></a> <a id="bg_2" href="#"><img src="textures/a.jpg" /></a> </div> <div id="labels" class="menu"> Equation<br /><br /> <div class="lbl btn" id="btn_add">Add</div> <div class="lbl btn" id="btn_sub">Subtract</div> <div class="lbl btn" id="btn_rsub">ReverseSubtract</div> Premultiply alpha<br /><br /> <div class="lbl btn" id="btn_pre">On</div> <div class="lbl btn" id="btn_nopre">Off</div> Labels<br /><br /> <div class="lbl" id="lbl_src">Source</div> <div class="lbl" id="lbl_dst">Destination</div> </div> <script src="./Cm3WebGL/lib/jquery-2.2.0.min.js"></script> <script src="./Cm3WebGL/cm_compile.js"></script> <script> CMWORLD.Compile.includeCm3Library("./Cm3WebGL/"); </script> <script src="./js/SceneUtils.js"></script> <script> var camera, scene, renderer; var materialBg; var materials = []; var mapsPre = []; var mapsNoPre = []; var currentMaps = mapsNoPre; var currentIndex = 0; init(); animate(); function init() { // CAMERA camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 ); camera.position.z = 700; // SCENE scene = new THREE.Scene(); // TEXTURE LOADER var textureLoader = new THREE.TextureLoader(); // BACKGROUND IMAGES var x = document.createElement( "canvas" ); var xc = x.getContext( "2d" ); x.width = x.height = 128; xc.fillStyle = "#eee"; xc.fillRect( 0, 0, 128, 128 ); xc.fillStyle = "#999"; xc.fillRect( 0, 0, 64, 64 ); xc.fillStyle = "#aaa"; xc.fillRect( 32, 32, 32, 32 ); xc.fillStyle = "#999"; xc.fillRect( 64, 64, 64, 64 ); xc.fillStyle = "#bbb"; xc.fillRect( 96, 96, 32, 32 ); document.getElementById("bg_1").appendChild( x ); var x2 = document.createElement( "canvas" ); var xc2 = x2.getContext( "2d" ); x2.width = x2.height = 128; xc2.fillStyle = "#444"; xc2.fillRect( 0, 0, 128, 128 ); xc2.fillStyle = "#000"; xc2.fillRect( 0, 0, 64, 64 ); xc2.fillStyle = "#111"; xc2.fillRect( 32, 32, 32, 32 ); xc2.fillStyle = "#000"; xc2.fillRect( 64, 64, 64, 64 ); xc2.fillStyle = "#222"; xc2.fillRect( 96, 96, 32, 32 ); document.getElementById("bg_1").appendChild( x ); document.getElementById("bg_2").appendChild( x2 ); var mapBg0 = new THREE.Texture( x ); mapBg0.wrapS = mapBg0.wrapT = THREE.RepeatWrapping; mapBg0.repeat.set( 128, 64 ); mapBg0.needsUpdate = true; var mapBg1 = new THREE.Texture( x2 ); mapBg1.wrapS = mapBg1.wrapT = THREE.RepeatWrapping; mapBg1.repeat.set( 128, 64 ); mapBg1.needsUpdate = true; var mapBg2 = textureLoader.load( "textures/a.jpg" ); mapBg2.wrapS = mapBg2.wrapT = THREE.RepeatWrapping; mapBg2.repeat.set( 8, 4 ); // BACKGROUND materialBg = new THREE.MeshBasicMaterial( { map: mapBg2 } ); var meshBg = new THREE.Mesh( new THREE.PlaneBufferGeometry( 5000, 3000 ), materialBg ); meshBg.position.set( 0, 0, -1 ); scene.add( meshBg ); // FOREGROUND IMAGES var images = ['textures/explosion_dxt5_mip.dds']; //var images = ['http://xdworld.vworld.kr:8080/XDServer/requestLayerNode?APIKey=350E1668-0D3F-348A-A950-7F80174028D5&Layer=tile&Level=7&IDX=1090&IDY=454']; for ( var i = 0; i < images.length; i ++ ) { //var map = textureLoader.load( images[ i ] ); var loader = new THREE.DDSLoader(); var map = loader.load(images[i]); map.anisotropy = 4; mapsNoPre.push( map ); //var mapPre = textureLoader.load(images[i]); var mapPre = loader.load(images[i]); mapPre.premultiplyAlpha = true; mapPre.needsUpdate = true; mapsPre.push( mapPre ); } var canvasimg = document.createElement("canvas"); var canvasctx = canvasimg.getContext("2d"); canvasimg.width = canvasimg.height = 128; canvasctx.fillStyle = "rgba(0.0, 0.0, 0.0, 0.0)"; canvasctx.globalAlpha = 0.0; canvasctx.fillRect(0, 0, canvasimg.width, canvasimg.height); canvasctx.clearRect(0, 0, canvasimg.width, canvasimg.height); canvasctx.globalAlpha = 1.0; canvasctx.strokeStyle = 'yellow'; canvasctx.lineWidth = 3.0; canvasctx.strokeRect(0, 0, canvasimg.width, canvasimg.height); canvasctx.fillStyle = "blue"; canvasctx.fillRect(20, 20, 80, 80); canvasctx.fillStyle = "white"; canvasctx.font = "24pt arial bold"; canvasctx.fillText("궁금해", 8, 30); mapsPre.push(canvasimg); var canvastexture = new THREE.Texture(canvasimg); canvastexture.anisotropy = 4; canvastexture.magFilter = THREE.LinearFilter; canvastexture.minFilter = THREE.LinearFilter; canvastexture.needsUpdate = true; // FOREGROUND OBJECTS var src = [ "ZeroFactor", "OneFactor", "SrcAlphaFactor", "OneMinusSrcAlphaFactor", "DstAlphaFactor", "OneMinusDstAlphaFactor", "DstColorFactor", "OneMinusDstColorFactor", "SrcAlphaSaturateFactor" ]; var dst = [ "ZeroFactor", "OneFactor", "SrcColorFactor", "OneMinusSrcColorFactor", "SrcAlphaFactor", "OneMinusSrcAlphaFactor", "DstAlphaFactor", "OneMinusDstAlphaFactor" ]; //var src = [ "SrcAlphaFactor"]; //var dst = [ "OneMinusSrcAlphaFactor"]; var geo1 = new THREE.PlaneBufferGeometry( 100, 100 ); var geo2 = new THREE.PlaneBufferGeometry( 100, 25 ); var blending = "CustomBlending"; var hemiLight = new THREE.AmbientLight(0x55555555); // soft white light //GlobalOption.hemiLight.color.setHSL(1, 1, 1); //GlobalOption.hemiLight.position.set(0, 0, 0); //GlobalOption.hemiLight.groundColor.setHSL(0.095, 1, 0.75); scene.add(hemiLight); var SunLight = new THREE.DirectionalLight(0xffffff, 0.8); var sunpos = new THREE.Vector3(1, 1, 1); //sunpos.normalize(); SunLight.position.set(sunpos.x, sunpos.y, sunpos.z); scene.add(SunLight); for ( var i = 0; i < dst.length; i ++ ) { var blendDst = dst[ i ]; for ( var j = 0; j < src.length; j ++ ) { var blendSrc = src[ j ]; var material1 = new THREE.MeshBasicMaterial({ map: canvastexture, transparent : true }); material1.transparent = true; material1.blending = THREE.CustomBlending; material1.blendSrc = THREE.SrcAlphaFactor; material1.blendDst = THREE.OneMinusSrcAlphaFactor; material1.blending = THREE[ blending ]; material1.blendSrc = THREE[ blendSrc ]; material1.blendDst = THREE[ blendDst ]; material1.blendEquation = THREE.AddEquation; var x = ( j - src.length / 2 ) * 110; var z = 0; var y = (i - dst.length / 2) * 110 + 50; var material2 = new THREE.MeshBasicMaterial({ map: currentMaps[0] }); //var mesh = new THREE.Mesh(geo1, material2); var mesh = THREE.SceneUtils.createMultiMaterialObject(geo1, [material1, material2]); mesh.position.set(x, -y, z); mesh.name = "testmesh"; //mesh.matrixAutoUpdate = false; mesh.updateMatrix(); scene.add( mesh ); materials.push( material2 ); } } for ( var j = 0; j < src.length; j ++ ) { var blendSrc = src[ j ]; var x = ( j - src.length / 2 ) * 110; var z = 0; var y = ( 0 - dst.length / 2 ) * 110 + 50; var mesh = new THREE.Mesh( geo2, generateLabelMaterial( blendSrc.replace( "Factor", "" ), "rgba( 0, 150, 0, 1 )" ) ); mesh.position.set( x, - (y - 70), z ); //mesh.matrixAutoUpdate = false; mesh.updateMatrix(); scene.add( mesh ); } for ( var i = 0; i < dst.length; i ++ ) { var blendDst = dst[ i ]; var x = ( 0 - src.length / 2 ) * 110 - 125; var z = 0; var y = ( i - dst.length / 2 ) * 110 + 165; var mesh = new THREE.Mesh( geo2, generateLabelMaterial( blendDst.replace( "Factor", "" ), "rgba( 150, 0, 0, 1 )" ) ); mesh.position.set( x, - (y - 120), z ); //mesh.matrixAutoUpdate = false; mesh.updateMatrix(); scene.add( mesh ); } // RENDERER renderer = new THREE.WebGLRenderer({ canvas: bgcanvas }); renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); renderer.domElement.style.position = "absolute"; renderer.domElement.style.left = "215px"; document.body.appendChild( renderer.domElement ); // EVENTS window.addEventListener( 'resize', onWindowResize, false ); addImgHandler( "img_0", 0 ); addBgHandler( "bg_0", mapBg2 ); addBgHandler( "bg_1", mapBg0 ); addBgHandler( "bg_2", mapBg1 ); addEqHandler( "btn_add", THREE.AddEquation ); addEqHandler( "btn_sub", THREE.SubtractEquation ); addEqHandler( "btn_rsub", THREE.ReverseSubtractEquation ); addPreHandler( "btn_pre", mapsPre ); addPreHandler( "btn_nopre", mapsNoPre ); var imgdata = canvasctx.getImageData(0, 0, canvasimg.width, canvasimg.height); var debugcanvas = document.getElementById("debugimage"); var ctx = debugcanvas.getContext("2d"); //ctx.clearRect(0, 0, this.Image.width, this.Image.height); ctx.setTransform(1, 0, 0, 1, 0, 0); ctx.fillStyle = 'blue'; ctx.fillRect(0, 0, canvasimg.width, canvasimg.height); ctx.drawImage(canvasimg, 0, 0, canvasimg.width, canvasimg.height); } // function addImgHandler( id, index ) { var el = document.getElementById( id ); el.addEventListener( 'click', function () { for ( var i = 0; i < materials.length; i ++ ) { materials[ i ].map = currentMaps[ index ]; } currentIndex = index; } ); } function addEqHandler( id, eq ) { var el = document.getElementById( id ); el.addEventListener( 'click', function () { for ( var i = 0; i < materials.length; i ++ ) { materials[ i ].blendEquation = eq; } document.getElementById( "btn_add" ).style.backgroundColor = "transparent"; document.getElementById( "btn_sub" ).style.backgroundColor = "transparent"; document.getElementById( "btn_rsub" ).style.backgroundColor = "transparent"; el.style.backgroundColor = "darkorange"; }); } function addBgHandler( id, map ) { var el = document.getElementById( id ); el.addEventListener( 'click', function () { materialBg.map = map; } ); } function addPreHandler( id, marray ) { var el = document.getElementById( id ); el.addEventListener( 'click', function () { currentMaps = marray; for ( var i = 0; i < materials.length; i ++ ) { materials[ i ].map = currentMaps[ currentIndex ]; } document.getElementById( "btn_pre" ).style.backgroundColor = "transparent"; document.getElementById( "btn_nopre" ).style.backgroundColor = "transparent"; el.style.backgroundColor = "darkorange"; } ); } // function onWindowResize( event ) { renderer.setSize( window.innerWidth, window.innerHeight ); camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); } // function generateLabelMaterial( text, bg ) { var x = document.createElement( "canvas" ); var xc = x.getContext( "2d" ); x.width = 128; x.height = 32; xc.fillStyle = bg; xc.fillRect( 0, 0, 128, 32 ); //xc.shadowColor = "#000"; //xc.shadowBlur = 3; xc.fillStyle = "white"; xc.font = "12pt arial bold"; xc.fillText( text, 8, 22 ); var map = new THREE.Texture( x ); map.needsUpdate = true; var material = new THREE.MeshBasicMaterial( { map: map, transparent: true } ); return material; } function animate() { requestAnimationFrame( animate ); var time = Date.now() * 0.00025; var ox = ( time * -0.01 * materialBg.map.repeat.x ) % 1; var oy = ( time * -0.01 * materialBg.map.repeat.y ) % 1; materialBg.map.offset.set( ox, oy ); renderer.clear(); renderer.render( scene, camera ); } </script> </body> </html>