webvr js meetup initial commit
This commit is contained in:
152
node_modules/three/examples/js/effects/AnaglyphEffect.js
generated
vendored
Normal file
152
node_modules/three/examples/js/effects/AnaglyphEffect.js
generated
vendored
Normal file
@@ -0,0 +1,152 @@
|
||||
/**
|
||||
* @author mrdoob / http://mrdoob.com/
|
||||
* @author marklundin / http://mark-lundin.com/
|
||||
* @author alteredq / http://alteredqualia.com/
|
||||
* @author tschw
|
||||
*/
|
||||
|
||||
THREE.AnaglyphEffect = function ( renderer, width, height ) {
|
||||
|
||||
// Matrices generated with angler.js https://github.com/tschw/angler.js/
|
||||
// (in column-major element order, as accepted by WebGL)
|
||||
|
||||
this.colorMatrixLeft = new THREE.Matrix3().fromArray( [
|
||||
|
||||
1.0671679973602295, -0.0016435992438346148, 0.0001777536963345483, // r out
|
||||
-0.028107794001698494, -0.00019593400065787137, -0.0002875397040043026, // g out
|
||||
-0.04279090091586113, 0.000015809757314855233, -0.00024287120322696865 // b out
|
||||
|
||||
] );
|
||||
|
||||
// red green blue in
|
||||
|
||||
this.colorMatrixRight = new THREE.Matrix3().fromArray( [
|
||||
|
||||
-0.0355340838432312, -0.06440307199954987, 0.018319187685847282, // r out
|
||||
-0.10269022732973099, 0.8079727292060852, -0.04835830628871918, // g out
|
||||
0.0001224992738571018, -0.009558862075209618, 0.567823588848114 // b out
|
||||
|
||||
] );
|
||||
|
||||
var _camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
|
||||
|
||||
var _scene = new THREE.Scene();
|
||||
|
||||
var _stereo = new THREE.StereoCamera();
|
||||
|
||||
var _params = { minFilter: THREE.LinearFilter, magFilter: THREE.NearestFilter, format: THREE.RGBAFormat };
|
||||
|
||||
if ( width === undefined ) width = 512;
|
||||
if ( height === undefined ) height = 512;
|
||||
|
||||
var _renderTargetL = new THREE.WebGLRenderTarget( width, height, _params );
|
||||
var _renderTargetR = new THREE.WebGLRenderTarget( width, height, _params );
|
||||
|
||||
var _material = new THREE.ShaderMaterial( {
|
||||
|
||||
uniforms: {
|
||||
|
||||
"mapLeft": { value: _renderTargetL.texture },
|
||||
"mapRight": { value: _renderTargetR.texture },
|
||||
|
||||
"colorMatrixLeft": { value: this.colorMatrixLeft },
|
||||
"colorMatrixRight": { value: this.colorMatrixRight }
|
||||
|
||||
},
|
||||
|
||||
vertexShader: [
|
||||
|
||||
"varying vec2 vUv;",
|
||||
|
||||
"void main() {",
|
||||
|
||||
" vUv = vec2( uv.x, uv.y );",
|
||||
" gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
|
||||
|
||||
"}"
|
||||
|
||||
].join( "\n" ),
|
||||
|
||||
fragmentShader: [
|
||||
|
||||
"uniform sampler2D mapLeft;",
|
||||
"uniform sampler2D mapRight;",
|
||||
"varying vec2 vUv;",
|
||||
|
||||
"uniform mat3 colorMatrixLeft;",
|
||||
"uniform mat3 colorMatrixRight;",
|
||||
|
||||
// These functions implement sRGB linearization and gamma correction
|
||||
|
||||
"float lin( float c ) {",
|
||||
" return c <= 0.04045 ? c * 0.0773993808 :",
|
||||
" pow( c * 0.9478672986 + 0.0521327014, 2.4 );",
|
||||
"}",
|
||||
|
||||
"vec4 lin( vec4 c ) {",
|
||||
" return vec4( lin( c.r ), lin( c.g ), lin( c.b ), c.a );",
|
||||
"}",
|
||||
|
||||
"float dev( float c ) {",
|
||||
" return c <= 0.0031308 ? c * 12.92",
|
||||
" : pow( c, 0.41666 ) * 1.055 - 0.055;",
|
||||
"}",
|
||||
|
||||
|
||||
"void main() {",
|
||||
|
||||
" vec2 uv = vUv;",
|
||||
|
||||
" vec4 colorL = lin( texture2D( mapLeft, uv ) );",
|
||||
" vec4 colorR = lin( texture2D( mapRight, uv ) );",
|
||||
|
||||
" vec3 color = clamp(",
|
||||
" colorMatrixLeft * colorL.rgb +",
|
||||
" colorMatrixRight * colorR.rgb, 0., 1. );",
|
||||
|
||||
" gl_FragColor = vec4(",
|
||||
" dev( color.r ), dev( color.g ), dev( color.b ),",
|
||||
" max( colorL.a, colorR.a ) );",
|
||||
|
||||
"}"
|
||||
|
||||
].join( "\n" )
|
||||
|
||||
} );
|
||||
|
||||
var mesh = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2, 2 ), _material );
|
||||
_scene.add( mesh );
|
||||
|
||||
this.setSize = function ( width, height ) {
|
||||
|
||||
renderer.setSize( width, height );
|
||||
|
||||
var pixelRatio = renderer.getPixelRatio();
|
||||
|
||||
_renderTargetL.setSize( width * pixelRatio, height * pixelRatio );
|
||||
_renderTargetR.setSize( width * pixelRatio, height * pixelRatio );
|
||||
|
||||
};
|
||||
|
||||
this.render = function ( scene, camera ) {
|
||||
|
||||
scene.updateMatrixWorld();
|
||||
|
||||
if ( camera.parent === null ) camera.updateMatrixWorld();
|
||||
|
||||
_stereo.update( camera );
|
||||
|
||||
renderer.render( scene, _stereo.cameraL, _renderTargetL, true );
|
||||
renderer.render( scene, _stereo.cameraR, _renderTargetR, true );
|
||||
renderer.render( _scene, _camera );
|
||||
|
||||
};
|
||||
|
||||
this.dispose = function() {
|
||||
|
||||
if ( _renderTargetL ) _renderTargetL.dispose();
|
||||
if ( _renderTargetR ) _renderTargetR.dispose();
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
283
node_modules/three/examples/js/effects/AsciiEffect.js
generated
vendored
Normal file
283
node_modules/three/examples/js/effects/AsciiEffect.js
generated
vendored
Normal file
@@ -0,0 +1,283 @@
|
||||
/*
|
||||
* @author zz85 / https://github.com/zz85
|
||||
*
|
||||
* Ascii generation is based on http://www.nihilogic.dk/labs/jsascii/
|
||||
* Maybe more about this later with a blog post at http://lab4games.net/zz85/blog
|
||||
*
|
||||
* 16 April 2012 - @blurspline
|
||||
*/
|
||||
|
||||
THREE.AsciiEffect = function ( renderer, charSet, options ) {
|
||||
|
||||
// its fun to create one your own!
|
||||
|
||||
charSet = ( charSet === undefined ) ? ' .:-=+*#%@' : charSet;
|
||||
|
||||
// ' .,:;=|iI+hHOE#`$';
|
||||
// darker bolder character set from https://github.com/saw/Canvas-ASCII-Art/
|
||||
// ' .\'`^",:;Il!i~+_-?][}{1)(|/tfjrxnuvczXYUJCLQ0OZmwqpdbkhao*#MW&8%B@$'.split('');
|
||||
|
||||
if ( ! options ) options = {};
|
||||
|
||||
// Some ASCII settings
|
||||
|
||||
var bResolution = ! options[ 'resolution' ] ? 0.15 : options[ 'resolution' ]; // Higher for more details
|
||||
var iScale = ! options[ 'scale' ] ? 1 : options[ 'scale' ];
|
||||
var bColor = ! options[ 'color' ] ? false : options[ 'color' ]; // nice but slows down rendering!
|
||||
var bAlpha = ! options[ 'alpha' ] ? false : options[ 'alpha' ]; // Transparency
|
||||
var bBlock = ! options[ 'block' ] ? false : options[ 'block' ]; // blocked characters. like good O dos
|
||||
var bInvert = ! options[ 'invert' ] ? false : options[ 'invert' ]; // black is white, white is black
|
||||
|
||||
var strResolution = 'low';
|
||||
|
||||
var width, height;
|
||||
|
||||
var domElement = document.createElement( 'div' );
|
||||
domElement.style.cursor = 'default';
|
||||
|
||||
var oAscii = document.createElement( "table" );
|
||||
domElement.appendChild( oAscii );
|
||||
|
||||
var iWidth, iHeight;
|
||||
var oImg;
|
||||
|
||||
this.setSize = function ( w, h ) {
|
||||
|
||||
width = w;
|
||||
height = h;
|
||||
|
||||
renderer.setSize( w, h );
|
||||
|
||||
initAsciiSize();
|
||||
|
||||
};
|
||||
|
||||
|
||||
this.render = function ( scene, camera ) {
|
||||
|
||||
renderer.render( scene, camera );
|
||||
asciifyImage( renderer, oAscii );
|
||||
|
||||
};
|
||||
|
||||
this.domElement = domElement;
|
||||
|
||||
|
||||
// Throw in ascii library from http://www.nihilogic.dk/labs/jsascii/jsascii.js
|
||||
|
||||
/*
|
||||
* jsAscii 0.1
|
||||
* Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
|
||||
* MIT License [http://www.nihilogic.dk/licenses/mit-license.txt]
|
||||
*/
|
||||
|
||||
function initAsciiSize() {
|
||||
|
||||
iWidth = Math.round( width * fResolution );
|
||||
iHeight = Math.round( height * fResolution );
|
||||
|
||||
oCanvas.width = iWidth;
|
||||
oCanvas.height = iHeight;
|
||||
// oCanvas.style.display = "none";
|
||||
// oCanvas.style.width = iWidth;
|
||||
// oCanvas.style.height = iHeight;
|
||||
|
||||
oImg = renderer.domElement;
|
||||
|
||||
if ( oImg.style.backgroundColor ) {
|
||||
|
||||
oAscii.rows[ 0 ].cells[ 0 ].style.backgroundColor = oImg.style.backgroundColor;
|
||||
oAscii.rows[ 0 ].cells[ 0 ].style.color = oImg.style.color;
|
||||
|
||||
}
|
||||
|
||||
oAscii.cellSpacing = 0;
|
||||
oAscii.cellPadding = 0;
|
||||
|
||||
var oStyle = oAscii.style;
|
||||
oStyle.display = "inline";
|
||||
oStyle.width = Math.round( iWidth / fResolution * iScale ) + "px";
|
||||
oStyle.height = Math.round( iHeight / fResolution * iScale ) + "px";
|
||||
oStyle.whiteSpace = "pre";
|
||||
oStyle.margin = "0px";
|
||||
oStyle.padding = "0px";
|
||||
oStyle.letterSpacing = fLetterSpacing + "px";
|
||||
oStyle.fontFamily = strFont;
|
||||
oStyle.fontSize = fFontSize + "px";
|
||||
oStyle.lineHeight = fLineHeight + "px";
|
||||
oStyle.textAlign = "left";
|
||||
oStyle.textDecoration = "none";
|
||||
|
||||
}
|
||||
|
||||
|
||||
var aDefaultCharList = ( " .,:;i1tfLCG08@" ).split( "" );
|
||||
var aDefaultColorCharList = ( " CGO08@" ).split( "" );
|
||||
var strFont = "courier new, monospace";
|
||||
|
||||
var oCanvasImg = renderer.domElement;
|
||||
|
||||
var oCanvas = document.createElement( "canvas" );
|
||||
if ( ! oCanvas.getContext ) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
var oCtx = oCanvas.getContext( "2d" );
|
||||
if ( ! oCtx.getImageData ) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
var aCharList = ( bColor ? aDefaultColorCharList : aDefaultCharList );
|
||||
|
||||
if ( charSet ) aCharList = charSet;
|
||||
|
||||
var fResolution = 0.5;
|
||||
|
||||
switch ( strResolution ) {
|
||||
|
||||
case "low" : fResolution = 0.25; break;
|
||||
case "medium" : fResolution = 0.5; break;
|
||||
case "high" : fResolution = 1; break;
|
||||
|
||||
}
|
||||
|
||||
if ( bResolution ) fResolution = bResolution;
|
||||
|
||||
// Setup dom
|
||||
|
||||
var fFontSize = ( 2 / fResolution ) * iScale;
|
||||
var fLineHeight = ( 2 / fResolution ) * iScale;
|
||||
|
||||
// adjust letter-spacing for all combinations of scale and resolution to get it to fit the image width.
|
||||
|
||||
var fLetterSpacing = 0;
|
||||
|
||||
if ( strResolution == "low" ) {
|
||||
|
||||
switch ( iScale ) {
|
||||
case 1 : fLetterSpacing = - 1; break;
|
||||
case 2 :
|
||||
case 3 : fLetterSpacing = - 2.1; break;
|
||||
case 4 : fLetterSpacing = - 3.1; break;
|
||||
case 5 : fLetterSpacing = - 4.15; break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( strResolution == "medium" ) {
|
||||
|
||||
switch ( iScale ) {
|
||||
case 1 : fLetterSpacing = 0; break;
|
||||
case 2 : fLetterSpacing = - 1; break;
|
||||
case 3 : fLetterSpacing = - 1.04; break;
|
||||
case 4 :
|
||||
case 5 : fLetterSpacing = - 2.1; break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( strResolution == "high" ) {
|
||||
|
||||
switch ( iScale ) {
|
||||
case 1 :
|
||||
case 2 : fLetterSpacing = 0; break;
|
||||
case 3 :
|
||||
case 4 :
|
||||
case 5 : fLetterSpacing = - 1; break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// can't get a span or div to flow like an img element, but a table works?
|
||||
|
||||
|
||||
// convert img element to ascii
|
||||
|
||||
function asciifyImage( canvasRenderer, oAscii ) {
|
||||
|
||||
oCtx.clearRect( 0, 0, iWidth, iHeight );
|
||||
oCtx.drawImage( oCanvasImg, 0, 0, iWidth, iHeight );
|
||||
var oImgData = oCtx.getImageData( 0, 0, iWidth, iHeight ).data;
|
||||
|
||||
// Coloring loop starts now
|
||||
var strChars = "";
|
||||
|
||||
// console.time('rendering');
|
||||
|
||||
for ( var y = 0; y < iHeight; y += 2 ) {
|
||||
|
||||
for ( var x = 0; x < iWidth; x ++ ) {
|
||||
|
||||
var iOffset = ( y * iWidth + x ) * 4;
|
||||
|
||||
var iRed = oImgData[ iOffset ];
|
||||
var iGreen = oImgData[ iOffset + 1 ];
|
||||
var iBlue = oImgData[ iOffset + 2 ];
|
||||
var iAlpha = oImgData[ iOffset + 3 ];
|
||||
var iCharIdx;
|
||||
|
||||
var fBrightness;
|
||||
|
||||
fBrightness = ( 0.3 * iRed + 0.59 * iGreen + 0.11 * iBlue ) / 255;
|
||||
// fBrightness = (0.3*iRed + 0.5*iGreen + 0.3*iBlue) / 255;
|
||||
|
||||
if ( iAlpha == 0 ) {
|
||||
|
||||
// should calculate alpha instead, but quick hack :)
|
||||
//fBrightness *= (iAlpha / 255);
|
||||
fBrightness = 1;
|
||||
|
||||
}
|
||||
|
||||
iCharIdx = Math.floor( ( 1 - fBrightness ) * ( aCharList.length - 1 ) );
|
||||
|
||||
if ( bInvert ) {
|
||||
|
||||
iCharIdx = aCharList.length - iCharIdx - 1;
|
||||
|
||||
}
|
||||
|
||||
// good for debugging
|
||||
//fBrightness = Math.floor(fBrightness * 10);
|
||||
//strThisChar = fBrightness;
|
||||
|
||||
var strThisChar = aCharList[ iCharIdx ];
|
||||
|
||||
if ( strThisChar === undefined || strThisChar == " " )
|
||||
strThisChar = " ";
|
||||
|
||||
if ( bColor ) {
|
||||
|
||||
strChars += "<span style='"
|
||||
+ "color:rgb(" + iRed + "," + iGreen + "," + iBlue + ");"
|
||||
+ ( bBlock ? "background-color:rgb(" + iRed + "," + iGreen + "," + iBlue + ");" : "" )
|
||||
+ ( bAlpha ? "opacity:" + ( iAlpha / 255 ) + ";" : "" )
|
||||
+ "'>" + strThisChar + "</span>";
|
||||
|
||||
} else {
|
||||
|
||||
strChars += strThisChar;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
strChars += "<br/>";
|
||||
|
||||
}
|
||||
|
||||
oAscii.innerHTML = "<tr><td>" + strChars + "</td></tr>";
|
||||
|
||||
// console.timeEnd('rendering');
|
||||
|
||||
// return oAscii;
|
||||
|
||||
}
|
||||
|
||||
// end modified asciifyImage block
|
||||
|
||||
};
|
||||
569
node_modules/three/examples/js/effects/OutlineEffect.js
generated
vendored
Normal file
569
node_modules/three/examples/js/effects/OutlineEffect.js
generated
vendored
Normal file
@@ -0,0 +1,569 @@
|
||||
/**
|
||||
* @author takahirox / http://github.com/takahirox/
|
||||
*
|
||||
* Reference: https://en.wikipedia.org/wiki/Cel_shading
|
||||
*
|
||||
* // How to set default outline parameters
|
||||
* new THREE.OutlineEffect( renderer, {
|
||||
* defaultThickNess: 0.01,
|
||||
* defaultColor: new THREE.Color( 0x888888 ),
|
||||
* defaultAlpha: 0.8,
|
||||
* defaultKeepAlive: true // keeps outline material in cache even if material is removed from scene
|
||||
* } );
|
||||
*
|
||||
* // How to set outline parameters for each material
|
||||
* material.outlineParameters = {
|
||||
* thickNess: 0.01, // this paremeter won't work for MultiMaterial
|
||||
* color: new THREE.Color( 0x888888 ), // this paremeter won't work for MultiMaterial
|
||||
* alpha: 0.8, // this paremeter won't work for MultiMaterial
|
||||
* visible: true,
|
||||
* keepAlive: true // this paremeter won't work for Material in materials of MultiMaterial
|
||||
* };
|
||||
*
|
||||
* TODO
|
||||
* - support shader material without objectNormal in its vertexShader
|
||||
*/
|
||||
|
||||
THREE.OutlineEffect = function ( renderer, parameters ) {
|
||||
|
||||
parameters = parameters || {};
|
||||
|
||||
this.enabled = true;
|
||||
|
||||
var defaultThickness = parameters.defaultThickness !== undefined ? parameters.defaultThickness : 0.003;
|
||||
var defaultColor = parameters.defaultColor !== undefined ? parameters.defaultColor : new THREE.Color( 0x000000 );
|
||||
var defaultAlpha = parameters.defaultAlpha !== undefined ? parameters.defaultAlpha : 1.0;
|
||||
var defaultKeepAlive = parameters.defaultKeepAlive !== undefined ? parameters.defaultKeepAlive : false;
|
||||
|
||||
// object.material.uuid -> outlineMaterial
|
||||
// (no mapping from children of MultiMaterial)
|
||||
// save at the outline material creation and release
|
||||
// if it's unused removeThresholdCount frames
|
||||
// unless keepAlive is true.
|
||||
var cache = {};
|
||||
|
||||
var removeThresholdCount = 60;
|
||||
|
||||
// outlineMaterial.uuid (or object.uuid for invisibleMaterial) -> originalMaterial
|
||||
// including children of MultiMaterial.
|
||||
// save before render and release after render.
|
||||
var originalMaterials = {};
|
||||
|
||||
// object.uuid -> originalOnBeforeRender
|
||||
// save before render and release after render.
|
||||
var originalOnBeforeRenders = {};
|
||||
|
||||
//this.cache = cache; // for debug
|
||||
|
||||
var invisibleMaterial = new THREE.ShaderMaterial( { visible: false } );
|
||||
|
||||
// copied from WebGLPrograms and removed some materials
|
||||
var shaderIDs = {
|
||||
MeshBasicMaterial: 'basic',
|
||||
MeshLambertMaterial: 'lambert',
|
||||
MeshPhongMaterial: 'phong',
|
||||
MeshToonMaterial: 'phong',
|
||||
MeshStandardMaterial: 'physical',
|
||||
MeshPhysicalMaterial: 'physical'
|
||||
};
|
||||
|
||||
var uniformsChunk = {
|
||||
outlineThickness: { type: "f", value: defaultThickness },
|
||||
outlineColor: { type: "c", value: defaultColor },
|
||||
outlineAlpha: { type: "f", value: defaultAlpha }
|
||||
};
|
||||
|
||||
var vertexShaderChunk = [
|
||||
|
||||
"#include <fog_pars_vertex>",
|
||||
|
||||
"uniform float outlineThickness;",
|
||||
|
||||
"vec4 calculateOutline( vec4 pos, vec3 objectNormal, vec4 skinned ) {",
|
||||
|
||||
" float thickness = outlineThickness;",
|
||||
" const float ratio = 1.0;", // TODO: support outline thickness ratio for each vertex
|
||||
" vec4 pos2 = projectionMatrix * modelViewMatrix * vec4( skinned.xyz + objectNormal, 1.0 );",
|
||||
// NOTE: subtract pos2 from pos because BackSide objectNormal is negative
|
||||
" vec4 norm = normalize( pos - pos2 );",
|
||||
" return pos + norm * thickness * pos.w * ratio;",
|
||||
|
||||
"}"
|
||||
|
||||
].join( "\n" );
|
||||
|
||||
var vertexShaderChunk2 = [
|
||||
|
||||
"#if ! defined( LAMBERT ) && ! defined( PHONG ) && ! defined( TOON ) && ! defined( PHYSICAL )",
|
||||
|
||||
" #ifndef USE_ENVMAP",
|
||||
" vec3 objectNormal = normalize( normal );",
|
||||
|
||||
" #ifdef FLIP_SIDED",
|
||||
" objectNormal = -objectNormal;",
|
||||
" #endif",
|
||||
|
||||
" #endif",
|
||||
|
||||
"#endif",
|
||||
|
||||
"#ifdef DECLARE_TRANSFORMED",
|
||||
" vec3 transformed = vec3( position );",
|
||||
"#endif",
|
||||
|
||||
"#ifdef USE_SKINNING",
|
||||
" gl_Position = calculateOutline( gl_Position, objectNormal, skinned );",
|
||||
"#else",
|
||||
" gl_Position = calculateOutline( gl_Position, objectNormal, vec4( transformed, 1.0 ) );",
|
||||
"#endif",
|
||||
|
||||
"#include <fog_vertex>"
|
||||
|
||||
].join( "\n" );
|
||||
|
||||
var fragmentShader = [
|
||||
|
||||
"#include <common>",
|
||||
"#include <fog_pars_fragment>",
|
||||
|
||||
"uniform vec3 outlineColor;",
|
||||
"uniform float outlineAlpha;",
|
||||
|
||||
"void main() {",
|
||||
|
||||
" gl_FragColor = vec4( outlineColor, outlineAlpha );",
|
||||
|
||||
" #include <fog_fragment>",
|
||||
|
||||
"}"
|
||||
|
||||
].join( "\n" );
|
||||
|
||||
function createMaterial( originalMaterial ) {
|
||||
|
||||
var shaderID = shaderIDs[ originalMaterial.type ];
|
||||
var originalUniforms, originalVertexShader;
|
||||
var outlineParameters = originalMaterial.outlineParameters;
|
||||
|
||||
if ( shaderID !== undefined ) {
|
||||
|
||||
var shader = THREE.ShaderLib[ shaderID ];
|
||||
originalUniforms = shader.uniforms;
|
||||
originalVertexShader = shader.vertexShader;
|
||||
|
||||
} else if ( originalMaterial.isRawShaderMaterial === true ) {
|
||||
|
||||
originalUniforms = originalMaterial.uniforms;
|
||||
originalVertexShader = originalMaterial.vertexShader;
|
||||
|
||||
if ( ! /attribute\s+vec3\s+position\s*;/.test( originalVertexShader ) ||
|
||||
! /attribute\s+vec3\s+normal\s*;/.test( originalVertexShader ) ) {
|
||||
|
||||
console.warn( 'THREE.OutlineEffect requires both vec3 position and normal attributes in vertex shader, ' +
|
||||
'does not draw outline for ' + originalMaterial.name + '(uuid:' + originalMaterial.uuid + ') material.' );
|
||||
|
||||
return invisibleMaterial;
|
||||
|
||||
}
|
||||
|
||||
} else if ( originalMaterial.isShaderMaterial === true ) {
|
||||
|
||||
originalUniforms = originalMaterial.uniforms;
|
||||
originalVertexShader = originalMaterial.vertexShader;
|
||||
|
||||
} else {
|
||||
|
||||
return invisibleMaterial;
|
||||
|
||||
}
|
||||
|
||||
var uniforms = Object.assign( {}, originalUniforms, uniformsChunk );
|
||||
|
||||
var vertexShader = originalVertexShader
|
||||
// put vertexShaderChunk right before "void main() {...}"
|
||||
.replace( /void\s+main\s*\(\s*\)/, vertexShaderChunk + '\nvoid main()' )
|
||||
// put vertexShaderChunk2 the end of "void main() {...}"
|
||||
// Note: here assums originalVertexShader ends with "}" of "void main() {...}"
|
||||
.replace( /\}\s*$/, vertexShaderChunk2 + '\n}' )
|
||||
// remove any light related lines
|
||||
// Note: here is very sensitive to originalVertexShader
|
||||
// TODO: consider safer way
|
||||
.replace( /#include\s+<[\w_]*light[\w_]*>/g, '' );
|
||||
|
||||
var defines = {};
|
||||
|
||||
if ( ! /vec3\s+transformed\s*=/.test( originalVertexShader ) &&
|
||||
! /#include\s+<begin_vertex>/.test( originalVertexShader ) ) defines.DECLARE_TRANSFORMED = true;
|
||||
|
||||
var material = new THREE.ShaderMaterial( {
|
||||
defines: defines,
|
||||
uniforms: uniforms,
|
||||
vertexShader: vertexShader,
|
||||
fragmentShader: fragmentShader,
|
||||
side: THREE.BackSide,
|
||||
//wireframe: true,
|
||||
skinning: false,
|
||||
morphTargets: false,
|
||||
morphNormals: false,
|
||||
fog: false
|
||||
} );
|
||||
|
||||
return material;
|
||||
|
||||
}
|
||||
|
||||
function createMultiMaterial( originalMaterial ) {
|
||||
|
||||
var materials = [];
|
||||
|
||||
for ( var i = 0, il = originalMaterial.materials.length; i < il; i ++ ) {
|
||||
|
||||
materials.push( createMaterial( originalMaterial.materials[ i ] ) );
|
||||
|
||||
}
|
||||
|
||||
return new THREE.MultiMaterial( materials );
|
||||
|
||||
}
|
||||
|
||||
function setOutlineMaterial( object ) {
|
||||
|
||||
if ( object.material === undefined ) return;
|
||||
|
||||
var data = cache[ object.material.uuid ];
|
||||
|
||||
if ( data === undefined ) {
|
||||
|
||||
data = {
|
||||
material: object.material.isMultiMaterial === true ? createMultiMaterial( object.material ) : createMaterial( object.material ),
|
||||
used: true,
|
||||
keepAlive: defaultKeepAlive,
|
||||
count: 0
|
||||
};
|
||||
|
||||
cache[ object.material.uuid ] = data;
|
||||
|
||||
}
|
||||
|
||||
var outlineMaterial = data.material;
|
||||
data.used = true;
|
||||
|
||||
var uuid = outlineMaterial !== invisibleMaterial ? outlineMaterial.uuid : object.uuid;
|
||||
originalMaterials[ uuid ] = object.material;
|
||||
|
||||
if ( object.material.isMultiMaterial === true ) {
|
||||
|
||||
for ( var i = 0, il = object.material.materials.length; i < il; i ++ ) {
|
||||
|
||||
// originalMaterial of leaf material of MultiMaterial is used only for
|
||||
// updating outlineMaterial. so need not to save for invisibleMaterial.
|
||||
if ( outlineMaterial.materials[ i ] !== invisibleMaterial ) {
|
||||
|
||||
originalMaterials[ outlineMaterial.materials[ i ].uuid ] = object.material.materials[ i ];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
updateOutlineMultiMaterial( outlineMaterial, object.material );
|
||||
|
||||
} else {
|
||||
|
||||
updateOutlineMaterial( outlineMaterial, object.material );
|
||||
|
||||
}
|
||||
|
||||
object.material = outlineMaterial;
|
||||
|
||||
originalOnBeforeRenders[ object.uuid ] = object.onBeforeRender;
|
||||
object.onBeforeRender = onBeforeRender;
|
||||
|
||||
}
|
||||
|
||||
function restoreOriginalMaterial( object ) {
|
||||
|
||||
if ( object.material === undefined ) return;
|
||||
|
||||
var originalMaterial = originalMaterials[ object.material.uuid ];
|
||||
|
||||
if ( originalMaterial === undefined ) {
|
||||
|
||||
originalMaterial = originalMaterials[ object.uuid ];
|
||||
|
||||
if ( originalMaterial === undefined ) return;
|
||||
|
||||
}
|
||||
|
||||
object.material = originalMaterial;
|
||||
object.onBeforeRender = originalOnBeforeRenders[ object.uuid ];
|
||||
|
||||
}
|
||||
|
||||
function onBeforeRender( renderer, scene, camera, geometry, material, group ) {
|
||||
|
||||
// check some things before updating just in case
|
||||
|
||||
if ( material === invisibleMaterial ) return;
|
||||
|
||||
if ( material.isMultiMaterial === true ) return;
|
||||
|
||||
var originalMaterial = originalMaterials[ material.uuid ];
|
||||
|
||||
if ( originalMaterial === undefined ) return;
|
||||
|
||||
updateUniforms( material, originalMaterial );
|
||||
|
||||
}
|
||||
|
||||
function updateUniforms( material, originalMaterial ) {
|
||||
|
||||
var outlineParameters = originalMaterial.outlineParameters;
|
||||
|
||||
material.uniforms.outlineAlpha.value = originalMaterial.opacity;
|
||||
|
||||
if ( outlineParameters !== undefined ) {
|
||||
|
||||
if ( outlineParameters.thickness !== undefined ) material.uniforms.outlineThickness.value = outlineParameters.thickness;
|
||||
if ( outlineParameters.color !== undefined ) material.uniforms.outlineColor.value.copy( outlineParameters.color );
|
||||
if ( outlineParameters.alpha !== undefined ) material.uniforms.outlineAlpha.value = outlineParameters.alpha;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function updateOutlineMaterial( material, originalMaterial ) {
|
||||
|
||||
if ( material === invisibleMaterial ) return;
|
||||
|
||||
var outlineParameters = originalMaterial.outlineParameters;
|
||||
|
||||
material.skinning = originalMaterial.skinning;
|
||||
material.morphTargets = originalMaterial.morphTargets;
|
||||
material.morphNormals = originalMaterial.morphNormals;
|
||||
material.fog = originalMaterial.fog;
|
||||
|
||||
if ( outlineParameters !== undefined ) {
|
||||
|
||||
if ( originalMaterial.visible === false ) {
|
||||
|
||||
material.visible = false;
|
||||
|
||||
} else {
|
||||
|
||||
material.visible = ( outlineParameters.visible !== undefined ) ? outlineParameters.visible : true;
|
||||
|
||||
}
|
||||
|
||||
material.transparent = ( outlineParameters.alpha !== undefined && outlineParameters.alpha < 1.0 ) ? true : originalMaterial.transparent;
|
||||
|
||||
// cache[ originalMaterial.uuid ] is undefined if originalMaterial is in materials of MultiMaterial
|
||||
if ( outlineParameters.keepAlive !== undefined && cache[ originalMaterial.uuid ] !== undefined ) cache[ originalMaterial.uuid ].keepAlive = outlineParameters.keepAlive;
|
||||
|
||||
} else {
|
||||
|
||||
material.transparent = originalMaterial.transparent;
|
||||
material.visible = originalMaterial.visible;
|
||||
|
||||
}
|
||||
|
||||
if ( originalMaterial.wireframe === true || originalMaterial.depthTest === false ) material.visible = false;
|
||||
|
||||
}
|
||||
|
||||
function updateOutlineMultiMaterial( material, originalMaterial ) {
|
||||
|
||||
if ( material === invisibleMaterial ) return;
|
||||
|
||||
var outlineParameters = originalMaterial.outlineParameters;
|
||||
|
||||
if ( outlineParameters !== undefined ) {
|
||||
|
||||
if ( originalMaterial.visible === false ) {
|
||||
|
||||
material.visible = false;
|
||||
|
||||
} else {
|
||||
|
||||
material.visible = ( outlineParameters.visible !== undefined ) ? outlineParameters.visible : true;
|
||||
|
||||
}
|
||||
|
||||
if ( outlineParameters.keepAlive !== undefined ) cache[ originalMaterial.uuid ].keepAlive = outlineParameters.keepAlive;
|
||||
|
||||
} else {
|
||||
|
||||
material.visible = originalMaterial.visible;
|
||||
|
||||
}
|
||||
|
||||
for ( var i = 0, il = material.materials.length; i < il; i ++ ) {
|
||||
|
||||
updateOutlineMaterial( material.materials[ i ], originalMaterial.materials[ i ] );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function cleanupCache() {
|
||||
|
||||
var keys;
|
||||
|
||||
// clear originialMaterials
|
||||
keys = Object.keys( originalMaterials );
|
||||
|
||||
for ( var i = 0, il = keys.length; i < il; i ++ ) {
|
||||
|
||||
originalMaterials[ keys[ i ] ] = undefined;
|
||||
|
||||
}
|
||||
|
||||
// clear originalOnBeforeRenders
|
||||
keys = Object.keys( originalOnBeforeRenders );
|
||||
|
||||
for ( var i = 0, il = keys.length; i < il; i ++ ) {
|
||||
|
||||
originalOnBeforeRenders[ keys[ i ] ] = undefined;
|
||||
|
||||
}
|
||||
|
||||
// remove unused outlineMaterial from cache
|
||||
keys = Object.keys( cache );
|
||||
|
||||
for ( var i = 0, il = keys.length; i < il; i ++ ) {
|
||||
|
||||
var key = keys[ i ];
|
||||
|
||||
if ( cache[ key ].used === false ) {
|
||||
|
||||
cache[ key ].count++;
|
||||
|
||||
if ( cache[ key ].keepAlive === false && cache[ key ].count > removeThresholdCount ) {
|
||||
|
||||
delete cache[ key ];
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
cache[ key ].used = false;
|
||||
cache[ key ].count = 0;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.render = function ( scene, camera, renderTarget, forceClear ) {
|
||||
|
||||
if ( this.enabled === false ) {
|
||||
|
||||
renderer.render( scene, camera, renderTarget, forceClear );
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
var currentAutoClear = renderer.autoClear;
|
||||
renderer.autoClear = this.autoClear;
|
||||
|
||||
// 1. render normally
|
||||
renderer.render( scene, camera, renderTarget, forceClear );
|
||||
|
||||
// 2. render outline
|
||||
var currentSceneAutoUpdate = scene.autoUpdate;
|
||||
var currentSceneBackground = scene.background;
|
||||
var currentShadowMapEnabled = renderer.shadowMap.enabled;
|
||||
|
||||
scene.autoUpdate = false;
|
||||
scene.background = null;
|
||||
renderer.autoClear = false;
|
||||
renderer.shadowMap.enabled = false;
|
||||
|
||||
scene.traverse( setOutlineMaterial );
|
||||
|
||||
renderer.render( scene, camera, renderTarget );
|
||||
|
||||
scene.traverse( restoreOriginalMaterial );
|
||||
|
||||
cleanupCache();
|
||||
|
||||
scene.autoUpdate = currentSceneAutoUpdate;
|
||||
scene.background = currentSceneBackground;
|
||||
renderer.autoClear = currentAutoClear;
|
||||
renderer.shadowMap.enabled = currentShadowMapEnabled;
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
* See #9918
|
||||
*
|
||||
* The following property copies and wrapper methods enable
|
||||
* THREE.OutlineEffect to be called from other *Effect, like
|
||||
*
|
||||
* effect = new THREE.VREffect( new THREE.OutlineEffect( renderer ) );
|
||||
*
|
||||
* function render () {
|
||||
*
|
||||
* effect.render( scene, camera );
|
||||
*
|
||||
* }
|
||||
*/
|
||||
this.autoClear = renderer.autoClear;
|
||||
this.domElement = renderer.domElement;
|
||||
this.shadowMap = renderer.shadowMap;
|
||||
|
||||
this.clear = function ( color, depth, stencil ) {
|
||||
|
||||
renderer.clear( color, depth, stencil );
|
||||
|
||||
};
|
||||
|
||||
this.getPixelRatio = function () {
|
||||
|
||||
return renderer.getPixelRatio();
|
||||
|
||||
};
|
||||
|
||||
this.setPixelRatio = function ( value ) {
|
||||
|
||||
renderer.setPixelRatio( value );
|
||||
|
||||
};
|
||||
|
||||
this.getSize = function () {
|
||||
|
||||
return renderer.getSize();
|
||||
|
||||
};
|
||||
|
||||
this.setSize = function ( width, height, updateStyle ) {
|
||||
|
||||
renderer.setSize( width, height, updateStyle );
|
||||
|
||||
};
|
||||
|
||||
this.setViewport = function ( x, y, width, height ) {
|
||||
|
||||
renderer.setViewport( x, y, width, height );
|
||||
|
||||
};
|
||||
|
||||
this.setScissor = function ( x, y, width, height ) {
|
||||
|
||||
renderer.setScissor( x, y, width, height );
|
||||
|
||||
};
|
||||
|
||||
this.setScissorTest = function ( boolean ) {
|
||||
|
||||
renderer.setScissorTest( boolean );
|
||||
|
||||
};
|
||||
|
||||
this.setRenderTarget = function ( renderTarget ) {
|
||||
|
||||
renderer.setRenderTarget( renderTarget );
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
96
node_modules/three/examples/js/effects/ParallaxBarrierEffect.js
generated
vendored
Normal file
96
node_modules/three/examples/js/effects/ParallaxBarrierEffect.js
generated
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
/**
|
||||
* @author mrdoob / http://mrdoob.com/
|
||||
* @author marklundin / http://mark-lundin.com/
|
||||
* @author alteredq / http://alteredqualia.com/
|
||||
*/
|
||||
|
||||
THREE.ParallaxBarrierEffect = function ( renderer ) {
|
||||
|
||||
var _camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
|
||||
|
||||
var _scene = new THREE.Scene();
|
||||
|
||||
var _stereo = new THREE.StereoCamera();
|
||||
|
||||
var _params = { minFilter: THREE.LinearFilter, magFilter: THREE.NearestFilter, format: THREE.RGBAFormat };
|
||||
|
||||
var _renderTargetL = new THREE.WebGLRenderTarget( 512, 512, _params );
|
||||
var _renderTargetR = new THREE.WebGLRenderTarget( 512, 512, _params );
|
||||
|
||||
var _material = new THREE.ShaderMaterial( {
|
||||
|
||||
uniforms: {
|
||||
|
||||
"mapLeft": { value: _renderTargetL.texture },
|
||||
"mapRight": { value: _renderTargetR.texture }
|
||||
|
||||
},
|
||||
|
||||
vertexShader: [
|
||||
|
||||
"varying vec2 vUv;",
|
||||
|
||||
"void main() {",
|
||||
|
||||
" vUv = vec2( uv.x, uv.y );",
|
||||
" gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
|
||||
|
||||
"}"
|
||||
|
||||
].join( "\n" ),
|
||||
|
||||
fragmentShader: [
|
||||
|
||||
"uniform sampler2D mapLeft;",
|
||||
"uniform sampler2D mapRight;",
|
||||
"varying vec2 vUv;",
|
||||
|
||||
"void main() {",
|
||||
|
||||
" vec2 uv = vUv;",
|
||||
|
||||
" if ( ( mod( gl_FragCoord.y, 2.0 ) ) > 1.00 ) {",
|
||||
|
||||
" gl_FragColor = texture2D( mapLeft, uv );",
|
||||
|
||||
" } else {",
|
||||
|
||||
" gl_FragColor = texture2D( mapRight, uv );",
|
||||
|
||||
" }",
|
||||
|
||||
"}"
|
||||
|
||||
].join( "\n" )
|
||||
|
||||
} );
|
||||
|
||||
var mesh = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2, 2 ), _material );
|
||||
_scene.add( mesh );
|
||||
|
||||
this.setSize = function ( width, height ) {
|
||||
|
||||
renderer.setSize( width, height );
|
||||
|
||||
var pixelRatio = renderer.getPixelRatio();
|
||||
|
||||
_renderTargetL.setSize( width * pixelRatio, height * pixelRatio );
|
||||
_renderTargetR.setSize( width * pixelRatio, height * pixelRatio );
|
||||
|
||||
};
|
||||
|
||||
this.render = function ( scene, camera ) {
|
||||
|
||||
scene.updateMatrixWorld();
|
||||
|
||||
if ( camera.parent === null ) camera.updateMatrixWorld();
|
||||
|
||||
_stereo.update( camera );
|
||||
|
||||
renderer.render( scene, _stereo.cameraL, _renderTargetL, true );
|
||||
renderer.render( scene, _stereo.cameraR, _renderTargetR, true );
|
||||
renderer.render( _scene, _camera );
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
143
node_modules/three/examples/js/effects/PeppersGhostEffect.js
generated
vendored
Normal file
143
node_modules/three/examples/js/effects/PeppersGhostEffect.js
generated
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
/**
|
||||
* Created by tpowellmeto on 29/10/2015.
|
||||
*
|
||||
* peppers ghost effect based on http://www.instructables.com/id/Reflective-Prism/?ALLSTEPS
|
||||
*/
|
||||
|
||||
THREE.PeppersGhostEffect = function ( renderer ) {
|
||||
|
||||
var scope = this;
|
||||
|
||||
scope.cameraDistance = 15;
|
||||
scope.reflectFromAbove = false;
|
||||
|
||||
// Internals
|
||||
var _halfWidth, _width, _height;
|
||||
|
||||
var _cameraF = new THREE.PerspectiveCamera(); //front
|
||||
var _cameraB = new THREE.PerspectiveCamera(); //back
|
||||
var _cameraL = new THREE.PerspectiveCamera(); //left
|
||||
var _cameraR = new THREE.PerspectiveCamera(); //right
|
||||
|
||||
var _position = new THREE.Vector3();
|
||||
var _quaternion = new THREE.Quaternion();
|
||||
var _scale = new THREE.Vector3();
|
||||
|
||||
// Initialization
|
||||
renderer.autoClear = false;
|
||||
|
||||
this.setSize = function ( width, height ) {
|
||||
|
||||
_halfWidth = width / 2;
|
||||
if ( width < height ) {
|
||||
|
||||
_width = width / 3;
|
||||
_height = width / 3;
|
||||
|
||||
} else {
|
||||
|
||||
_width = height / 3;
|
||||
_height = height / 3;
|
||||
|
||||
}
|
||||
renderer.setSize( width, height );
|
||||
|
||||
};
|
||||
|
||||
this.render = function ( scene, camera ) {
|
||||
|
||||
scene.updateMatrixWorld();
|
||||
|
||||
if ( camera.parent === null ) camera.updateMatrixWorld();
|
||||
|
||||
camera.matrixWorld.decompose( _position, _quaternion, _scale );
|
||||
|
||||
// front
|
||||
_cameraF.position.copy( _position );
|
||||
_cameraF.quaternion.copy( _quaternion );
|
||||
_cameraF.translateZ( scope.cameraDistance );
|
||||
_cameraF.lookAt( scene.position );
|
||||
|
||||
// back
|
||||
_cameraB.position.copy( _position );
|
||||
_cameraB.quaternion.copy( _quaternion );
|
||||
_cameraB.translateZ( - ( scope.cameraDistance ) );
|
||||
_cameraB.lookAt( scene.position );
|
||||
_cameraB.rotation.z += 180 * ( Math.PI / 180 );
|
||||
|
||||
// left
|
||||
_cameraL.position.copy( _position );
|
||||
_cameraL.quaternion.copy( _quaternion );
|
||||
_cameraL.translateX( - ( scope.cameraDistance ) );
|
||||
_cameraL.lookAt( scene.position );
|
||||
_cameraL.rotation.x += 90 * ( Math.PI / 180 );
|
||||
|
||||
// right
|
||||
_cameraR.position.copy( _position );
|
||||
_cameraR.quaternion.copy( _quaternion );
|
||||
_cameraR.translateX( scope.cameraDistance );
|
||||
_cameraR.lookAt( scene.position );
|
||||
_cameraR.rotation.x += 90 * ( Math.PI / 180 );
|
||||
|
||||
|
||||
renderer.clear();
|
||||
renderer.setScissorTest( true );
|
||||
|
||||
renderer.setScissor( _halfWidth - ( _width / 2 ), ( _height * 2 ), _width, _height );
|
||||
renderer.setViewport( _halfWidth - ( _width / 2 ), ( _height * 2 ), _width, _height );
|
||||
|
||||
if ( scope.reflectFromAbove ) {
|
||||
|
||||
renderer.render( scene, _cameraB );
|
||||
|
||||
} else {
|
||||
|
||||
renderer.render( scene, _cameraF );
|
||||
|
||||
}
|
||||
|
||||
renderer.setScissor( _halfWidth - ( _width / 2 ), 0, _width, _height );
|
||||
renderer.setViewport( _halfWidth - ( _width / 2 ), 0, _width, _height );
|
||||
|
||||
if ( scope.reflectFromAbove ) {
|
||||
|
||||
renderer.render( scene, _cameraF );
|
||||
|
||||
} else {
|
||||
|
||||
renderer.render( scene, _cameraB );
|
||||
|
||||
}
|
||||
|
||||
renderer.setScissor( _halfWidth - ( _width / 2 ) - _width, _height, _width, _height );
|
||||
renderer.setViewport( _halfWidth - ( _width / 2 ) - _width, _height, _width, _height );
|
||||
|
||||
if ( scope.reflectFromAbove ) {
|
||||
|
||||
renderer.render( scene, _cameraR );
|
||||
|
||||
} else {
|
||||
|
||||
renderer.render( scene, _cameraL );
|
||||
|
||||
}
|
||||
|
||||
renderer.setScissor( _halfWidth + ( _width / 2 ), _height, _width, _height );
|
||||
renderer.setViewport( _halfWidth + ( _width / 2 ), _height, _width, _height );
|
||||
|
||||
if ( scope.reflectFromAbove ) {
|
||||
|
||||
renderer.render( scene, _cameraL );
|
||||
|
||||
} else {
|
||||
|
||||
renderer.render( scene, _cameraR );
|
||||
|
||||
}
|
||||
|
||||
renderer.setScissorTest( false );
|
||||
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
50
node_modules/three/examples/js/effects/StereoEffect.js
generated
vendored
Normal file
50
node_modules/three/examples/js/effects/StereoEffect.js
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* @author alteredq / http://alteredqualia.com/
|
||||
* @authod mrdoob / http://mrdoob.com/
|
||||
* @authod arodic / http://aleksandarrodic.com/
|
||||
* @authod fonserbc / http://fonserbc.github.io/
|
||||
*/
|
||||
|
||||
THREE.StereoEffect = function ( renderer ) {
|
||||
|
||||
var _stereo = new THREE.StereoCamera();
|
||||
_stereo.aspect = 0.5;
|
||||
|
||||
this.setEyeSeparation = function ( eyeSep ) {
|
||||
|
||||
_stereo.eyeSep = eyeSep;
|
||||
|
||||
};
|
||||
|
||||
this.setSize = function ( width, height ) {
|
||||
|
||||
renderer.setSize( width, height );
|
||||
|
||||
};
|
||||
|
||||
this.render = function ( scene, camera ) {
|
||||
|
||||
scene.updateMatrixWorld();
|
||||
|
||||
if ( camera.parent === null ) camera.updateMatrixWorld();
|
||||
|
||||
_stereo.update( camera );
|
||||
|
||||
var size = renderer.getSize();
|
||||
|
||||
if ( renderer.autoClear ) renderer.clear();
|
||||
renderer.setScissorTest( true );
|
||||
|
||||
renderer.setScissor( 0, 0, size.width / 2, size.height );
|
||||
renderer.setViewport( 0, 0, size.width / 2, size.height );
|
||||
renderer.render( scene, _stereo.cameraL );
|
||||
|
||||
renderer.setScissor( size.width / 2, 0, size.width / 2, size.height );
|
||||
renderer.setViewport( size.width / 2, 0, size.width / 2, size.height );
|
||||
renderer.render( scene, _stereo.cameraR );
|
||||
|
||||
renderer.setScissorTest( false );
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
477
node_modules/three/examples/js/effects/VREffect.js
generated
vendored
Normal file
477
node_modules/three/examples/js/effects/VREffect.js
generated
vendored
Normal file
@@ -0,0 +1,477 @@
|
||||
/**
|
||||
* @author dmarcos / https://github.com/dmarcos
|
||||
* @author mrdoob / http://mrdoob.com
|
||||
*
|
||||
* WebVR Spec: http://mozvr.github.io/webvr-spec/webvr.html
|
||||
*
|
||||
* Firefox: http://mozvr.com/downloads/
|
||||
* Chromium: https://webvr.info/get-chrome
|
||||
*
|
||||
*/
|
||||
|
||||
THREE.VREffect = function( renderer, onError ) {
|
||||
|
||||
var vrDisplay, vrDisplays;
|
||||
var eyeTranslationL = new THREE.Vector3();
|
||||
var eyeTranslationR = new THREE.Vector3();
|
||||
var renderRectL, renderRectR;
|
||||
|
||||
var frameData = null;
|
||||
|
||||
if ( 'VRFrameData' in window ) {
|
||||
|
||||
frameData = new window.VRFrameData();
|
||||
|
||||
}
|
||||
|
||||
function gotVRDisplays( displays ) {
|
||||
|
||||
vrDisplays = displays;
|
||||
|
||||
if ( displays.length > 0 ) {
|
||||
|
||||
vrDisplay = displays[ 0 ];
|
||||
|
||||
} else {
|
||||
|
||||
if ( onError ) onError( 'HMD not available' );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( navigator.getVRDisplays ) {
|
||||
|
||||
navigator.getVRDisplays().then( gotVRDisplays ).catch( function() {
|
||||
|
||||
console.warn( 'THREE.VREffect: Unable to get VR Displays' );
|
||||
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
this.isPresenting = false;
|
||||
this.scale = 1;
|
||||
|
||||
var scope = this;
|
||||
|
||||
var rendererSize = renderer.getSize();
|
||||
var rendererUpdateStyle = false;
|
||||
var rendererPixelRatio = renderer.getPixelRatio();
|
||||
|
||||
this.getVRDisplay = function() {
|
||||
|
||||
return vrDisplay;
|
||||
|
||||
};
|
||||
|
||||
this.setVRDisplay = function( value ) {
|
||||
|
||||
vrDisplay = value;
|
||||
|
||||
};
|
||||
|
||||
this.getVRDisplays = function() {
|
||||
|
||||
console.warn( 'THREE.VREffect: getVRDisplays() is being deprecated.' );
|
||||
return vrDisplays;
|
||||
|
||||
};
|
||||
|
||||
this.setSize = function( width, height, updateStyle ) {
|
||||
|
||||
rendererSize = { width: width, height: height };
|
||||
rendererUpdateStyle = updateStyle;
|
||||
|
||||
if ( scope.isPresenting ) {
|
||||
|
||||
var eyeParamsL = vrDisplay.getEyeParameters( 'left' );
|
||||
renderer.setPixelRatio( 1 );
|
||||
renderer.setSize( eyeParamsL.renderWidth * 2, eyeParamsL.renderHeight, false );
|
||||
|
||||
} else {
|
||||
|
||||
renderer.setPixelRatio( rendererPixelRatio );
|
||||
renderer.setSize( width, height, updateStyle );
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// VR presentation
|
||||
|
||||
var canvas = renderer.domElement;
|
||||
var defaultLeftBounds = [ 0.0, 0.0, 0.5, 1.0 ];
|
||||
var defaultRightBounds = [ 0.5, 0.0, 0.5, 1.0 ];
|
||||
|
||||
function onVRDisplayPresentChange() {
|
||||
|
||||
var wasPresenting = scope.isPresenting;
|
||||
scope.isPresenting = vrDisplay !== undefined && vrDisplay.isPresenting;
|
||||
|
||||
if ( scope.isPresenting ) {
|
||||
|
||||
var eyeParamsL = vrDisplay.getEyeParameters( 'left' );
|
||||
var eyeWidth = eyeParamsL.renderWidth;
|
||||
var eyeHeight = eyeParamsL.renderHeight;
|
||||
|
||||
if ( ! wasPresenting ) {
|
||||
|
||||
rendererPixelRatio = renderer.getPixelRatio();
|
||||
rendererSize = renderer.getSize();
|
||||
|
||||
renderer.setPixelRatio( 1 );
|
||||
renderer.setSize( eyeWidth * 2, eyeHeight, false );
|
||||
|
||||
}
|
||||
|
||||
} else if ( wasPresenting ) {
|
||||
|
||||
renderer.setPixelRatio( rendererPixelRatio );
|
||||
renderer.setSize( rendererSize.width, rendererSize.height, rendererUpdateStyle );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
window.addEventListener( 'vrdisplaypresentchange', onVRDisplayPresentChange, false );
|
||||
|
||||
this.setFullScreen = function( boolean ) {
|
||||
|
||||
return new Promise( function( resolve, reject ) {
|
||||
|
||||
if ( vrDisplay === undefined ) {
|
||||
|
||||
reject( new Error( 'No VR hardware found.' ) );
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if ( scope.isPresenting === boolean ) {
|
||||
|
||||
resolve();
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if ( boolean ) {
|
||||
|
||||
resolve( vrDisplay.requestPresent( [ { source: canvas } ] ) );
|
||||
|
||||
} else {
|
||||
|
||||
resolve( vrDisplay.exitPresent() );
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
};
|
||||
|
||||
this.requestPresent = function() {
|
||||
|
||||
return this.setFullScreen( true );
|
||||
|
||||
};
|
||||
|
||||
this.exitPresent = function() {
|
||||
|
||||
return this.setFullScreen( false );
|
||||
|
||||
};
|
||||
|
||||
this.requestAnimationFrame = function( f ) {
|
||||
|
||||
if ( vrDisplay !== undefined ) {
|
||||
|
||||
return vrDisplay.requestAnimationFrame( f );
|
||||
|
||||
} else {
|
||||
|
||||
return window.requestAnimationFrame( f );
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
this.cancelAnimationFrame = function( h ) {
|
||||
|
||||
if ( vrDisplay !== undefined ) {
|
||||
|
||||
vrDisplay.cancelAnimationFrame( h );
|
||||
|
||||
} else {
|
||||
|
||||
window.cancelAnimationFrame( h );
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
this.submitFrame = function() {
|
||||
|
||||
if ( vrDisplay !== undefined && scope.isPresenting ) {
|
||||
|
||||
vrDisplay.submitFrame();
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
this.autoSubmitFrame = true;
|
||||
|
||||
// render
|
||||
|
||||
var cameraL = new THREE.PerspectiveCamera();
|
||||
cameraL.layers.enable( 1 );
|
||||
|
||||
var cameraR = new THREE.PerspectiveCamera();
|
||||
cameraR.layers.enable( 2 );
|
||||
|
||||
this.render = function( scene, camera, renderTarget, forceClear ) {
|
||||
|
||||
if ( vrDisplay && scope.isPresenting ) {
|
||||
|
||||
var autoUpdate = scene.autoUpdate;
|
||||
|
||||
if ( autoUpdate ) {
|
||||
|
||||
scene.updateMatrixWorld();
|
||||
scene.autoUpdate = false;
|
||||
|
||||
}
|
||||
|
||||
var eyeParamsL = vrDisplay.getEyeParameters( 'left' );
|
||||
var eyeParamsR = vrDisplay.getEyeParameters( 'right' );
|
||||
|
||||
eyeTranslationL.fromArray( eyeParamsL.offset );
|
||||
eyeTranslationR.fromArray( eyeParamsR.offset );
|
||||
|
||||
if ( Array.isArray( scene ) ) {
|
||||
|
||||
console.warn( 'THREE.VREffect.render() no longer supports arrays. Use object.layers instead.' );
|
||||
scene = scene[ 0 ];
|
||||
|
||||
}
|
||||
|
||||
// When rendering we don't care what the recommended size is, only what the actual size
|
||||
// of the backbuffer is.
|
||||
var size = renderer.getSize();
|
||||
var layers = vrDisplay.getLayers();
|
||||
var leftBounds;
|
||||
var rightBounds;
|
||||
|
||||
if ( layers.length ) {
|
||||
|
||||
var layer = layers[ 0 ];
|
||||
|
||||
leftBounds = layer.leftBounds !== null && layer.leftBounds.length === 4 ? layer.leftBounds : defaultLeftBounds;
|
||||
rightBounds = layer.rightBounds !== null && layer.rightBounds.length === 4 ? layer.rightBounds : defaultRightBounds;
|
||||
|
||||
} else {
|
||||
|
||||
leftBounds = defaultLeftBounds;
|
||||
rightBounds = defaultRightBounds;
|
||||
|
||||
}
|
||||
|
||||
renderRectL = {
|
||||
x: Math.round( size.width * leftBounds[ 0 ] ),
|
||||
y: Math.round( size.height * leftBounds[ 1 ] ),
|
||||
width: Math.round( size.width * leftBounds[ 2 ] ),
|
||||
height: Math.round( size.height * leftBounds[ 3 ] )
|
||||
};
|
||||
renderRectR = {
|
||||
x: Math.round( size.width * rightBounds[ 0 ] ),
|
||||
y: Math.round( size.height * rightBounds[ 1 ] ),
|
||||
width: Math.round( size.width * rightBounds[ 2 ] ),
|
||||
height: Math.round( size.height * rightBounds[ 3 ] )
|
||||
};
|
||||
|
||||
if ( renderTarget ) {
|
||||
|
||||
renderer.setRenderTarget( renderTarget );
|
||||
renderTarget.scissorTest = true;
|
||||
|
||||
} else {
|
||||
|
||||
renderer.setRenderTarget( null );
|
||||
renderer.setScissorTest( true );
|
||||
|
||||
}
|
||||
|
||||
if ( renderer.autoClear || forceClear ) renderer.clear();
|
||||
|
||||
if ( camera.parent === null ) camera.updateMatrixWorld();
|
||||
|
||||
camera.matrixWorld.decompose( cameraL.position, cameraL.quaternion, cameraL.scale );
|
||||
camera.matrixWorld.decompose( cameraR.position, cameraR.quaternion, cameraR.scale );
|
||||
|
||||
var scale = this.scale;
|
||||
cameraL.translateOnAxis( eyeTranslationL, scale );
|
||||
cameraR.translateOnAxis( eyeTranslationR, scale );
|
||||
|
||||
if ( vrDisplay.getFrameData ) {
|
||||
|
||||
vrDisplay.depthNear = camera.near;
|
||||
vrDisplay.depthFar = camera.far;
|
||||
|
||||
vrDisplay.getFrameData( frameData );
|
||||
|
||||
cameraL.projectionMatrix.elements = frameData.leftProjectionMatrix;
|
||||
cameraR.projectionMatrix.elements = frameData.rightProjectionMatrix;
|
||||
|
||||
} else {
|
||||
|
||||
cameraL.projectionMatrix = fovToProjection( eyeParamsL.fieldOfView, true, camera.near, camera.far );
|
||||
cameraR.projectionMatrix = fovToProjection( eyeParamsR.fieldOfView, true, camera.near, camera.far );
|
||||
|
||||
}
|
||||
|
||||
// render left eye
|
||||
if ( renderTarget ) {
|
||||
|
||||
renderTarget.viewport.set( renderRectL.x, renderRectL.y, renderRectL.width, renderRectL.height );
|
||||
renderTarget.scissor.set( renderRectL.x, renderRectL.y, renderRectL.width, renderRectL.height );
|
||||
|
||||
} else {
|
||||
|
||||
renderer.setViewport( renderRectL.x, renderRectL.y, renderRectL.width, renderRectL.height );
|
||||
renderer.setScissor( renderRectL.x, renderRectL.y, renderRectL.width, renderRectL.height );
|
||||
|
||||
}
|
||||
renderer.render( scene, cameraL, renderTarget, forceClear );
|
||||
|
||||
// render right eye
|
||||
if ( renderTarget ) {
|
||||
|
||||
renderTarget.viewport.set( renderRectR.x, renderRectR.y, renderRectR.width, renderRectR.height );
|
||||
renderTarget.scissor.set( renderRectR.x, renderRectR.y, renderRectR.width, renderRectR.height );
|
||||
|
||||
} else {
|
||||
|
||||
renderer.setViewport( renderRectR.x, renderRectR.y, renderRectR.width, renderRectR.height );
|
||||
renderer.setScissor( renderRectR.x, renderRectR.y, renderRectR.width, renderRectR.height );
|
||||
|
||||
}
|
||||
renderer.render( scene, cameraR, renderTarget, forceClear );
|
||||
|
||||
if ( renderTarget ) {
|
||||
|
||||
renderTarget.viewport.set( 0, 0, size.width, size.height );
|
||||
renderTarget.scissor.set( 0, 0, size.width, size.height );
|
||||
renderTarget.scissorTest = false;
|
||||
renderer.setRenderTarget( null );
|
||||
|
||||
} else {
|
||||
|
||||
renderer.setViewport( 0, 0, size.width, size.height );
|
||||
renderer.setScissorTest( false );
|
||||
|
||||
}
|
||||
|
||||
if ( autoUpdate ) {
|
||||
|
||||
scene.autoUpdate = true;
|
||||
|
||||
}
|
||||
|
||||
if ( scope.autoSubmitFrame ) {
|
||||
|
||||
scope.submitFrame();
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
// Regular render mode if not HMD
|
||||
|
||||
renderer.render( scene, camera, renderTarget, forceClear );
|
||||
|
||||
};
|
||||
|
||||
this.dispose = function() {
|
||||
|
||||
window.removeEventListener( 'vrdisplaypresentchange', onVRDisplayPresentChange, false );
|
||||
|
||||
};
|
||||
|
||||
//
|
||||
|
||||
function fovToNDCScaleOffset( fov ) {
|
||||
|
||||
var pxscale = 2.0 / ( fov.leftTan + fov.rightTan );
|
||||
var pxoffset = ( fov.leftTan - fov.rightTan ) * pxscale * 0.5;
|
||||
var pyscale = 2.0 / ( fov.upTan + fov.downTan );
|
||||
var pyoffset = ( fov.upTan - fov.downTan ) * pyscale * 0.5;
|
||||
return { scale: [ pxscale, pyscale ], offset: [ pxoffset, pyoffset ] };
|
||||
|
||||
}
|
||||
|
||||
function fovPortToProjection( fov, rightHanded, zNear, zFar ) {
|
||||
|
||||
rightHanded = rightHanded === undefined ? true : rightHanded;
|
||||
zNear = zNear === undefined ? 0.01 : zNear;
|
||||
zFar = zFar === undefined ? 10000.0 : zFar;
|
||||
|
||||
var handednessScale = rightHanded ? - 1.0 : 1.0;
|
||||
|
||||
// start with an identity matrix
|
||||
var mobj = new THREE.Matrix4();
|
||||
var m = mobj.elements;
|
||||
|
||||
// and with scale/offset info for normalized device coords
|
||||
var scaleAndOffset = fovToNDCScaleOffset( fov );
|
||||
|
||||
// X result, map clip edges to [-w,+w]
|
||||
m[ 0 * 4 + 0 ] = scaleAndOffset.scale[ 0 ];
|
||||
m[ 0 * 4 + 1 ] = 0.0;
|
||||
m[ 0 * 4 + 2 ] = scaleAndOffset.offset[ 0 ] * handednessScale;
|
||||
m[ 0 * 4 + 3 ] = 0.0;
|
||||
|
||||
// Y result, map clip edges to [-w,+w]
|
||||
// Y offset is negated because this proj matrix transforms from world coords with Y=up,
|
||||
// but the NDC scaling has Y=down (thanks D3D?)
|
||||
m[ 1 * 4 + 0 ] = 0.0;
|
||||
m[ 1 * 4 + 1 ] = scaleAndOffset.scale[ 1 ];
|
||||
m[ 1 * 4 + 2 ] = - scaleAndOffset.offset[ 1 ] * handednessScale;
|
||||
m[ 1 * 4 + 3 ] = 0.0;
|
||||
|
||||
// Z result (up to the app)
|
||||
m[ 2 * 4 + 0 ] = 0.0;
|
||||
m[ 2 * 4 + 1 ] = 0.0;
|
||||
m[ 2 * 4 + 2 ] = zFar / ( zNear - zFar ) * - handednessScale;
|
||||
m[ 2 * 4 + 3 ] = ( zFar * zNear ) / ( zNear - zFar );
|
||||
|
||||
// W result (= Z in)
|
||||
m[ 3 * 4 + 0 ] = 0.0;
|
||||
m[ 3 * 4 + 1 ] = 0.0;
|
||||
m[ 3 * 4 + 2 ] = handednessScale;
|
||||
m[ 3 * 4 + 3 ] = 0.0;
|
||||
|
||||
mobj.transpose();
|
||||
|
||||
return mobj;
|
||||
|
||||
}
|
||||
|
||||
function fovToProjection( fov, rightHanded, zNear, zFar ) {
|
||||
|
||||
var DEG2RAD = Math.PI / 180.0;
|
||||
|
||||
var fovPort = {
|
||||
upTan: Math.tan( fov.upDegrees * DEG2RAD ),
|
||||
downTan: Math.tan( fov.downDegrees * DEG2RAD ),
|
||||
leftTan: Math.tan( fov.leftDegrees * DEG2RAD ),
|
||||
rightTan: Math.tan( fov.rightDegrees * DEG2RAD )
|
||||
};
|
||||
|
||||
return fovPortToProjection( fovPort, rightHanded, zNear, zFar );
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
Reference in New Issue
Block a user