提交 9fb22372 编写于 作者: M Michael Schlachter 提交者: GitHub

Merge branch 'dev' into blender-exporter-multimaterial

...@@ -5389,9 +5389,18 @@ ...@@ -5389,9 +5389,18 @@
map: { value: null }, map: { value: null },
offsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) }, offsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) },
specularMap: { value: null },
alphaMap: { value: null }, alphaMap: { value: null },
},
specularmap: {
specularMap: { value: null },
},
envmap: {
envMap: { value: null }, envMap: { value: null },
flipEnvMap: { value: - 1 }, flipEnvMap: { value: - 1 },
reflectivity: { value: 1.0 }, reflectivity: { value: 1.0 },
...@@ -5784,9 +5793,9 @@ ...@@ -5784,9 +5793,9 @@
var worldpos_vertex = "#if defined( USE_ENVMAP ) || defined( PHONG ) || defined( PHYSICAL ) || defined( LAMBERT ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP )\n\tvec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );\n#endif\n"; var worldpos_vertex = "#if defined( USE_ENVMAP ) || defined( PHONG ) || defined( PHYSICAL ) || defined( LAMBERT ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP )\n\tvec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );\n#endif\n";
var cube_frag = "uniform samplerCube tCube;\nuniform float tFlip;\nuniform float opacity;\nvarying vec3 vWorldPosition;\n#include <common>\nvoid main() {\n\tgl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );\n\tgl_FragColor.a *= opacity;\n}\n"; var cube_frag = "uniform samplerCube tCube;\nuniform float tFlip;\nuniform float opacity;\nvarying vec3 vWorldPosition;\nvoid main() {\n\tgl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );\n\tgl_FragColor.a *= opacity;\n}\n";
var cube_vert = "varying vec3 vWorldPosition;\n#include <common>\nvoid main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n}\n"; var cube_vert = "varying vec3 vWorldPosition;\n#include <common>\nvoid main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\tgl_Position = projectionMatrix * vec4( normalMatrix * position, 1.0 );\n}\n";
var depth_frag = "#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include <common>\n#include <packing>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <logdepthbuf_fragment>\n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( gl_FragCoord.z ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( gl_FragCoord.z );\n\t#endif\n}\n"; var depth_frag = "#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include <common>\n#include <packing>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <logdepthbuf_fragment>\n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( gl_FragCoord.z ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( gl_FragCoord.z );\n\t#endif\n}\n";
...@@ -5796,7 +5805,7 @@ ...@@ -5796,7 +5805,7 @@
var distanceRGBA_vert = "#define DISTANCE\nvarying vec3 vWorldPosition;\n#include <common>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <worldpos_vertex>\n\t#include <clipping_planes_vertex>\n\tvWorldPosition = worldPosition.xyz;\n}\n"; var distanceRGBA_vert = "#define DISTANCE\nvarying vec3 vWorldPosition;\n#include <common>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <worldpos_vertex>\n\t#include <clipping_planes_vertex>\n\tvWorldPosition = worldPosition.xyz;\n}\n";
var equirect_frag = "uniform sampler2D tEquirect;\nuniform float tFlip;\nvarying vec3 vWorldPosition;\n#include <common>\nvoid main() {\n\tvec3 direction = normalize( vWorldPosition );\n\tvec2 sampleUV;\n\tsampleUV.y = saturate( tFlip * direction.y * -0.5 + 0.5 );\n\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\n\tgl_FragColor = texture2D( tEquirect, sampleUV );\n}\n"; var equirect_frag = "uniform sampler2D tEquirect;\nvarying vec3 vWorldPosition;\n#include <common>\nvoid main() {\n\tvec3 direction = normalize( vWorldPosition );\n\tvec2 sampleUV;\n\tsampleUV.y = asin( clamp( direction.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\n\tgl_FragColor = texture2D( tEquirect, sampleUV );\n}\n";
var equirect_vert = "varying vec3 vWorldPosition;\n#include <common>\nvoid main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n}\n"; var equirect_vert = "varying vec3 vWorldPosition;\n#include <common>\nvoid main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n}\n";
...@@ -5957,6 +5966,8 @@ ...@@ -5957,6 +5966,8 @@
uniforms: UniformsUtils.merge( [ uniforms: UniformsUtils.merge( [
UniformsLib.common, UniformsLib.common,
UniformsLib.specularmap,
UniformsLib.envmap,
UniformsLib.aomap, UniformsLib.aomap,
UniformsLib.lightmap, UniformsLib.lightmap,
UniformsLib.fog UniformsLib.fog
...@@ -5971,6 +5982,8 @@ ...@@ -5971,6 +5982,8 @@
uniforms: UniformsUtils.merge( [ uniforms: UniformsUtils.merge( [
UniformsLib.common, UniformsLib.common,
UniformsLib.specularmap,
UniformsLib.envmap,
UniformsLib.aomap, UniformsLib.aomap,
UniformsLib.lightmap, UniformsLib.lightmap,
UniformsLib.emissivemap, UniformsLib.emissivemap,
...@@ -5990,6 +6003,8 @@ ...@@ -5990,6 +6003,8 @@
uniforms: UniformsUtils.merge( [ uniforms: UniformsUtils.merge( [
UniformsLib.common, UniformsLib.common,
UniformsLib.specularmap,
UniformsLib.envmap,
UniformsLib.aomap, UniformsLib.aomap,
UniformsLib.lightmap, UniformsLib.lightmap,
UniformsLib.emissivemap, UniformsLib.emissivemap,
...@@ -6015,6 +6030,7 @@ ...@@ -6015,6 +6030,7 @@
uniforms: UniformsUtils.merge( [ uniforms: UniformsUtils.merge( [
UniformsLib.common, UniformsLib.common,
UniformsLib.envmap,
UniformsLib.aomap, UniformsLib.aomap,
UniformsLib.lightmap, UniformsLib.lightmap,
UniformsLib.emissivemap, UniformsLib.emissivemap,
...@@ -6113,15 +6129,10 @@ ...@@ -6113,15 +6129,10 @@
}, },
/* -------------------------------------------------------------------------
// Cube map shader
------------------------------------------------------------------------- */
equirect: { equirect: {
uniforms: { uniforms: {
tEquirect: { value: null }, tEquirect: { value: null },
tFlip: { value: - 1 }
}, },
vertexShader: ShaderChunk.equirect_vert, vertexShader: ShaderChunk.equirect_vert,
...@@ -8356,15 +8367,7 @@ ...@@ -8356,15 +8367,7 @@
intersectsPlane: function ( plane ) { intersectsPlane: function ( plane ) {
// We use the following equation to compute the signed distance from return Math.abs( plane.distanceToPoint( this.center ) ) <= this.radius;
// the center of the sphere to the plane.
//
// distance = q * n - d
//
// If this distance is greater than the radius of the sphere,
// then there is no intersection.
return Math.abs( this.center.dot( plane.normal ) - plane.constant ) <= this.radius;
}, },
...@@ -8756,6 +8759,8 @@ ...@@ -8756,6 +8759,8 @@
function Plane( normal, constant ) { function Plane( normal, constant ) {
// normal is assumed to be normalized
this.normal = ( normal !== undefined ) ? normal : new Vector3( 1, 0, 0 ); this.normal = ( normal !== undefined ) ? normal : new Vector3( 1, 0, 0 );
this.constant = ( constant !== undefined ) ? constant : 0; this.constant = ( constant !== undefined ) ? constant : 0;
...@@ -16301,7 +16306,7 @@ ...@@ -16301,7 +16306,7 @@
var clearAlpha = 0; var clearAlpha = 0;
var planeCamera, planeMesh; var planeCamera, planeMesh;
var boxCamera, boxMesh; var boxMesh;
function render( scene, camera, forceClear ) { function render( scene, camera, forceClear ) {
...@@ -16326,9 +16331,7 @@ ...@@ -16326,9 +16331,7 @@
if ( background && background.isCubeTexture ) { if ( background && background.isCubeTexture ) {
if ( boxCamera === undefined ) { if ( boxMesh === undefined ) {
boxCamera = new PerspectiveCamera();
boxMesh = new Mesh( boxMesh = new Mesh(
new BoxBufferGeometry( 5, 5, 5 ), new BoxBufferGeometry( 5, 5, 5 ),
...@@ -16345,17 +16348,13 @@ ...@@ -16345,17 +16348,13 @@
} }
boxCamera.projectionMatrix.copy( camera.projectionMatrix );
boxCamera.matrixWorld.extractRotation( camera.matrixWorld );
boxCamera.matrixWorldInverse.getInverse( boxCamera.matrixWorld );
boxMesh.material.uniforms[ "tCube" ].value = background; boxMesh.material.uniforms[ "tCube" ].value = background;
boxMesh.modelViewMatrix.multiplyMatrices( boxCamera.matrixWorldInverse, boxMesh.matrixWorld ); boxMesh.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, boxMesh.matrixWorld );
boxMesh.normalMatrix.getNormalMatrix( boxMesh.modelViewMatrix );
geometries.update( boxMesh.geometry ); geometries.update( boxMesh.geometry );
renderer.renderBufferDirect( boxCamera, null, boxMesh.geometry, boxMesh.material, boxMesh, null ); renderer.renderBufferDirect( camera, null, boxMesh.geometry, boxMesh.material, boxMesh, null );
} else if ( background && background.isTexture ) { } else if ( background && background.isTexture ) {
...@@ -16467,43 +16466,42 @@ ...@@ -16467,43 +16466,42 @@
function WebGLRenderList() { function WebGLRenderList() {
var opaque = []; var renderItems = [];
var opaqueLastIndex = - 1; var renderItemsIndex = 0;
var opaque = [];
var transparent = []; var transparent = [];
var transparentLastIndex = - 1;
function init() { function init() {
opaqueLastIndex = - 1; renderItemsIndex = 0;
transparentLastIndex = - 1;
opaque.length = 0;
transparent.length = 0;
} }
function push( object, geometry, material, z, group ) { function push( object, geometry, material, z, group ) {
var array, index; var renderItem = renderItems[ renderItemsIndex ];
// allocate the next position in the appropriate array if ( renderItem === undefined ) {
if ( material.transparent ) { renderItem = {
id: object.id,
object: object,
geometry: geometry,
material: material,
program: material.program,
renderOrder: object.renderOrder,
z: z,
group: group
};
array = transparent; renderItems[ renderItemsIndex ] = renderItem;
index = ++ transparentLastIndex;
} else { } else {
array = opaque;
index = ++ opaqueLastIndex;
}
// recycle existing render item or grow the array
var renderItem = array[ index ];
if ( renderItem ) {
renderItem.id = object.id; renderItem.id = object.id;
renderItem.object = object; renderItem.object = object;
renderItem.geometry = geometry; renderItem.geometry = geometry;
...@@ -16513,37 +16511,18 @@ ...@@ -16513,37 +16511,18 @@
renderItem.z = z; renderItem.z = z;
renderItem.group = group; renderItem.group = group;
} else {
renderItem = {
id: object.id,
object: object,
geometry: geometry,
material: material,
program: material.program,
renderOrder: object.renderOrder,
z: z,
group: group
};
// assert( index === array.length );
array.push( renderItem );
} }
} ( material.transparent === true ? transparent : opaque ).push( renderItem );
function finish() {
opaque.length = opaqueLastIndex + 1; renderItemsIndex ++;
transparent.length = transparentLastIndex + 1;
} }
function sort() { function sort() {
opaque.sort( painterSortStable ); if ( opaque.length > 1 ) opaque.sort( painterSortStable );
transparent.sort( reversePainterSortStable ); if ( transparent.length > 1 ) transparent.sort( reversePainterSortStable );
} }
...@@ -16553,7 +16532,6 @@ ...@@ -16553,7 +16532,6 @@
init: init, init: init,
push: push, push: push,
finish: finish,
sort: sort sort: sort
}; };
...@@ -16595,6 +16573,115 @@ ...@@ -16595,6 +16573,115 @@
} }
/**
* @author mrdoob / http://mrdoob.com/
*/
function absNumericalSort( a, b ) {
return Math.abs( b[ 1 ] ) - Math.abs( a[ 1 ] );
}
function WebGLMorphtargets( gl ) {
var influencesList = {};
var morphInfluences = new Float32Array( 8 );
function update( object, geometry, material, program ) {
var objectInfluences = object.morphTargetInfluences;
var length = objectInfluences.length;
var influences = influencesList[ geometry.id ];
if ( influences === undefined ) {
// initialise list
influences = [];
for ( var i = 0; i < length; i ++ ) {
influences[ i ] = [ i, 0 ];
}
influencesList[ geometry.id ] = influences;
}
var morphTargets = material.morphTargets && geometry.morphAttributes.position;
var morphNormals = material.morphNormals && geometry.morphAttributes.normal;
// Remove current morphAttributes
for ( var i = 0; i < length; i ++ ) {
var influence = influences[ i ];
if ( influence[ 1 ] !== 0 ) {
if ( morphTargets ) geometry.removeAttribute( 'morphTarget' + i );
if ( morphNormals ) geometry.removeAttribute( 'morphNormal' + i );
}
}
// Collect influences
for ( var i = 0; i < length; i ++ ) {
var influence = influences[ i ];
influence[ 0 ] = i;
influence[ 1 ] = objectInfluences[ i ];
}
influences.sort( absNumericalSort );
// Add morphAttributes
for ( var i = 0; i < 8; i ++ ) {
var influence = influences[ i ];
if ( influence ) {
var index = influence[ 0 ];
var value = influence[ 1 ];
if ( value ) {
if ( morphTargets ) geometry.addAttribute( 'morphTarget' + i, morphTargets[ index ] );
if ( morphNormals ) geometry.addAttribute( 'morphNormal' + i, morphNormals[ index ] );
morphInfluences[ i ] = value;
continue;
}
}
morphInfluences[ i ] = 0;
}
program.getUniforms().setValue( gl, 'morphTargetInfluences', morphInfluences );
}
return {
update: update
}
}
/** /**
* @author mrdoob / http://mrdoob.com/ * @author mrdoob / http://mrdoob.com/
*/ */
...@@ -20679,8 +20766,6 @@ ...@@ -20679,8 +20766,6 @@
var currentRenderList = null; var currentRenderList = null;
var morphInfluences = new Float32Array( 8 );
var spritesArray = []; var spritesArray = [];
var flaresArray = []; var flaresArray = [];
...@@ -20864,7 +20949,7 @@ ...@@ -20864,7 +20949,7 @@
var properties, textures, attributes, geometries, objects, lights; var properties, textures, attributes, geometries, objects, lights;
var programCache, renderLists; var programCache, renderLists;
var background, bufferRenderer, indexedBufferRenderer; var background, morphtargets, bufferRenderer, indexedBufferRenderer;
var flareRenderer, spriteRenderer; var flareRenderer, spriteRenderer;
function initGLContext() { function initGLContext() {
...@@ -20895,6 +20980,7 @@ ...@@ -20895,6 +20980,7 @@
attributes = new WebGLAttributes( _gl ); attributes = new WebGLAttributes( _gl );
geometries = new WebGLGeometries( _gl, attributes, _infoMemory ); geometries = new WebGLGeometries( _gl, attributes, _infoMemory );
objects = new WebGLObjects( geometries, _infoRender ); objects = new WebGLObjects( geometries, _infoRender );
morphtargets = new WebGLMorphtargets( _gl );
programCache = new WebGLPrograms( _this, extensions, capabilities ); programCache = new WebGLPrograms( _this, extensions, capabilities );
lights = new WebGLLights(); lights = new WebGLLights();
renderLists = new WebGLRenderLists(); renderLists = new WebGLRenderLists();
...@@ -21276,12 +21362,6 @@ ...@@ -21276,12 +21362,6 @@
}; };
function absNumericalSort( a, b ) {
return Math.abs( b[ 0 ] ) - Math.abs( a[ 0 ] );
}
this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) { this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {
state.setMaterial( material ); state.setMaterial( material );
...@@ -21298,61 +21378,9 @@ ...@@ -21298,61 +21378,9 @@
} }
// morph targets if ( object.morphTargetInfluences ) {
var morphTargetInfluences = object.morphTargetInfluences;
if ( morphTargetInfluences !== undefined ) {
// TODO Remove allocations
var activeInfluences = [];
for ( var i = 0, l = morphTargetInfluences.length; i < l; i ++ ) {
var influence = morphTargetInfluences[ i ];
activeInfluences.push( [ influence, i ] );
}
activeInfluences.sort( absNumericalSort );
if ( activeInfluences.length > 8 ) {
activeInfluences.length = 8;
} morphtargets.update( object, geometry, material, program );
var morphAttributes = geometry.morphAttributes;
for ( var i = 0, l = activeInfluences.length; i < l; i ++ ) {
var influence = activeInfluences[ i ];
morphInfluences[ i ] = influence[ 0 ];
if ( influence[ 0 ] !== 0 ) {
var index = influence[ 1 ];
if ( material.morphTargets === true && morphAttributes.position ) geometry.addAttribute( 'morphTarget' + i, morphAttributes.position[ index ] );
if ( material.morphNormals === true && morphAttributes.normal ) geometry.addAttribute( 'morphNormal' + i, morphAttributes.normal[ index ] );
} else {
if ( material.morphTargets === true ) geometry.removeAttribute( 'morphTarget' + i );
if ( material.morphNormals === true ) geometry.removeAttribute( 'morphNormal' + i );
}
}
for ( var i = activeInfluences.length, il = morphInfluences.length; i < il; i ++ ) {
morphInfluences[ i ] = 0.0;
}
program.getUniforms().setValue( _gl, 'morphTargetInfluences', morphInfluences );
updateBuffers = true; updateBuffers = true;
...@@ -21740,8 +21768,6 @@ ...@@ -21740,8 +21768,6 @@
projectObject( scene, camera, _this.sortObjects ); projectObject( scene, camera, _this.sortObjects );
currentRenderList.finish();
if ( _this.sortObjects === true ) { if ( _this.sortObjects === true ) {
currentRenderList.sort(); currentRenderList.sort();
...@@ -22523,7 +22549,11 @@ ...@@ -22523,7 +22549,11 @@
uniforms.opacity.value = material.opacity; uniforms.opacity.value = material.opacity;
uniforms.diffuse.value = material.color; if ( material.color ) {
uniforms.diffuse.value = material.color;
}
if ( material.emissive ) { if ( material.emissive ) {
...@@ -22531,9 +22561,38 @@ ...@@ -22531,9 +22561,38 @@
} }
uniforms.map.value = material.map; if ( material.map ) {
uniforms.specularMap.value = material.specularMap;
uniforms.alphaMap.value = material.alphaMap; uniforms.map.value = material.map;
}
if ( material.alphaMap ) {
uniforms.alphaMap.value = material.alphaMap;
}
if ( material.specularMap ) {
uniforms.specularMap.value = material.specularMap;
}
if ( material.envMap ) {
uniforms.envMap.value = material.envMap;
// don't flip CubeTexture envMaps, flip everything else:
// WebGLRenderTargetCube will be flipped for backwards compatibility
// WebGLRenderTargetCube.texture will be flipped because it's a Texture and NOT a CubeTexture
// this check must be handled differently, or removed entirely, if WebGLRenderTargetCube uses a CubeTexture in the future
uniforms.flipEnvMap.value = ( ! ( material.envMap && material.envMap.isCubeTexture ) ) ? 1 : - 1;
uniforms.reflectivity.value = material.reflectivity;
uniforms.refractionRatio.value = material.refractionRatio;
}
if ( material.lightMap ) { if ( material.lightMap ) {
...@@ -22613,17 +22672,6 @@ ...@@ -22613,17 +22672,6 @@
} }
uniforms.envMap.value = material.envMap;
// don't flip CubeTexture envMaps, flip everything else:
// WebGLRenderTargetCube will be flipped for backwards compatibility
// WebGLRenderTargetCube.texture will be flipped because it's a Texture and NOT a CubeTexture
// this check must be handled differently, or removed entirely, if WebGLRenderTargetCube uses a CubeTexture in the future
uniforms.flipEnvMap.value = ( ! ( material.envMap && material.envMap.isCubeTexture ) ) ? 1 : - 1;
uniforms.reflectivity.value = material.reflectivity;
uniforms.refractionRatio.value = material.refractionRatio;
} }
function refreshUniformsLine( uniforms, material ) { function refreshUniformsLine( uniforms, material ) {
...@@ -32276,7 +32324,7 @@ ...@@ -32276,7 +32324,7 @@
} else { } else {
// by default, we asssume a constructor compatible with the base // by default, we assume a constructor compatible with the base
return new trackType( return new trackType(
json.name, json.times, json.values, json.interpolation ); json.name, json.times, json.values, json.interpolation );
此差异已折叠。
...@@ -5383,9 +5383,18 @@ var UniformsLib = { ...@@ -5383,9 +5383,18 @@ var UniformsLib = {
map: { value: null }, map: { value: null },
offsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) }, offsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) },
specularMap: { value: null },
alphaMap: { value: null }, alphaMap: { value: null },
},
specularmap: {
specularMap: { value: null },
},
envmap: {
envMap: { value: null }, envMap: { value: null },
flipEnvMap: { value: - 1 }, flipEnvMap: { value: - 1 },
reflectivity: { value: 1.0 }, reflectivity: { value: 1.0 },
...@@ -5778,9 +5787,9 @@ var uv2_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = ...@@ -5778,9 +5787,9 @@ var uv2_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 =
var worldpos_vertex = "#if defined( USE_ENVMAP ) || defined( PHONG ) || defined( PHYSICAL ) || defined( LAMBERT ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP )\n\tvec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );\n#endif\n"; var worldpos_vertex = "#if defined( USE_ENVMAP ) || defined( PHONG ) || defined( PHYSICAL ) || defined( LAMBERT ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP )\n\tvec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );\n#endif\n";
var cube_frag = "uniform samplerCube tCube;\nuniform float tFlip;\nuniform float opacity;\nvarying vec3 vWorldPosition;\n#include <common>\nvoid main() {\n\tgl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );\n\tgl_FragColor.a *= opacity;\n}\n"; var cube_frag = "uniform samplerCube tCube;\nuniform float tFlip;\nuniform float opacity;\nvarying vec3 vWorldPosition;\nvoid main() {\n\tgl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );\n\tgl_FragColor.a *= opacity;\n}\n";
var cube_vert = "varying vec3 vWorldPosition;\n#include <common>\nvoid main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n}\n"; var cube_vert = "varying vec3 vWorldPosition;\n#include <common>\nvoid main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\tgl_Position = projectionMatrix * vec4( normalMatrix * position, 1.0 );\n}\n";
var depth_frag = "#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include <common>\n#include <packing>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <logdepthbuf_fragment>\n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( gl_FragCoord.z ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( gl_FragCoord.z );\n\t#endif\n}\n"; var depth_frag = "#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include <common>\n#include <packing>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <logdepthbuf_fragment>\n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( gl_FragCoord.z ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( gl_FragCoord.z );\n\t#endif\n}\n";
...@@ -5790,7 +5799,7 @@ var distanceRGBA_frag = "#define DISTANCE\nuniform vec3 referencePosition;\nunif ...@@ -5790,7 +5799,7 @@ var distanceRGBA_frag = "#define DISTANCE\nuniform vec3 referencePosition;\nunif
var distanceRGBA_vert = "#define DISTANCE\nvarying vec3 vWorldPosition;\n#include <common>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <worldpos_vertex>\n\t#include <clipping_planes_vertex>\n\tvWorldPosition = worldPosition.xyz;\n}\n"; var distanceRGBA_vert = "#define DISTANCE\nvarying vec3 vWorldPosition;\n#include <common>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <worldpos_vertex>\n\t#include <clipping_planes_vertex>\n\tvWorldPosition = worldPosition.xyz;\n}\n";
var equirect_frag = "uniform sampler2D tEquirect;\nuniform float tFlip;\nvarying vec3 vWorldPosition;\n#include <common>\nvoid main() {\n\tvec3 direction = normalize( vWorldPosition );\n\tvec2 sampleUV;\n\tsampleUV.y = saturate( tFlip * direction.y * -0.5 + 0.5 );\n\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\n\tgl_FragColor = texture2D( tEquirect, sampleUV );\n}\n"; var equirect_frag = "uniform sampler2D tEquirect;\nvarying vec3 vWorldPosition;\n#include <common>\nvoid main() {\n\tvec3 direction = normalize( vWorldPosition );\n\tvec2 sampleUV;\n\tsampleUV.y = asin( clamp( direction.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\tsampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;\n\tgl_FragColor = texture2D( tEquirect, sampleUV );\n}\n";
var equirect_vert = "varying vec3 vWorldPosition;\n#include <common>\nvoid main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n}\n"; var equirect_vert = "varying vec3 vWorldPosition;\n#include <common>\nvoid main() {\n\tvWorldPosition = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n}\n";
...@@ -5951,6 +5960,8 @@ var ShaderLib = { ...@@ -5951,6 +5960,8 @@ var ShaderLib = {
uniforms: UniformsUtils.merge( [ uniforms: UniformsUtils.merge( [
UniformsLib.common, UniformsLib.common,
UniformsLib.specularmap,
UniformsLib.envmap,
UniformsLib.aomap, UniformsLib.aomap,
UniformsLib.lightmap, UniformsLib.lightmap,
UniformsLib.fog UniformsLib.fog
...@@ -5965,6 +5976,8 @@ var ShaderLib = { ...@@ -5965,6 +5976,8 @@ var ShaderLib = {
uniforms: UniformsUtils.merge( [ uniforms: UniformsUtils.merge( [
UniformsLib.common, UniformsLib.common,
UniformsLib.specularmap,
UniformsLib.envmap,
UniformsLib.aomap, UniformsLib.aomap,
UniformsLib.lightmap, UniformsLib.lightmap,
UniformsLib.emissivemap, UniformsLib.emissivemap,
...@@ -5984,6 +5997,8 @@ var ShaderLib = { ...@@ -5984,6 +5997,8 @@ var ShaderLib = {
uniforms: UniformsUtils.merge( [ uniforms: UniformsUtils.merge( [
UniformsLib.common, UniformsLib.common,
UniformsLib.specularmap,
UniformsLib.envmap,
UniformsLib.aomap, UniformsLib.aomap,
UniformsLib.lightmap, UniformsLib.lightmap,
UniformsLib.emissivemap, UniformsLib.emissivemap,
...@@ -6009,6 +6024,7 @@ var ShaderLib = { ...@@ -6009,6 +6024,7 @@ var ShaderLib = {
uniforms: UniformsUtils.merge( [ uniforms: UniformsUtils.merge( [
UniformsLib.common, UniformsLib.common,
UniformsLib.envmap,
UniformsLib.aomap, UniformsLib.aomap,
UniformsLib.lightmap, UniformsLib.lightmap,
UniformsLib.emissivemap, UniformsLib.emissivemap,
...@@ -6107,15 +6123,10 @@ var ShaderLib = { ...@@ -6107,15 +6123,10 @@ var ShaderLib = {
}, },
/* -------------------------------------------------------------------------
// Cube map shader
------------------------------------------------------------------------- */
equirect: { equirect: {
uniforms: { uniforms: {
tEquirect: { value: null }, tEquirect: { value: null },
tFlip: { value: - 1 }
}, },
vertexShader: ShaderChunk.equirect_vert, vertexShader: ShaderChunk.equirect_vert,
...@@ -8350,15 +8361,7 @@ Object.assign( Sphere.prototype, { ...@@ -8350,15 +8361,7 @@ Object.assign( Sphere.prototype, {
intersectsPlane: function ( plane ) { intersectsPlane: function ( plane ) {
// We use the following equation to compute the signed distance from return Math.abs( plane.distanceToPoint( this.center ) ) <= this.radius;
// the center of the sphere to the plane.
//
// distance = q * n - d
//
// If this distance is greater than the radius of the sphere,
// then there is no intersection.
return Math.abs( this.center.dot( plane.normal ) - plane.constant ) <= this.radius;
}, },
...@@ -8750,6 +8753,8 @@ Object.assign( Matrix3.prototype, { ...@@ -8750,6 +8753,8 @@ Object.assign( Matrix3.prototype, {
function Plane( normal, constant ) { function Plane( normal, constant ) {
// normal is assumed to be normalized
this.normal = ( normal !== undefined ) ? normal : new Vector3( 1, 0, 0 ); this.normal = ( normal !== undefined ) ? normal : new Vector3( 1, 0, 0 );
this.constant = ( constant !== undefined ) ? constant : 0; this.constant = ( constant !== undefined ) ? constant : 0;
...@@ -16295,7 +16300,7 @@ function WebGLBackground( renderer, state, geometries, premultipliedAlpha ) { ...@@ -16295,7 +16300,7 @@ function WebGLBackground( renderer, state, geometries, premultipliedAlpha ) {
var clearAlpha = 0; var clearAlpha = 0;
var planeCamera, planeMesh; var planeCamera, planeMesh;
var boxCamera, boxMesh; var boxMesh;
function render( scene, camera, forceClear ) { function render( scene, camera, forceClear ) {
...@@ -16320,9 +16325,7 @@ function WebGLBackground( renderer, state, geometries, premultipliedAlpha ) { ...@@ -16320,9 +16325,7 @@ function WebGLBackground( renderer, state, geometries, premultipliedAlpha ) {
if ( background && background.isCubeTexture ) { if ( background && background.isCubeTexture ) {
if ( boxCamera === undefined ) { if ( boxMesh === undefined ) {
boxCamera = new PerspectiveCamera();
boxMesh = new Mesh( boxMesh = new Mesh(
new BoxBufferGeometry( 5, 5, 5 ), new BoxBufferGeometry( 5, 5, 5 ),
...@@ -16339,17 +16342,13 @@ function WebGLBackground( renderer, state, geometries, premultipliedAlpha ) { ...@@ -16339,17 +16342,13 @@ function WebGLBackground( renderer, state, geometries, premultipliedAlpha ) {
} }
boxCamera.projectionMatrix.copy( camera.projectionMatrix );
boxCamera.matrixWorld.extractRotation( camera.matrixWorld );
boxCamera.matrixWorldInverse.getInverse( boxCamera.matrixWorld );
boxMesh.material.uniforms[ "tCube" ].value = background; boxMesh.material.uniforms[ "tCube" ].value = background;
boxMesh.modelViewMatrix.multiplyMatrices( boxCamera.matrixWorldInverse, boxMesh.matrixWorld ); boxMesh.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, boxMesh.matrixWorld );
boxMesh.normalMatrix.getNormalMatrix( boxMesh.modelViewMatrix );
geometries.update( boxMesh.geometry ); geometries.update( boxMesh.geometry );
renderer.renderBufferDirect( boxCamera, null, boxMesh.geometry, boxMesh.material, boxMesh, null ); renderer.renderBufferDirect( camera, null, boxMesh.geometry, boxMesh.material, boxMesh, null );
} else if ( background && background.isTexture ) { } else if ( background && background.isTexture ) {
...@@ -16461,43 +16460,42 @@ function reversePainterSortStable( a, b ) { ...@@ -16461,43 +16460,42 @@ function reversePainterSortStable( a, b ) {
function WebGLRenderList() { function WebGLRenderList() {
var opaque = []; var renderItems = [];
var opaqueLastIndex = - 1; var renderItemsIndex = 0;
var opaque = [];
var transparent = []; var transparent = [];
var transparentLastIndex = - 1;
function init() { function init() {
opaqueLastIndex = - 1; renderItemsIndex = 0;
transparentLastIndex = - 1;
opaque.length = 0;
transparent.length = 0;
} }
function push( object, geometry, material, z, group ) { function push( object, geometry, material, z, group ) {
var array, index; var renderItem = renderItems[ renderItemsIndex ];
// allocate the next position in the appropriate array if ( renderItem === undefined ) {
if ( material.transparent ) { renderItem = {
id: object.id,
object: object,
geometry: geometry,
material: material,
program: material.program,
renderOrder: object.renderOrder,
z: z,
group: group
};
array = transparent; renderItems[ renderItemsIndex ] = renderItem;
index = ++ transparentLastIndex;
} else { } else {
array = opaque;
index = ++ opaqueLastIndex;
}
// recycle existing render item or grow the array
var renderItem = array[ index ];
if ( renderItem ) {
renderItem.id = object.id; renderItem.id = object.id;
renderItem.object = object; renderItem.object = object;
renderItem.geometry = geometry; renderItem.geometry = geometry;
...@@ -16507,37 +16505,18 @@ function WebGLRenderList() { ...@@ -16507,37 +16505,18 @@ function WebGLRenderList() {
renderItem.z = z; renderItem.z = z;
renderItem.group = group; renderItem.group = group;
} else {
renderItem = {
id: object.id,
object: object,
geometry: geometry,
material: material,
program: material.program,
renderOrder: object.renderOrder,
z: z,
group: group
};
// assert( index === array.length );
array.push( renderItem );
} }
} ( material.transparent === true ? transparent : opaque ).push( renderItem );
function finish() {
opaque.length = opaqueLastIndex + 1; renderItemsIndex ++;
transparent.length = transparentLastIndex + 1;
} }
function sort() { function sort() {
opaque.sort( painterSortStable ); if ( opaque.length > 1 ) opaque.sort( painterSortStable );
transparent.sort( reversePainterSortStable ); if ( transparent.length > 1 ) transparent.sort( reversePainterSortStable );
} }
...@@ -16547,7 +16526,6 @@ function WebGLRenderList() { ...@@ -16547,7 +16526,6 @@ function WebGLRenderList() {
init: init, init: init,
push: push, push: push,
finish: finish,
sort: sort sort: sort
}; };
...@@ -16589,6 +16567,115 @@ function WebGLRenderLists() { ...@@ -16589,6 +16567,115 @@ function WebGLRenderLists() {
} }
/**
* @author mrdoob / http://mrdoob.com/
*/
function absNumericalSort( a, b ) {
return Math.abs( b[ 1 ] ) - Math.abs( a[ 1 ] );
}
function WebGLMorphtargets( gl ) {
var influencesList = {};
var morphInfluences = new Float32Array( 8 );
function update( object, geometry, material, program ) {
var objectInfluences = object.morphTargetInfluences;
var length = objectInfluences.length;
var influences = influencesList[ geometry.id ];
if ( influences === undefined ) {
// initialise list
influences = [];
for ( var i = 0; i < length; i ++ ) {
influences[ i ] = [ i, 0 ];
}
influencesList[ geometry.id ] = influences;
}
var morphTargets = material.morphTargets && geometry.morphAttributes.position;
var morphNormals = material.morphNormals && geometry.morphAttributes.normal;
// Remove current morphAttributes
for ( var i = 0; i < length; i ++ ) {
var influence = influences[ i ];
if ( influence[ 1 ] !== 0 ) {
if ( morphTargets ) geometry.removeAttribute( 'morphTarget' + i );
if ( morphNormals ) geometry.removeAttribute( 'morphNormal' + i );
}
}
// Collect influences
for ( var i = 0; i < length; i ++ ) {
var influence = influences[ i ];
influence[ 0 ] = i;
influence[ 1 ] = objectInfluences[ i ];
}
influences.sort( absNumericalSort );
// Add morphAttributes
for ( var i = 0; i < 8; i ++ ) {
var influence = influences[ i ];
if ( influence ) {
var index = influence[ 0 ];
var value = influence[ 1 ];
if ( value ) {
if ( morphTargets ) geometry.addAttribute( 'morphTarget' + i, morphTargets[ index ] );
if ( morphNormals ) geometry.addAttribute( 'morphNormal' + i, morphNormals[ index ] );
morphInfluences[ i ] = value;
continue;
}
}
morphInfluences[ i ] = 0;
}
program.getUniforms().setValue( gl, 'morphTargetInfluences', morphInfluences );
}
return {
update: update
}
}
/** /**
* @author mrdoob / http://mrdoob.com/ * @author mrdoob / http://mrdoob.com/
*/ */
...@@ -20673,8 +20760,6 @@ function WebGLRenderer( parameters ) { ...@@ -20673,8 +20760,6 @@ function WebGLRenderer( parameters ) {
var currentRenderList = null; var currentRenderList = null;
var morphInfluences = new Float32Array( 8 );
var spritesArray = []; var spritesArray = [];
var flaresArray = []; var flaresArray = [];
...@@ -20858,7 +20943,7 @@ function WebGLRenderer( parameters ) { ...@@ -20858,7 +20943,7 @@ function WebGLRenderer( parameters ) {
var properties, textures, attributes, geometries, objects, lights; var properties, textures, attributes, geometries, objects, lights;
var programCache, renderLists; var programCache, renderLists;
var background, bufferRenderer, indexedBufferRenderer; var background, morphtargets, bufferRenderer, indexedBufferRenderer;
var flareRenderer, spriteRenderer; var flareRenderer, spriteRenderer;
function initGLContext() { function initGLContext() {
...@@ -20889,6 +20974,7 @@ function WebGLRenderer( parameters ) { ...@@ -20889,6 +20974,7 @@ function WebGLRenderer( parameters ) {
attributes = new WebGLAttributes( _gl ); attributes = new WebGLAttributes( _gl );
geometries = new WebGLGeometries( _gl, attributes, _infoMemory ); geometries = new WebGLGeometries( _gl, attributes, _infoMemory );
objects = new WebGLObjects( geometries, _infoRender ); objects = new WebGLObjects( geometries, _infoRender );
morphtargets = new WebGLMorphtargets( _gl );
programCache = new WebGLPrograms( _this, extensions, capabilities ); programCache = new WebGLPrograms( _this, extensions, capabilities );
lights = new WebGLLights(); lights = new WebGLLights();
renderLists = new WebGLRenderLists(); renderLists = new WebGLRenderLists();
...@@ -21270,12 +21356,6 @@ function WebGLRenderer( parameters ) { ...@@ -21270,12 +21356,6 @@ function WebGLRenderer( parameters ) {
}; };
function absNumericalSort( a, b ) {
return Math.abs( b[ 0 ] ) - Math.abs( a[ 0 ] );
}
this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) { this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {
state.setMaterial( material ); state.setMaterial( material );
...@@ -21292,61 +21372,9 @@ function WebGLRenderer( parameters ) { ...@@ -21292,61 +21372,9 @@ function WebGLRenderer( parameters ) {
} }
// morph targets if ( object.morphTargetInfluences ) {
var morphTargetInfluences = object.morphTargetInfluences;
if ( morphTargetInfluences !== undefined ) {
// TODO Remove allocations
var activeInfluences = [];
for ( var i = 0, l = morphTargetInfluences.length; i < l; i ++ ) {
var influence = morphTargetInfluences[ i ];
activeInfluences.push( [ influence, i ] );
}
activeInfluences.sort( absNumericalSort );
if ( activeInfluences.length > 8 ) {
activeInfluences.length = 8;
} morphtargets.update( object, geometry, material, program );
var morphAttributes = geometry.morphAttributes;
for ( var i = 0, l = activeInfluences.length; i < l; i ++ ) {
var influence = activeInfluences[ i ];
morphInfluences[ i ] = influence[ 0 ];
if ( influence[ 0 ] !== 0 ) {
var index = influence[ 1 ];
if ( material.morphTargets === true && morphAttributes.position ) geometry.addAttribute( 'morphTarget' + i, morphAttributes.position[ index ] );
if ( material.morphNormals === true && morphAttributes.normal ) geometry.addAttribute( 'morphNormal' + i, morphAttributes.normal[ index ] );
} else {
if ( material.morphTargets === true ) geometry.removeAttribute( 'morphTarget' + i );
if ( material.morphNormals === true ) geometry.removeAttribute( 'morphNormal' + i );
}
}
for ( var i = activeInfluences.length, il = morphInfluences.length; i < il; i ++ ) {
morphInfluences[ i ] = 0.0;
}
program.getUniforms().setValue( _gl, 'morphTargetInfluences', morphInfluences );
updateBuffers = true; updateBuffers = true;
...@@ -21734,8 +21762,6 @@ function WebGLRenderer( parameters ) { ...@@ -21734,8 +21762,6 @@ function WebGLRenderer( parameters ) {
projectObject( scene, camera, _this.sortObjects ); projectObject( scene, camera, _this.sortObjects );
currentRenderList.finish();
if ( _this.sortObjects === true ) { if ( _this.sortObjects === true ) {
currentRenderList.sort(); currentRenderList.sort();
...@@ -22517,7 +22543,11 @@ function WebGLRenderer( parameters ) { ...@@ -22517,7 +22543,11 @@ function WebGLRenderer( parameters ) {
uniforms.opacity.value = material.opacity; uniforms.opacity.value = material.opacity;
uniforms.diffuse.value = material.color; if ( material.color ) {
uniforms.diffuse.value = material.color;
}
if ( material.emissive ) { if ( material.emissive ) {
...@@ -22525,9 +22555,38 @@ function WebGLRenderer( parameters ) { ...@@ -22525,9 +22555,38 @@ function WebGLRenderer( parameters ) {
} }
uniforms.map.value = material.map; if ( material.map ) {
uniforms.specularMap.value = material.specularMap;
uniforms.alphaMap.value = material.alphaMap; uniforms.map.value = material.map;
}
if ( material.alphaMap ) {
uniforms.alphaMap.value = material.alphaMap;
}
if ( material.specularMap ) {
uniforms.specularMap.value = material.specularMap;
}
if ( material.envMap ) {
uniforms.envMap.value = material.envMap;
// don't flip CubeTexture envMaps, flip everything else:
// WebGLRenderTargetCube will be flipped for backwards compatibility
// WebGLRenderTargetCube.texture will be flipped because it's a Texture and NOT a CubeTexture
// this check must be handled differently, or removed entirely, if WebGLRenderTargetCube uses a CubeTexture in the future
uniforms.flipEnvMap.value = ( ! ( material.envMap && material.envMap.isCubeTexture ) ) ? 1 : - 1;
uniforms.reflectivity.value = material.reflectivity;
uniforms.refractionRatio.value = material.refractionRatio;
}
if ( material.lightMap ) { if ( material.lightMap ) {
...@@ -22607,17 +22666,6 @@ function WebGLRenderer( parameters ) { ...@@ -22607,17 +22666,6 @@ function WebGLRenderer( parameters ) {
} }
uniforms.envMap.value = material.envMap;
// don't flip CubeTexture envMaps, flip everything else:
// WebGLRenderTargetCube will be flipped for backwards compatibility
// WebGLRenderTargetCube.texture will be flipped because it's a Texture and NOT a CubeTexture
// this check must be handled differently, or removed entirely, if WebGLRenderTargetCube uses a CubeTexture in the future
uniforms.flipEnvMap.value = ( ! ( material.envMap && material.envMap.isCubeTexture ) ) ? 1 : - 1;
uniforms.reflectivity.value = material.reflectivity;
uniforms.refractionRatio.value = material.refractionRatio;
} }
function refreshUniformsLine( uniforms, material ) { function refreshUniformsLine( uniforms, material ) {
...@@ -32270,7 +32318,7 @@ Object.assign( KeyframeTrack, { ...@@ -32270,7 +32318,7 @@ Object.assign( KeyframeTrack, {
} else { } else {
// by default, we asssume a constructor compatible with the base // by default, we assume a constructor compatible with the base
return new trackType( return new trackType(
json.name, json.times, json.values, json.interpolation ); json.name, json.times, json.values, json.interpolation );
......
...@@ -27,6 +27,19 @@ ...@@ -27,6 +27,19 @@
The [page:InterleavedBuffer InterleavedBuffer] instance passed in the constructor. The [page:InterleavedBuffer InterleavedBuffer] instance passed in the constructor.
</div> </div>
<h3>[property:TypedArray array]</h3>
<div>
The value of [page:InterleavedBufferAttribute.data data].array.
</div>
<h3>[property:Integer count]</h3>
<div>
The value of [page:InterleavedBufferAttribute.data data].count.
If the buffer is storing a 3-component vector (such as a position, normal, or color),
then this will count the number of such vectors stored.
</div>
<h3>[property:Integer itemSize]</h3> <h3>[property:Integer itemSize]</h3>
<div> <div>
</div> </div>
...@@ -47,16 +60,6 @@ ...@@ -47,16 +60,6 @@
<h2>Methods</h2> <h2>Methods</h2>
<h3>[method:Integer count]()</h3>
<div>
The value of [page:InterleavedBufferAttribute.data data].count.
</div>
<h3>[method:Array array]()</h3>
<div>
The value of [page:InterleavedBufferAttribute.data data].array.
</div>
<h3>[method:null getX]( index ) </h3> <h3>[method:null getX]( index ) </h3>
<div> <div>
......
...@@ -44,11 +44,11 @@ for ( var i = 0; i < 10000; i ++ ) { ...@@ -44,11 +44,11 @@ for ( var i = 0; i < 10000; i ++ ) {
star.y = THREE.Math.randFloatSpread( 2000 ); star.y = THREE.Math.randFloatSpread( 2000 );
star.z = THREE.Math.randFloatSpread( 2000 ); star.z = THREE.Math.randFloatSpread( 2000 );
starsGeometry.vertices.push( star ) starsGeometry.vertices.push( star );
} }
var starsMaterial = new THREE.PointsMaterial( { color: 0x888888 } ) var starsMaterial = new THREE.PointsMaterial( { color: 0x888888 } );
var starField = new THREE.Points( starsGeometry, starsMaterial ); var starField = new THREE.Points( starsGeometry, starsMaterial );
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
<div class="desc"> <div class="desc">
A two dimensional surface that extends infinitely in 3d space, represented in [link:http://mathworld.wolfram.com/HessianNormalForm.html Hessian normal form] A two dimensional surface that extends infinitely in 3d space, represented in [link:http://mathworld.wolfram.com/HessianNormalForm.html Hessian normal form]
by a normal vector and a constant. by a unit length normal vector and a constant.
</div> </div>
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
<h3>[name]( [page:Vector3 normal], [page:Float constant] )</h3> <h3>[name]( [page:Vector3 normal], [page:Float constant] )</h3>
<div> <div>
[page:Vector3 normal] - (optional) a [page:Vector3] defining the normal of the plane. Default is *(1, 0, 0)*.<br /> [page:Vector3 normal] - (optional) a unit length [page:Vector3] defining the normal of the plane. Default is *(1, 0, 0)*.<br />
[page:Float constant] - (optional) the signed distance from the origin to the plane. Default is *0*. [page:Float constant] - (optional) the signed distance from the origin to the plane. Default is *0*.
</div> </div>
...@@ -130,7 +130,7 @@ ...@@ -130,7 +130,7 @@
<h3>[method:Plane set]( [page:Vector3 normal], [page:Float constant] )</h3> <h3>[method:Plane set]( [page:Vector3 normal], [page:Float constant] )</h3>
<div> <div>
[page:Vector3 normal] - a [page:Vector3] defining the normal of the plane.<br /> [page:Vector3 normal] - a unit length [page:Vector3] defining the normal of the plane.<br />
[page:Float constant] - the signed distance from the origin to the plane. Default is *0*.<br /><br /> [page:Float constant] - the signed distance from the origin to the plane. Default is *0*.<br /><br />
Sets the plane's [page:.normal normal] and [page:.constant constant] properties. Sets the plane's [page:.normal normal] and [page:.constant constant] properties.
...@@ -138,9 +138,9 @@ ...@@ -138,9 +138,9 @@
<h3>[method:Plane setComponents]( [page:Float x], [page:Float y], [page:Float z], [page:Float w] )</h3> <h3>[method:Plane setComponents]( [page:Float x], [page:Float y], [page:Float z], [page:Float w] )</h3>
<div> <div>
[page:Float x] - x value of the normal vector.<br /> [page:Float x] - x value of the unit length normal vector.<br />
[page:Float y] - y value of the normal vector.<br /> [page:Float y] - y value of the unit length normal vector.<br />
[page:Float z] - z value of the normal vector.<br /> [page:Float z] - z value of the unit length normal vector.<br />
[page:Float w] - the value of the plane's [page:.constant constant] property.<br /><br /> [page:Float w] - the value of the plane's [page:.constant constant] property.<br /><br />
Set the individual components that define the plane. Set the individual components that define the plane.
...@@ -158,7 +158,7 @@ ...@@ -158,7 +158,7 @@
<h3>[method:Plane setFromNormalAndCoplanarPoint]( [page:Vector3 normal], [page:Vector3 point] ) [page:Vector3 this]</h3> <h3>[method:Plane setFromNormalAndCoplanarPoint]( [page:Vector3 normal], [page:Vector3 point] ) [page:Vector3 this]</h3>
<div> <div>
[page:Vector3 normal] - a [page:Vector3] defining the normal of the plane.<br /> [page:Vector3 normal] - a unit length [page:Vector3] defining the normal of the plane.<br />
[page:Vector3 point] - [page:Vector3]<br /><br /> [page:Vector3 point] - [page:Vector3]<br /><br />
Sets the plane's properties as defined by a [page:Vector3 normal] and an arbitrary coplanar [page:Vector3 point]. Sets the plane's properties as defined by a [page:Vector3 normal] and an arbitrary coplanar [page:Vector3 point].
......
...@@ -152,7 +152,7 @@ ...@@ -152,7 +152,7 @@
various WebGL extensions are supported. various WebGL extensions are supported.
</div> </div>
<h3>[property:Boolean gammaFactor]</h3> <h3>[property:Float gammaFactor]</h3>
<div>Default is *2*. </div> <div>Default is *2*. </div>
......
...@@ -1885,6 +1885,24 @@ THREE.ColladaLoader.prototype = { ...@@ -1885,6 +1885,24 @@ THREE.ColladaLoader.prototype = {
} }
function groupPrimitives( primitives ) {
var build = {};
for ( var i = 0; i < primitives.length; i ++ ) {
var primitive = primitives[ i ];
if ( build[ primitive.type ] === undefined ) build[ primitive.type ] = [];
build[ primitive.type ].push( primitive );
}
return build;
}
function buildGeometry( data ) { function buildGeometry( data ) {
var build = {}; var build = {};
...@@ -1895,6 +1913,27 @@ THREE.ColladaLoader.prototype = { ...@@ -1895,6 +1913,27 @@ THREE.ColladaLoader.prototype = {
if ( primitives.length === 0 ) return {}; if ( primitives.length === 0 ) return {};
// our goal is to create one buffer geoemtry for a single type of primitives
// first, we group all primitives by their type
var groupedPrimitives = groupPrimitives( primitives );
for ( var type in groupedPrimitives ) {
// second, we create for each type of primitives (polylist,triangles or lines) a buffer geometry
build[ type ] = buildGeometryType( groupedPrimitives[ type ], sources, vertices );
}
return build;
}
function buildGeometryType( primitives, sources, vertices ) {
var build = {};
var position = { array: [], stride: 0 }; var position = { array: [], stride: 0 };
var normal = { array: [], stride: 0 }; var normal = { array: [], stride: 0 };
var uv = { array: [], stride: 0 }; var uv = { array: [], stride: 0 };
...@@ -1904,7 +1943,6 @@ THREE.ColladaLoader.prototype = { ...@@ -1904,7 +1943,6 @@ THREE.ColladaLoader.prototype = {
var skinWeight = { array: [], stride: 4 }; var skinWeight = { array: [], stride: 4 };
var geometry = new THREE.BufferGeometry(); var geometry = new THREE.BufferGeometry();
geometry.name = data.name || '';
var materialKeys = []; var materialKeys = [];
...@@ -1925,7 +1963,16 @@ THREE.ColladaLoader.prototype = { ...@@ -1925,7 +1963,16 @@ THREE.ColladaLoader.prototype = {
// groups // groups
count = primitive.count * 3 * triangleCount; if ( primitive.type === 'lines' || primitive.type === 'linestrips' ) {
count = primitive.count * 2;
} else {
count = primitive.count * 3 * triangleCount;
}
geometry.addGroup( start, count, p ); geometry.addGroup( start, count, p );
start += count; start += count;
...@@ -1944,17 +1991,39 @@ THREE.ColladaLoader.prototype = { ...@@ -1944,17 +1991,39 @@ THREE.ColladaLoader.prototype = {
case 'VERTEX': case 'VERTEX':
for ( var key in vertices ) { for ( var key in vertices ) {
if ( key === 'POSITION' ) { var id = vertices[ key ];
buildGeometryData( primitive, sources[ vertices[ key ] ], input.offset, position.array ); switch ( key ) {
position.stride = sources[ vertices[ key ] ].stride;
if ( sources.skinWeights && sources.skinIndices ) { case 'POSITION':
buildGeometryData( primitive, sources[ id ], input.offset, position.array );
position.stride = sources[ id ].stride;
buildGeometryData( primitive, sources.skinIndices, input.offset, skinIndex.array ); if ( sources.skinWeights && sources.skinIndices ) {
buildGeometryData( primitive, sources.skinWeights, input.offset, skinWeight.array );
} buildGeometryData( primitive, sources.skinIndices, input.offset, skinIndex.array );
buildGeometryData( primitive, sources.skinWeights, input.offset, skinWeight.array );
}
break;
case 'NORMAL':
buildGeometryData( primitive, sources[ id ], input.offset, normal.array );
normal.stride = sources[ id ].stride;
break;
case 'COLOR':
buildGeometryData( primitive, sources[ id ], input.offset, color.array );
color.stride = sources[ id ].stride;
break;
case 'TEXCOORD':
buildGeometryData( primitive, sources[ id ], input.offset, uv.array );
uv.stride = sources[ id ].stride;
break;
default:
console.warn( 'THREE.ColladaLoader: Semantic "%s" not handled in geometry build process.', key );
} }
...@@ -2785,7 +2854,7 @@ THREE.ColladaLoader.prototype = { ...@@ -2785,7 +2854,7 @@ THREE.ColladaLoader.prototype = {
} }
function getSkeleton( skeletons, joints ) { function buildSkeleton( skeletons, joints ) {
var boneData = []; var boneData = [];
var sortedBoneData = []; var sortedBoneData = [];
...@@ -2917,54 +2986,83 @@ THREE.ColladaLoader.prototype = { ...@@ -2917,54 +2986,83 @@ THREE.ColladaLoader.prototype = {
var instanceGeometries = data.instanceGeometries; var instanceGeometries = data.instanceGeometries;
var instanceNodes = data.instanceNodes; var instanceNodes = data.instanceNodes;
// nodes
for ( var i = 0, l = nodes.length; i < l; i ++ ) { for ( var i = 0, l = nodes.length; i < l; i ++ ) {
objects.push( getNode( nodes[ i ] ) ); objects.push( getNode( nodes[ i ] ) );
} }
// instance cameras
for ( var i = 0, l = instanceCameras.length; i < l; i ++ ) { for ( var i = 0, l = instanceCameras.length; i < l; i ++ ) {
objects.push( getCamera( instanceCameras[ i ] ).clone() ); objects.push( getCamera( instanceCameras[ i ] ).clone() );
} }
// instance controllers
for ( var i = 0, l = instanceControllers.length; i < l; i ++ ) { for ( var i = 0, l = instanceControllers.length; i < l; i ++ ) {
var instance = instanceControllers[ i ]; var instance = instanceControllers[ i ];
var controller = getController( instance.id ); var controller = getController( instance.id );
var geometry = getGeometry( controller.id ); var geometries = getGeometry( controller.id );
var materials = resolveMaterialBinding( geometry.materialKeys, instance.materials ); var newObjects = buildObjects( geometries, instance.materials );
var object = getObject( geometry, materials );
var skeletons = instance.skeletons; var skeletons = instance.skeletons;
var joints = controller.skin.joints; var joints = controller.skin.joints;
var skeleton = getSkeleton( skeletons, joints ); var skeleton = buildSkeleton( skeletons, joints );
object.bind( skeleton, controller.skin.bindMatrix ); for ( var j = 0, jl = newObjects.length; j < jl; j ++ ) {
object.normalizeSkinWeights();
objects.push( object ); var object = newObjects[ j ];
if ( object.isSkinnedMesh ) {
object.bind( skeleton, controller.skin.bindMatrix );
object.normalizeSkinWeights();
}
objects.push( object );
}
} }
// instance lights
for ( var i = 0, l = instanceLights.length; i < l; i ++ ) { for ( var i = 0, l = instanceLights.length; i < l; i ++ ) {
objects.push( getLight( instanceLights[ i ] ).clone() ); objects.push( getLight( instanceLights[ i ] ).clone() );
} }
// instance geometries
for ( var i = 0, l = instanceGeometries.length; i < l; i ++ ) { for ( var i = 0, l = instanceGeometries.length; i < l; i ++ ) {
var instance = instanceGeometries[ i ]; var instance = instanceGeometries[ i ];
var geometry = getGeometry( instance.id );
var materials = resolveMaterialBinding( geometry.materialKeys, instance.materials ); // a single geometry instance in collada can lead to multiple object3Ds.
var object = getObject( geometry, materials ); // this is the case when primitives are combined like triangles and lines
objects.push( object );
var geometries = getGeometry( instance.id );
var newObjects = buildObjects( geometries, instance.materials );
for ( var j = 0, jl = newObjects.length; j < jl; j ++ ) {
objects.push( newObjects[ j ] );
}
} }
// instance nodes
for ( var i = 0, l = instanceNodes.length; i < l; i ++ ) { for ( var i = 0, l = instanceNodes.length; i < l; i ++ ) {
objects.push( getNode( instanceNodes[ i ] ).clone() ); objects.push( getNode( instanceNodes[ i ] ).clone() );
...@@ -3012,50 +3110,60 @@ THREE.ColladaLoader.prototype = { ...@@ -3012,50 +3110,60 @@ THREE.ColladaLoader.prototype = {
} }
function getObject( geometry, materials ) { function buildObjects( geometries, instanceMaterials ) {
var object; var objects = [];
for ( var type in geometries ) {
var geometry = geometries[ type ];
var skinning = ( geometry.data.attributes.skinIndex !== undefined ); var materials = resolveMaterialBinding( geometry.materialKeys, instanceMaterials );
if ( skinning ) { var skinning = ( geometry.data.attributes.skinIndex !== undefined );
for ( var i = 0, l = materials.length; i < l; i ++ ) { if ( skinning ) {
materials[ i ].skinning = true; for ( var i = 0, l = materials.length; i < l; i ++ ) {
materials[ i ].skinning = true;
}
} }
} var material = ( materials.length === 1 ) ? materials[ 0 ] : materials;
var material = ( materials.length === 1 ) ? materials[ 0 ] : materials; switch ( type ) {
switch ( geometry.type ) { case 'lines':
object = new THREE.LineSegments( geometry.data, material );
break;
case 'lines': case 'linestrips':
object = new THREE.LineSegments( geometry.data, material ); object = new THREE.Line( geometry.data, material );
break; break;
case 'linestrips': case 'triangles':
object = new THREE.Line( geometry.data, material ); case 'polylist':
break; if ( skinning ) {
case 'triangles': object = new THREE.SkinnedMesh( geometry.data, material );
case 'polylist':
if ( skinning ) {
object = new THREE.SkinnedMesh( geometry.data, material ); } else {
} else { object = new THREE.Mesh( geometry.data, material );
object = new THREE.Mesh( geometry.data, material ); }
break;
} }
break;
objects.push( object );
} }
return object; return objects;
} }
...@@ -3097,7 +3205,17 @@ THREE.ColladaLoader.prototype = { ...@@ -3097,7 +3205,17 @@ THREE.ColladaLoader.prototype = {
var child = children[ i ]; var child = children[ i ];
group.add( getNode( child.id ) ); if ( child.id === null ) {
group.add( buildNode( child ) );
} else {
// if there is an ID, let's try to get the finished build (e.g. joints are already build)
group.add( getNode( child.id ) );
}
} }
......
...@@ -22,7 +22,7 @@ THREE.GLTF2Loader = ( function () { ...@@ -22,7 +22,7 @@ THREE.GLTF2Loader = ( function () {
var scope = this; var scope = this;
var path = this.path && ( typeof this.path === "string" ) ? this.path : THREE.Loader.prototype.extractUrlBase( url ); var path = this.path && ( typeof this.path === 'string' ) ? this.path : THREE.Loader.prototype.extractUrlBase( url );
var loader = new THREE.FileLoader( scope.manager ); var loader = new THREE.FileLoader( scope.manager );
...@@ -110,10 +110,10 @@ THREE.GLTF2Loader = ( function () { ...@@ -110,10 +110,10 @@ THREE.GLTF2Loader = ( function () {
console.timeEnd( 'GLTF2Loader' ); console.timeEnd( 'GLTF2Loader' );
var glTF = { var glTF = {
"scene": scene, scene: scene,
"scenes": scenes, scenes: scenes,
"cameras": cameras, cameras: cameras,
"animations": animations animations: animations
}; };
callback( glTF ); callback( glTF );
...@@ -229,26 +229,26 @@ THREE.GLTF2Loader = ( function () { ...@@ -229,26 +229,26 @@ THREE.GLTF2Loader = ( function () {
switch ( boundUniform.semantic ) { switch ( boundUniform.semantic ) {
case "MODELVIEW": case 'MODELVIEW':
var m4 = boundUniform.uniform.value; var m4 = boundUniform.uniform.value;
m4.multiplyMatrices( camera.matrixWorldInverse, boundUniform.sourceNode.matrixWorld ); m4.multiplyMatrices( camera.matrixWorldInverse, boundUniform.sourceNode.matrixWorld );
break; break;
case "MODELVIEWINVERSETRANSPOSE": case 'MODELVIEWINVERSETRANSPOSE':
var m3 = boundUniform.uniform.value; var m3 = boundUniform.uniform.value;
this._m4.multiplyMatrices( camera.matrixWorldInverse, boundUniform.sourceNode.matrixWorld ); this._m4.multiplyMatrices( camera.matrixWorldInverse, boundUniform.sourceNode.matrixWorld );
m3.getNormalMatrix( this._m4 ); m3.getNormalMatrix( this._m4 );
break; break;
case "PROJECTION": case 'PROJECTION':
var m4 = boundUniform.uniform.value; var m4 = boundUniform.uniform.value;
m4.copy( camera.projectionMatrix ); m4.copy( camera.projectionMatrix );
break; break;
case "JOINTMATRIX": case 'JOINTMATRIX':
var m4v = boundUniform.uniform.value; var m4v = boundUniform.uniform.value;
...@@ -270,7 +270,7 @@ THREE.GLTF2Loader = ( function () { ...@@ -270,7 +270,7 @@ THREE.GLTF2Loader = ( function () {
default : default :
console.warn( "Unhandled shader semantic: " + boundUniform.semantic ); console.warn( 'THREE.GLTF2Loader: Unhandled shader semantic: ' + boundUniform.semantic );
break; break;
} }
...@@ -362,7 +362,7 @@ THREE.GLTF2Loader = ( function () { ...@@ -362,7 +362,7 @@ THREE.GLTF2Loader = ( function () {
if ( light.fallOffExponent !== undefined ) { if ( light.fallOffExponent !== undefined ) {
console.warn( 'GLTF2Loader: light.fallOffExponent not currently supported.' ); console.warn( 'THREE.GLTF2Loader:: light.fallOffExponent not currently supported.' );
} }
...@@ -495,11 +495,11 @@ THREE.GLTF2Loader = ( function () { ...@@ -495,11 +495,11 @@ THREE.GLTF2Loader = ( function () {
if ( this.header.magic !== BINARY_EXTENSION_HEADER_MAGIC ) { if ( this.header.magic !== BINARY_EXTENSION_HEADER_MAGIC ) {
throw new Error( 'GLTF2Loader: Unsupported glTF-Binary header.' ); throw new Error( 'THREE.GLTF2Loader: Unsupported glTF-Binary header.' );
} else if ( this.header.version < 2.0 ) { } else if ( this.header.version < 2.0 ) {
throw new Error( 'GLTF2Loader: Legacy binary file detected. Use GLTFLoader instead.' ); throw new Error( 'THREE.GLTF2Loader: Legacy binary file detected. Use GLTFLoader instead.' );
} }
...@@ -534,7 +534,7 @@ THREE.GLTF2Loader = ( function () { ...@@ -534,7 +534,7 @@ THREE.GLTF2Loader = ( function () {
if ( this.content === null ) { if ( this.content === null ) {
throw new Error( 'GLTF2Loader: JSON content not found.' ); throw new Error( 'THREE.GLTF2Loader: JSON content not found.' );
} }
...@@ -582,7 +582,7 @@ THREE.GLTF2Loader = ( function () { ...@@ -582,7 +582,7 @@ THREE.GLTF2Loader = ( function () {
if ( ! materialParams.fragmentShader ) { if ( ! materialParams.fragmentShader ) {
throw new Error( 'ERROR: Missing fragment shader definition:', program.fragmentShader ); throw new Error( 'THREE.GLTF2Loader: Missing fragment shader definition: ', program.fragmentShader );
} }
...@@ -590,7 +590,7 @@ THREE.GLTF2Loader = ( function () { ...@@ -590,7 +590,7 @@ THREE.GLTF2Loader = ( function () {
if ( ! vertexShader ) { if ( ! vertexShader ) {
throw new Error( 'ERROR: Missing vertex shader definition:', program.vertexShader ); throw new Error( 'THREE.GLTF2Loader: Missing vertex shader definition: ', program.vertexShader );
} }
...@@ -659,7 +659,7 @@ THREE.GLTF2Loader = ( function () { ...@@ -659,7 +659,7 @@ THREE.GLTF2Loader = ( function () {
case WEBGL_CONSTANTS.FLOAT_MAT2: case WEBGL_CONSTANTS.FLOAT_MAT2:
// what to do? // what to do?
console.warn( 'FLOAT_MAT2 is not a supported uniform type' ); console.warn( 'THREE.GLTF2Loader: FLOAT_MAT2 is not a supported uniform type.' );
break; break;
case WEBGL_CONSTANTS.FLOAT_MAT4: case WEBGL_CONSTANTS.FLOAT_MAT4:
...@@ -734,7 +734,7 @@ THREE.GLTF2Loader = ( function () { ...@@ -734,7 +734,7 @@ THREE.GLTF2Loader = ( function () {
} else { } else {
throw new Error( 'Unknown shader uniform param type: ' + ptype ); throw new Error( 'THREE.GLTF2Loader: Unknown shader uniform param type: ' + ptype );
} }
...@@ -781,7 +781,7 @@ THREE.GLTF2Loader = ( function () { ...@@ -781,7 +781,7 @@ THREE.GLTF2Loader = ( function () {
default: default:
throw new Error( "Unknown technique.states.enable: " + enable ); throw new Error( 'THREE.GLTF2Loader: Unknown technique.states.enable: ' + enable );
} }
...@@ -980,6 +980,8 @@ THREE.GLTF2Loader = ( function () { ...@@ -980,6 +980,8 @@ THREE.GLTF2Loader = ( function () {
transparent: params.transparent transparent: params.transparent
} ); } );
material.isGLTFSpecularGlossinessMaterial = true;
material.color = params.color; material.color = params.color;
material.map = params.map === undefined ? null : params.map; material.map = params.map === undefined ? null : params.map;
...@@ -1280,6 +1282,8 @@ THREE.GLTF2Loader = ( function () { ...@@ -1280,6 +1282,8 @@ THREE.GLTF2Loader = ( function () {
}; };
var INTERPOLATION = { var INTERPOLATION = {
CATMULLROMSPLINE: THREE.InterpolateSmooth,
CUBICSPLINE: THREE.InterpolateSmooth,
LINEAR: THREE.InterpolateLinear, LINEAR: THREE.InterpolateLinear,
STEP: THREE.InterpolateDiscrete STEP: THREE.InterpolateDiscrete
}; };
...@@ -1487,7 +1491,7 @@ THREE.GLTF2Loader = ( function () { ...@@ -1487,7 +1491,7 @@ THREE.GLTF2Loader = ( function () {
var param = params[ pname ]; var param = params[ pname ];
var semantic = param.semantic; var semantic = param.semantic;
var regEx = new RegExp( "\\b" + pname + "\\b", "g" ); var regEx = new RegExp( '\\b' + pname + '\\b', 'g' );
switch ( semantic ) { switch ( semantic ) {
...@@ -1612,7 +1616,7 @@ THREE.GLTF2Loader = ( function () { ...@@ -1612,7 +1616,7 @@ THREE.GLTF2Loader = ( function () {
for ( var i = 0; i < dependencies.length; i ++ ) { for ( var i = 0; i < dependencies.length; i ++ ) {
var dependency = dependencies[ i ]; var dependency = dependencies[ i ];
var fnName = "load" + dependency.charAt( 0 ).toUpperCase() + dependency.slice( 1 ); var fnName = 'load' + dependency.charAt( 0 ).toUpperCase() + dependency.slice( 1 );
var cached = this.cache.get( dependency ); var cached = this.cache.get( dependency );
...@@ -1649,9 +1653,9 @@ THREE.GLTF2Loader = ( function () { ...@@ -1649,9 +1653,9 @@ THREE.GLTF2Loader = ( function () {
// Fire the callback on complete // Fire the callback on complete
this._withDependencies( [ this._withDependencies( [
"scenes", 'scenes',
"cameras", 'cameras',
"animations" 'animations'
] ).then( function ( dependencies ) { ] ).then( function ( dependencies ) {
...@@ -1696,7 +1700,7 @@ THREE.GLTF2Loader = ( function () { ...@@ -1696,7 +1700,7 @@ THREE.GLTF2Loader = ( function () {
return this._withDependencies( [ return this._withDependencies( [
"bufferViews" 'bufferViews'
] ).then( function ( dependencies ) { ] ).then( function ( dependencies ) {
...@@ -1763,7 +1767,7 @@ THREE.GLTF2Loader = ( function () { ...@@ -1763,7 +1767,7 @@ THREE.GLTF2Loader = ( function () {
} else { } else {
console.warn( 'THREE.GLTF2Loader: ' + buffer.type + ' buffer type is not supported' ); console.warn( 'THREE.GLTF2Loader: %s buffer type is not supported.', buffer.type );
} }
...@@ -1777,7 +1781,7 @@ THREE.GLTF2Loader = ( function () { ...@@ -1777,7 +1781,7 @@ THREE.GLTF2Loader = ( function () {
return this._withDependencies( [ return this._withDependencies( [
"buffers" 'buffers'
] ).then( function ( dependencies ) { ] ).then( function ( dependencies ) {
...@@ -1802,7 +1806,7 @@ THREE.GLTF2Loader = ( function () { ...@@ -1802,7 +1806,7 @@ THREE.GLTF2Loader = ( function () {
return this._withDependencies( [ return this._withDependencies( [
"bufferViews" 'bufferViews'
] ).then( function ( dependencies ) { ] ).then( function ( dependencies ) {
...@@ -1850,7 +1854,7 @@ THREE.GLTF2Loader = ( function () { ...@@ -1850,7 +1854,7 @@ THREE.GLTF2Loader = ( function () {
return this._withDependencies( [ return this._withDependencies( [
"bufferViews" 'bufferViews'
] ).then( function ( dependencies ) { ] ).then( function ( dependencies ) {
...@@ -1900,7 +1904,7 @@ THREE.GLTF2Loader = ( function () { ...@@ -1900,7 +1904,7 @@ THREE.GLTF2Loader = ( function () {
if ( texture.internalFormat !== undefined && _texture.format !== WEBGL_TEXTURE_FORMATS[ texture.internalFormat ] ) { if ( texture.internalFormat !== undefined && _texture.format !== WEBGL_TEXTURE_FORMATS[ texture.internalFormat ] ) {
console.warn( 'THREE.GLTF2Loader: Three.js doesn\'t support texture internalFormat which is different from texture format. ' + console.warn( 'THREE.GLTF2Loader: Three.js does not support texture internalFormat which is different from texture format. ' +
'internalFormat will be forced to be the same value as format.' ); 'internalFormat will be forced to be the same value as format.' );
} }
...@@ -1911,7 +1915,7 @@ THREE.GLTF2Loader = ( function () { ...@@ -1911,7 +1915,7 @@ THREE.GLTF2Loader = ( function () {
var sampler = samplers[ texture.sampler ] || {}; var sampler = samplers[ texture.sampler ] || {};
_texture.magFilter = WEBGL_FILTERS[ sampler.magFilter ] || THREE.LinearFilter; _texture.magFilter = WEBGL_FILTERS[ sampler.magFilter ] || THREE.LinearFilter;
_texture.minFilter = WEBGL_FILTERS[ sampler.minFilter ] || THREE.NearestMipMapLinearFilter; _texture.minFilter = WEBGL_FILTERS[ sampler.minFilter ] || THREE.LinearMipMapLinearFilter;
_texture.wrapS = WEBGL_WRAPPINGS[ sampler.wrapS ] || THREE.RepeatWrapping; _texture.wrapS = WEBGL_WRAPPINGS[ sampler.wrapS ] || THREE.RepeatWrapping;
_texture.wrapT = WEBGL_WRAPPINGS[ sampler.wrapT ] || THREE.RepeatWrapping; _texture.wrapT = WEBGL_WRAPPINGS[ sampler.wrapT ] || THREE.RepeatWrapping;
...@@ -2082,6 +2086,10 @@ THREE.GLTF2Loader = ( function () { ...@@ -2082,6 +2086,10 @@ THREE.GLTF2Loader = ( function () {
if ( material.name !== undefined ) _material.name = material.name; if ( material.name !== undefined ) _material.name = material.name;
// Normal map textures use OpenGL conventions:
// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#materialnormaltexture
_material.normalScale.x = -1;
return _material; return _material;
} ); } );
...@@ -2096,8 +2104,8 @@ THREE.GLTF2Loader = ( function () { ...@@ -2096,8 +2104,8 @@ THREE.GLTF2Loader = ( function () {
return this._withDependencies( [ return this._withDependencies( [
"accessors", 'accessors',
"materials" 'materials'
] ).then( function ( dependencies ) { ] ).then( function ( dependencies ) {
...@@ -2191,7 +2199,7 @@ THREE.GLTF2Loader = ( function () { ...@@ -2191,7 +2199,7 @@ THREE.GLTF2Loader = ( function () {
&& geometry.attributes.uv2 === undefined && geometry.attributes.uv2 === undefined
&& geometry.attributes.uv !== undefined ) { && geometry.attributes.uv !== undefined ) {
console.log( 'GLTF2Loader: Duplicating UVs to support aoMap.' ); console.log( 'THREE.GLTF2Loader: Duplicating UVs to support aoMap.' );
geometry.addAttribute( 'uv2', new THREE.BufferAttribute( geometry.attributes.uv.array, 2 ) ); geometry.addAttribute( 'uv2', new THREE.BufferAttribute( geometry.attributes.uv.array, 2 ) );
} }
...@@ -2235,13 +2243,18 @@ THREE.GLTF2Loader = ( function () { ...@@ -2235,13 +2243,18 @@ THREE.GLTF2Loader = ( function () {
positionAttribute = dependencies.accessors[ target.POSITION ].clone(); positionAttribute = dependencies.accessors[ target.POSITION ].clone();
var position = geometry.attributes.position; var position = geometry.attributes.position;
for ( var j = 0, jl = positionAttribute.array.length; j < jl; j ++ ) { for ( var j = 0, jl = positionAttribute.count; j < jl; j ++ ) {
positionAttribute.array[ j ] += position.array[ j ]; positionAttribute.setXYZ(
j,
positionAttribute.getX( j ) + position.getX( j ),
positionAttribute.getY( j ) + position.getY( j ),
positionAttribute.getZ( j ) + position.getZ( j )
);
} }
} else { } else if ( geometry.attributes.position ) {
// Copying the original position not to affect the final position. // Copying the original position not to affect the final position.
// See the formula above. // See the formula above.
...@@ -2258,13 +2271,18 @@ THREE.GLTF2Loader = ( function () { ...@@ -2258,13 +2271,18 @@ THREE.GLTF2Loader = ( function () {
normalAttribute = dependencies.accessors[ target.NORMAL ].clone(); normalAttribute = dependencies.accessors[ target.NORMAL ].clone();
var normal = geometry.attributes.normal; var normal = geometry.attributes.normal;
for ( var j = 0, jl = normalAttribute.array.length; j < jl; j ++ ) { for ( var j = 0, jl = normalAttribute.count; j < jl; j ++ ) {
normalAttribute.array[ j ] += normal.array[ j ]; normalAttribute.setXYZ(
j,
normalAttribute.getX( j ) + normal.getX( j ),
normalAttribute.getY( j ) + normal.getY( j ),
normalAttribute.getZ( j ) + normal.getZ( j )
);
} }
} else { } else if ( geometry.attributes.normal ) {
normalAttribute = geometry.attributes.normal.clone(); normalAttribute = geometry.attributes.normal.clone();
...@@ -2275,11 +2293,19 @@ THREE.GLTF2Loader = ( function () { ...@@ -2275,11 +2293,19 @@ THREE.GLTF2Loader = ( function () {
} }
positionAttribute.name = attributeName; if ( positionAttribute ) {
normalAttribute.name = attributeName;
positionAttribute.name = attributeName;
morphAttributes.position.push( positionAttribute );
}
if ( normalAttribute ) {
morphAttributes.position.push( positionAttribute ); normalAttribute.name = attributeName;
morphAttributes.normal.push( normalAttribute ); morphAttributes.normal.push( normalAttribute );
}
} }
...@@ -2337,7 +2363,7 @@ THREE.GLTF2Loader = ( function () { ...@@ -2337,7 +2363,7 @@ THREE.GLTF2Loader = ( function () {
} else { } else {
throw new Error( 'Only triangular and line primitives are supported' ); throw new Error( 'THREE.GLTF2Loader: Only triangular and line primitives are supported.' );
} }
...@@ -2379,7 +2405,7 @@ THREE.GLTF2Loader = ( function () { ...@@ -2379,7 +2405,7 @@ THREE.GLTF2Loader = ( function () {
if ( !params ) { if ( !params ) {
console.warn( 'GLTF2Loader: Missing camera parameters.' ); console.warn( 'THREE.GLTF2Loader: Missing camera parameters.' );
return; return;
} }
...@@ -2412,7 +2438,7 @@ THREE.GLTF2Loader = ( function () { ...@@ -2412,7 +2438,7 @@ THREE.GLTF2Loader = ( function () {
return this._withDependencies( [ return this._withDependencies( [
"accessors" 'accessors'
] ).then( function ( dependencies ) { ] ).then( function ( dependencies ) {
...@@ -2437,8 +2463,8 @@ THREE.GLTF2Loader = ( function () { ...@@ -2437,8 +2463,8 @@ THREE.GLTF2Loader = ( function () {
return this._withDependencies( [ return this._withDependencies( [
"accessors", 'accessors',
"nodes" 'nodes'
] ).then( function ( dependencies ) { ] ).then( function ( dependencies ) {
...@@ -2492,6 +2518,13 @@ THREE.GLTF2Loader = ( function () { ...@@ -2492,6 +2518,13 @@ THREE.GLTF2Loader = ( function () {
} }
var targetName = node.name ? node.name : node.uuid; var targetName = node.name ? node.name : node.uuid;
if ( sampler.interpolation === 'CATMULLROMSPLINE' ) {
console.warn( 'THREE.GLTF2Loader: CATMULLROMSPLINE interpolation is not supported. Using CUBICSPLINE instead.' );
}
var interpolation = sampler.interpolation !== undefined ? INTERPOLATION[ sampler.interpolation ] : THREE.InterpolateLinear; var interpolation = sampler.interpolation !== undefined ? INTERPOLATION[ sampler.interpolation ] : THREE.InterpolateLinear;
var targetNames = []; var targetNames = [];
...@@ -2539,7 +2572,7 @@ THREE.GLTF2Loader = ( function () { ...@@ -2539,7 +2572,7 @@ THREE.GLTF2Loader = ( function () {
} }
var name = animation.name !== undefined ? animation.name : "animation_" + animationId; var name = animation.name !== undefined ? animation.name : 'animation_' + animationId;
return new THREE.AnimationClip( name, undefined, tracks ); return new THREE.AnimationClip( name, undefined, tracks );
...@@ -2617,9 +2650,9 @@ THREE.GLTF2Loader = ( function () { ...@@ -2617,9 +2650,9 @@ THREE.GLTF2Loader = ( function () {
return scope._withDependencies( [ return scope._withDependencies( [
"meshes", 'meshes',
"skins", 'skins',
"cameras" 'cameras'
] ).then( function ( dependencies ) { ] ).then( function ( dependencies ) {
...@@ -2635,7 +2668,7 @@ THREE.GLTF2Loader = ( function () { ...@@ -2635,7 +2668,7 @@ THREE.GLTF2Loader = ( function () {
} else if ( node.meshes !== undefined ) { } else if ( node.meshes !== undefined ) {
console.warn( 'GLTF2Loader: Legacy glTF file detected. Nodes may have no more than 1 mesh.' ); console.warn( 'THREE.GLTF2Loader: Legacy glTF file detected. Nodes may have no more than one mesh.' );
meshes = node.meshes; meshes = node.meshes;
...@@ -2650,7 +2683,7 @@ THREE.GLTF2Loader = ( function () { ...@@ -2650,7 +2683,7 @@ THREE.GLTF2Loader = ( function () {
if ( group === undefined ) { if ( group === undefined ) {
console.warn( 'GLTF2Loader: Couldn\'t find node "' + mesh + '".' ); console.warn( 'THREE.GLTF2Loader: Could not find node "' + mesh + '".' );
continue; continue;
} }
...@@ -2743,7 +2776,7 @@ THREE.GLTF2Loader = ( function () { ...@@ -2743,7 +2776,7 @@ THREE.GLTF2Loader = ( function () {
} else { } else {
console.warn( "WARNING: joint: '" + jointId + "' could not be found" ); console.warn( 'THREE.GLTF2Loader: Joint "%s" could not be found.', jointId );
} }
...@@ -2819,7 +2852,7 @@ THREE.GLTF2Loader = ( function () { ...@@ -2819,7 +2852,7 @@ THREE.GLTF2Loader = ( function () {
return this._withDependencies( [ return this._withDependencies( [
"nodes" 'nodes'
] ).then( function ( dependencies ) { ] ).then( function ( dependencies ) {
...@@ -2852,7 +2885,7 @@ THREE.GLTF2Loader = ( function () { ...@@ -2852,7 +2885,7 @@ THREE.GLTF2Loader = ( function () {
} }
// for Specular-Glossiness. // for Specular-Glossiness.
if ( child.material && child.material.type === 'ShaderMaterial' ) { if ( child.material && child.material.isGLTFSpecularGlossinessMaterial ) {
child.onBeforeRender = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].refreshUniforms; child.onBeforeRender = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].refreshUniforms;
......
...@@ -421,6 +421,12 @@ THREE.MTLLoader.MaterialCreator.prototype = { ...@@ -421,6 +421,12 @@ THREE.MTLLoader.MaterialCreator.prototype = {
break; break;
case 'norm':
setMapForType( "normalMap", value );
break;
case 'map_bump': case 'map_bump':
case 'bump': case 'bump':
......
...@@ -20,9 +20,10 @@ THREE.SSAOShader = { ...@@ -20,9 +20,10 @@ THREE.SSAOShader = {
"size": { value: new THREE.Vector2( 512, 512 ) }, "size": { value: new THREE.Vector2( 512, 512 ) },
"cameraNear": { value: 1 }, "cameraNear": { value: 1 },
"cameraFar": { value: 100 }, "cameraFar": { value: 100 },
"radius": { value: 32 },
"onlyAO": { value: 0 }, "onlyAO": { value: 0 },
"aoClamp": { value: 0.5 }, "aoClamp": { value: 0.25 },
"lumInfluence": { value: 0.5 } "lumInfluence": { value: 0.7 }
}, },
...@@ -48,6 +49,7 @@ THREE.SSAOShader = { ...@@ -48,6 +49,7 @@ THREE.SSAOShader = {
"uniform float logDepthBufFC;", "uniform float logDepthBufFC;",
"#endif", "#endif",
"uniform float radius;", // ao radius
"uniform bool onlyAO;", // use only ambient occlusion pass? "uniform bool onlyAO;", // use only ambient occlusion pass?
"uniform vec2 size;", // texture width, height "uniform vec2 size;", // texture width, height
...@@ -66,11 +68,10 @@ THREE.SSAOShader = { ...@@ -66,11 +68,10 @@ THREE.SSAOShader = {
// user variables // user variables
"const int samples = 8;", // ao sample count "const int samples = 64;", // ao sample count
"const float radius = 5.0;", // ao radius
"const bool useNoise = false;", // use noise instead of pattern for sample dithering "const bool useNoise = true;", // use noise instead of pattern for sample dithering
"const float noiseAmount = 0.0003;", // dithering amount "const float noiseAmount = 0.0004;", // dithering amount
"const float diffArea = 0.4;", // self-shadowing reduction "const float diffArea = 0.4;", // self-shadowing reduction
"const float gDisplace = 0.4;", // gauss bell center "const float gDisplace = 0.4;", // gauss bell center
...@@ -131,7 +132,7 @@ THREE.SSAOShader = { ...@@ -131,7 +132,7 @@ THREE.SSAOShader = {
"float compareDepths( const in float depth1, const in float depth2, inout int far ) {", "float compareDepths( const in float depth1, const in float depth2, inout int far ) {",
"float garea = 2.0;", // gauss bell width "float garea = 8.0;", // gauss bell width
"float diff = ( depth1 - depth2 ) * 100.0;", // depth difference (0-100) "float diff = ( depth1 - depth2 ) * 100.0;", // depth difference (0-100)
// reduce left bell width to avoid self-shadowing // reduce left bell width to avoid self-shadowing
...@@ -147,18 +148,17 @@ THREE.SSAOShader = { ...@@ -147,18 +148,17 @@ THREE.SSAOShader = {
"}", "}",
"float dd = diff - gDisplace;", "float dd = diff - gDisplace;",
"float gauss = pow( EULER, -2.0 * dd * dd / ( garea * garea ) );", "float gauss = pow( EULER, -2.0 * ( dd * dd ) / ( garea * garea ) );",
"return gauss;", "return gauss;",
"}", "}",
"float calcAO( float depth, float dw, float dh ) {", "float calcAO( float depth, float dw, float dh ) {",
"float dd = radius - depth * radius;",
"vec2 vv = vec2( dw, dh );", "vec2 vv = vec2( dw, dh );",
"vec2 coord1 = vUv + dd * vv;", "vec2 coord1 = vUv + radius * vv;",
"vec2 coord2 = vUv - dd * vv;", "vec2 coord2 = vUv - radius * vv;",
"float temp1 = 0.0;", "float temp1 = 0.0;",
"float temp2 = 0.0;", "float temp2 = 0.0;",
...@@ -186,14 +186,14 @@ THREE.SSAOShader = { ...@@ -186,14 +186,14 @@ THREE.SSAOShader = {
"float tt = clamp( depth, aoClamp, 1.0 );", "float tt = clamp( depth, aoClamp, 1.0 );",
"float w = ( 1.0 / size.x ) / tt + ( noise.x * ( 1.0 - noise.x ) );", "float w = ( 1.0 / size.x ) / tt + ( noise.x * ( 1.0 - noise.x ) );",
"float h = ( 1.0 / size.y ) / tt + ( noise.y * ( 1.0 - noise.y ) );", "float h = ( 1.0 / size.y ) / tt + ( noise.y * ( 1.0 - noise.y ) );",
"float ao = 0.0;", "float ao = 0.0;",
"float dz = 1.0 / float( samples );", "float dz = 1.0 / float( samples );",
"float z = 1.0 - dz / 2.0;",
"float l = 0.0;", "float l = 0.0;",
"float z = 1.0 - dz / 2.0;",
"for ( int i = 0; i <= samples; i ++ ) {", "for ( int i = 0; i <= samples; i ++ ) {",
......
...@@ -67,8 +67,7 @@ Spiral sampling http://web.archive.org/web/20120421191837/http://www.cgafaq.info ...@@ -67,8 +67,7 @@ Spiral sampling http://web.archive.org/web/20120421191837/http://www.cgafaq.info
var depthMaterial, effectComposer, depthRenderTarget; var depthMaterial, effectComposer, depthRenderTarget;
var ssaoPass; var ssaoPass;
var group; var group;
var depthScale = 1.0; var postprocessing = { enabled: true, ao_only: false, radius: 32 };
var postprocessing = { enabled : true, renderMode: 0 }; // renderMode: 0('framebuffer'), 1('onlyAO')
init(); init();
animate(); animate();
...@@ -79,7 +78,6 @@ Spiral sampling http://web.archive.org/web/20120421191837/http://www.cgafaq.info ...@@ -79,7 +78,6 @@ Spiral sampling http://web.archive.org/web/20120421191837/http://www.cgafaq.info
document.body.appendChild( container ); document.body.appendChild( container );
renderer = new THREE.WebGLRenderer( { antialias: false } ); renderer = new THREE.WebGLRenderer( { antialias: false } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight ); renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement ); document.body.appendChild( renderer.domElement );
...@@ -92,7 +90,7 @@ Spiral sampling http://web.archive.org/web/20120421191837/http://www.cgafaq.info ...@@ -92,7 +90,7 @@ Spiral sampling http://web.archive.org/web/20120421191837/http://www.cgafaq.info
group = new THREE.Object3D(); group = new THREE.Object3D();
scene.add( group ); scene.add( group );
var geometry = new THREE.IcosahedronGeometry( 5, 1 ); var geometry = new THREE.BoxGeometry( 10, 10, 10 );
for ( var i = 0; i < 200; i ++ ) { for ( var i = 0; i < 200; i ++ ) {
var material = new THREE.MeshBasicMaterial(); var material = new THREE.MeshBasicMaterial();
...@@ -121,30 +119,23 @@ Spiral sampling http://web.archive.org/web/20120421191837/http://www.cgafaq.info ...@@ -121,30 +119,23 @@ Spiral sampling http://web.archive.org/web/20120421191837/http://www.cgafaq.info
// Init gui // Init gui
var gui = new dat.GUI(); var gui = new dat.GUI();
gui.add( postprocessing, "enabled" ).onChange(); gui.add( postprocessing, "enabled" );
gui.add( postprocessing, "renderMode", { framebuffer: 0, onlyAO: 1 } ).onChange( renderModeChange ).listen(); gui.add( postprocessing, "ao_only", false ).onChange( renderModeChange );
gui.add( postprocessing, "radius" ).min( 0 ).max( 64 ).onChange( radiusChange );
window.addEventListener( 'resize', onWindowResize, false ); window.addEventListener( 'resize', onWindowResize, false );
} }
function renderModeChange( value ) { function radiusChange( value ) {
if ( value == 0 ) {
// framebuffer
ssaoPass.uniforms[ 'onlyAO' ].value = false;
} else if ( value == 1 ) {
// onlyAO ssaoPass.uniforms[ 'radius' ].value = value;
ssaoPass.uniforms[ 'onlyAO' ].value = true;
} else { }
console.error( "Not define renderModeChange type: " + value ); function renderModeChange( value ) {
} ssaoPass.uniforms[ 'onlyAO' ].value = value;
} }
...@@ -190,9 +181,6 @@ Spiral sampling http://web.archive.org/web/20120421191837/http://www.cgafaq.info ...@@ -190,9 +181,6 @@ Spiral sampling http://web.archive.org/web/20120421191837/http://www.cgafaq.info
ssaoPass.uniforms[ 'size' ].value.set( window.innerWidth, window.innerHeight ); ssaoPass.uniforms[ 'size' ].value.set( window.innerWidth, window.innerHeight );
ssaoPass.uniforms[ 'cameraNear' ].value = camera.near; ssaoPass.uniforms[ 'cameraNear' ].value = camera.near;
ssaoPass.uniforms[ 'cameraFar' ].value = camera.far; ssaoPass.uniforms[ 'cameraFar' ].value = camera.far;
ssaoPass.uniforms[ 'onlyAO' ].value = ( postprocessing.renderMode == 1 );
ssaoPass.uniforms[ 'aoClamp' ].value = 0.3;
ssaoPass.uniforms[ 'lumInfluence' ].value = 0.5;
// Add pass to effect composer // Add pass to effect composer
effectComposer = new THREE.EffectComposer( renderer ); effectComposer = new THREE.EffectComposer( renderer );
......
...@@ -4,8 +4,8 @@ ...@@ -4,8 +4,8 @@
<title>three.js webvr - cubes</title> <title>three.js webvr - cubes</title>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<!-- Origin Trial Token, feature = WebVR (For Chrome M59+), origin = https://threejs.org, expires = 2017-07-28 --> <!-- Origin Trial Token, feature = WebVR (For Chrome M59+), origin = https://threejs.org, expires = 2017-09-03 -->
<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M59+)" data-expires="2017-07-28" content="Ave6CPNUgSwHb3vCbyd55P/R7pfkwNniUJsYfSoUqI+l1X1BIOt6HfriVP0g2hmaG7Pp3qaUXuXdZeqGBmoMKg8AAABNeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMSIsImV4cGlyeSI6MTUwMTI2NzQwNX0="> <meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M59+)" data-expires="2017-09-03" content="Aqj+6XPnxHoSxQj/CDjGXhzrVFeP12/Pgvj7rfqFqVzodYX0ZXJNHTJIvCVExQfvip+Zq9GES+SOQ/zJlpceZgcAAABNeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMSIsImV4cGlyeSI6MTUwNDQ2NDIwNn0=">
<style> <style>
body { body {
font-family: Monospace; font-family: Monospace;
......
...@@ -4,8 +4,8 @@ ...@@ -4,8 +4,8 @@
<title>three.js webvr - daydream</title> <title>three.js webvr - daydream</title>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<!-- Origin Trial Token, feature = WebVR (For Chrome M59+), origin = https://threejs.org, expires = 2017-07-28 --> <!-- Origin Trial Token, feature = WebVR (For Chrome M59+), origin = https://threejs.org, expires = 2017-09-03 -->
<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M59+)" data-expires="2017-07-28" content="Ave6CPNUgSwHb3vCbyd55P/R7pfkwNniUJsYfSoUqI+l1X1BIOt6HfriVP0g2hmaG7Pp3qaUXuXdZeqGBmoMKg8AAABNeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMSIsImV4cGlyeSI6MTUwMTI2NzQwNX0="> <meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M59+)" data-expires="2017-09-03" content="Aqj+6XPnxHoSxQj/CDjGXhzrVFeP12/Pgvj7rfqFqVzodYX0ZXJNHTJIvCVExQfvip+Zq9GES+SOQ/zJlpceZgcAAABNeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMSIsImV4cGlyeSI6MTUwNDQ2NDIwNn0=">
<style> <style>
body { body {
font-family: Monospace; font-family: Monospace;
......
...@@ -4,8 +4,8 @@ ...@@ -4,8 +4,8 @@
<title>three.js webvr - panorama</title> <title>three.js webvr - panorama</title>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<!-- Origin Trial Token, feature = WebVR (For Chrome M59+), origin = https://threejs.org, expires = 2017-07-28 --> <!-- Origin Trial Token, feature = WebVR (For Chrome M59+), origin = https://threejs.org, expires = 2017-09-03 -->
<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M59+)" data-expires="2017-07-28" content="Ave6CPNUgSwHb3vCbyd55P/R7pfkwNniUJsYfSoUqI+l1X1BIOt6HfriVP0g2hmaG7Pp3qaUXuXdZeqGBmoMKg8AAABNeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMSIsImV4cGlyeSI6MTUwMTI2NzQwNX0="> <meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M59+)" data-expires="2017-09-03" content="Aqj+6XPnxHoSxQj/CDjGXhzrVFeP12/Pgvj7rfqFqVzodYX0ZXJNHTJIvCVExQfvip+Zq9GES+SOQ/zJlpceZgcAAABNeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMSIsImV4cGlyeSI6MTUwNDQ2NDIwNn0=">
<style> <style>
html, body { html, body {
background-color: #000; background-color: #000;
......
...@@ -4,8 +4,8 @@ ...@@ -4,8 +4,8 @@
<title>three.js webvr - roller coaster</title> <title>three.js webvr - roller coaster</title>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<!-- Origin Trial Token, feature = WebVR (For Chrome M59+), origin = https://threejs.org, expires = 2017-07-28 --> <!-- Origin Trial Token, feature = WebVR (For Chrome M59+), origin = https://threejs.org, expires = 2017-09-03 -->
<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M59+)" data-expires="2017-07-28" content="Ave6CPNUgSwHb3vCbyd55P/R7pfkwNniUJsYfSoUqI+l1X1BIOt6HfriVP0g2hmaG7Pp3qaUXuXdZeqGBmoMKg8AAABNeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMSIsImV4cGlyeSI6MTUwMTI2NzQwNX0="> <meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M59+)" data-expires="2017-09-03" content="Aqj+6XPnxHoSxQj/CDjGXhzrVFeP12/Pgvj7rfqFqVzodYX0ZXJNHTJIvCVExQfvip+Zq9GES+SOQ/zJlpceZgcAAABNeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMSIsImV4cGlyeSI6MTUwNDQ2NDIwNn0=">
<style> <style>
body { body {
margin: 0px; margin: 0px;
......
...@@ -4,8 +4,8 @@ ...@@ -4,8 +4,8 @@
<title>three.js webvr - sandbox</title> <title>three.js webvr - sandbox</title>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<!-- Origin Trial Token, feature = WebVR (For Chrome M59+), origin = https://threejs.org, expires = 2017-07-28 --> <!-- Origin Trial Token, feature = WebVR (For Chrome M59+), origin = https://threejs.org, expires = 2017-09-03 -->
<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M59+)" data-expires="2017-07-28" content="Ave6CPNUgSwHb3vCbyd55P/R7pfkwNniUJsYfSoUqI+l1X1BIOt6HfriVP0g2hmaG7Pp3qaUXuXdZeqGBmoMKg8AAABNeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMSIsImV4cGlyeSI6MTUwMTI2NzQwNX0="> <meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M59+)" data-expires="2017-09-03" content="Aqj+6XPnxHoSxQj/CDjGXhzrVFeP12/Pgvj7rfqFqVzodYX0ZXJNHTJIvCVExQfvip+Zq9GES+SOQ/zJlpceZgcAAABNeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMSIsImV4cGlyeSI6MTUwNDQ2NDIwNn0=">
<style> <style>
body { body {
margin: 0px; margin: 0px;
......
...@@ -4,8 +4,8 @@ ...@@ -4,8 +4,8 @@
<title>three.js webvr - video</title> <title>three.js webvr - video</title>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<!-- Origin Trial Token, feature = WebVR (For Chrome M59+), origin = https://threejs.org, expires = 2017-07-28 --> <!-- Origin Trial Token, feature = WebVR (For Chrome M59+), origin = https://threejs.org, expires = 2017-09-03 -->
<meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M59+)" data-expires="2017-07-28" content="Ave6CPNUgSwHb3vCbyd55P/R7pfkwNniUJsYfSoUqI+l1X1BIOt6HfriVP0g2hmaG7Pp3qaUXuXdZeqGBmoMKg8AAABNeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMSIsImV4cGlyeSI6MTUwMTI2NzQwNX0="> <meta http-equiv="origin-trial" data-feature="WebVR (For Chrome M59+)" data-expires="2017-09-03" content="Aqj+6XPnxHoSxQj/CDjGXhzrVFeP12/Pgvj7rfqFqVzodYX0ZXJNHTJIvCVExQfvip+Zq9GES+SOQ/zJlpceZgcAAABNeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJWUjEuMSIsImV4cGlyeSI6MTUwNDQ2NDIwNn0=">
<style> <style>
body { body {
font-family: Monospace; font-family: Monospace;
......
...@@ -62,7 +62,7 @@ Object.assign( KeyframeTrack, { ...@@ -62,7 +62,7 @@ Object.assign( KeyframeTrack, {
} else { } else {
// by default, we asssume a constructor compatible with the base // by default, we assume a constructor compatible with the base
return new trackType( return new trackType(
json.name, json.times, json.values, json.interpolation ); json.name, json.times, json.values, json.interpolation );
......
...@@ -7,6 +7,8 @@ import { Vector3 } from './Vector3'; ...@@ -7,6 +7,8 @@ import { Vector3 } from './Vector3';
function Plane( normal, constant ) { function Plane( normal, constant ) {
// normal is assumed to be normalized
this.normal = ( normal !== undefined ) ? normal : new Vector3( 1, 0, 0 ); this.normal = ( normal !== undefined ) ? normal : new Vector3( 1, 0, 0 );
this.constant = ( constant !== undefined ) ? constant : 0; this.constant = ( constant !== undefined ) ? constant : 0;
......
...@@ -107,15 +107,7 @@ Object.assign( Sphere.prototype, { ...@@ -107,15 +107,7 @@ Object.assign( Sphere.prototype, {
intersectsPlane: function ( plane ) { intersectsPlane: function ( plane ) {
// We use the following equation to compute the signed distance from return Math.abs( plane.distanceToPoint( this.center ) ) <= this.radius;
// the center of the sphere to the plane.
//
// distance = q * n - d
//
// If this distance is greater than the radius of the sphere,
// then there is no intersection.
return Math.abs( this.center.dot( plane.normal ) - plane.constant ) <= this.radius;
}, },
......
...@@ -12,6 +12,7 @@ import { WebGLShadowMap } from './webgl/WebGLShadowMap'; ...@@ -12,6 +12,7 @@ import { WebGLShadowMap } from './webgl/WebGLShadowMap';
import { WebGLAttributes } from './webgl/WebGLAttributes'; import { WebGLAttributes } from './webgl/WebGLAttributes';
import { WebGLBackground } from './webgl/WebGLBackground'; import { WebGLBackground } from './webgl/WebGLBackground';
import { WebGLRenderLists } from './webgl/WebGLRenderLists'; import { WebGLRenderLists } from './webgl/WebGLRenderLists';
import { WebGLMorphtargets } from './webgl/WebGLMorphtargets';
import { WebGLIndexedBufferRenderer } from './webgl/WebGLIndexedBufferRenderer'; import { WebGLIndexedBufferRenderer } from './webgl/WebGLIndexedBufferRenderer';
import { WebGLBufferRenderer } from './webgl/WebGLBufferRenderer'; import { WebGLBufferRenderer } from './webgl/WebGLBufferRenderer';
import { WebGLGeometries } from './webgl/WebGLGeometries'; import { WebGLGeometries } from './webgl/WebGLGeometries';
...@@ -60,8 +61,6 @@ function WebGLRenderer( parameters ) { ...@@ -60,8 +61,6 @@ function WebGLRenderer( parameters ) {
var currentRenderList = null; var currentRenderList = null;
var morphInfluences = new Float32Array( 8 );
var spritesArray = []; var spritesArray = [];
var flaresArray = []; var flaresArray = [];
...@@ -245,7 +244,7 @@ function WebGLRenderer( parameters ) { ...@@ -245,7 +244,7 @@ function WebGLRenderer( parameters ) {
var properties, textures, attributes, geometries, objects, lights; var properties, textures, attributes, geometries, objects, lights;
var programCache, renderLists; var programCache, renderLists;
var background, bufferRenderer, indexedBufferRenderer; var background, morphtargets, bufferRenderer, indexedBufferRenderer;
var flareRenderer, spriteRenderer; var flareRenderer, spriteRenderer;
function initGLContext() { function initGLContext() {
...@@ -276,6 +275,7 @@ function WebGLRenderer( parameters ) { ...@@ -276,6 +275,7 @@ function WebGLRenderer( parameters ) {
attributes = new WebGLAttributes( _gl ); attributes = new WebGLAttributes( _gl );
geometries = new WebGLGeometries( _gl, attributes, _infoMemory ); geometries = new WebGLGeometries( _gl, attributes, _infoMemory );
objects = new WebGLObjects( geometries, _infoRender ); objects = new WebGLObjects( geometries, _infoRender );
morphtargets = new WebGLMorphtargets( _gl );
programCache = new WebGLPrograms( _this, extensions, capabilities ); programCache = new WebGLPrograms( _this, extensions, capabilities );
lights = new WebGLLights(); lights = new WebGLLights();
renderLists = new WebGLRenderLists(); renderLists = new WebGLRenderLists();
...@@ -657,12 +657,6 @@ function WebGLRenderer( parameters ) { ...@@ -657,12 +657,6 @@ function WebGLRenderer( parameters ) {
}; };
function absNumericalSort( a, b ) {
return Math.abs( b[ 0 ] ) - Math.abs( a[ 0 ] );
}
this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) { this.renderBufferDirect = function ( camera, fog, geometry, material, object, group ) {
state.setMaterial( material ); state.setMaterial( material );
...@@ -679,61 +673,9 @@ function WebGLRenderer( parameters ) { ...@@ -679,61 +673,9 @@ function WebGLRenderer( parameters ) {
} }
// morph targets if ( object.morphTargetInfluences ) {
var morphTargetInfluences = object.morphTargetInfluences;
if ( morphTargetInfluences !== undefined ) {
// TODO Remove allocations
var activeInfluences = [];
for ( var i = 0, l = morphTargetInfluences.length; i < l; i ++ ) {
var influence = morphTargetInfluences[ i ];
activeInfluences.push( [ influence, i ] );
}
activeInfluences.sort( absNumericalSort );
if ( activeInfluences.length > 8 ) {
activeInfluences.length = 8;
}
var morphAttributes = geometry.morphAttributes;
for ( var i = 0, l = activeInfluences.length; i < l; i ++ ) {
var influence = activeInfluences[ i ];
morphInfluences[ i ] = influence[ 0 ];
if ( influence[ 0 ] !== 0 ) {
var index = influence[ 1 ];
if ( material.morphTargets === true && morphAttributes.position ) geometry.addAttribute( 'morphTarget' + i, morphAttributes.position[ index ] );
if ( material.morphNormals === true && morphAttributes.normal ) geometry.addAttribute( 'morphNormal' + i, morphAttributes.normal[ index ] );
} else {
if ( material.morphTargets === true ) geometry.removeAttribute( 'morphTarget' + i );
if ( material.morphNormals === true ) geometry.removeAttribute( 'morphNormal' + i );
}
}
for ( var i = activeInfluences.length, il = morphInfluences.length; i < il; i ++ ) {
morphInfluences[ i ] = 0.0; morphtargets.update( object, geometry, material, program );
}
program.getUniforms().setValue( _gl, 'morphTargetInfluences', morphInfluences );
updateBuffers = true; updateBuffers = true;
...@@ -1121,8 +1063,6 @@ function WebGLRenderer( parameters ) { ...@@ -1121,8 +1063,6 @@ function WebGLRenderer( parameters ) {
projectObject( scene, camera, _this.sortObjects ); projectObject( scene, camera, _this.sortObjects );
currentRenderList.finish();
if ( _this.sortObjects === true ) { if ( _this.sortObjects === true ) {
currentRenderList.sort(); currentRenderList.sort();
...@@ -1904,7 +1844,11 @@ function WebGLRenderer( parameters ) { ...@@ -1904,7 +1844,11 @@ function WebGLRenderer( parameters ) {
uniforms.opacity.value = material.opacity; uniforms.opacity.value = material.opacity;
uniforms.diffuse.value = material.color; if ( material.color ) {
uniforms.diffuse.value = material.color;
}
if ( material.emissive ) { if ( material.emissive ) {
...@@ -1912,9 +1856,38 @@ function WebGLRenderer( parameters ) { ...@@ -1912,9 +1856,38 @@ function WebGLRenderer( parameters ) {
} }
uniforms.map.value = material.map; if ( material.map ) {
uniforms.specularMap.value = material.specularMap;
uniforms.alphaMap.value = material.alphaMap; uniforms.map.value = material.map;
}
if ( material.alphaMap ) {
uniforms.alphaMap.value = material.alphaMap;
}
if ( material.specularMap ) {
uniforms.specularMap.value = material.specularMap;
}
if ( material.envMap ) {
uniforms.envMap.value = material.envMap;
// don't flip CubeTexture envMaps, flip everything else:
// WebGLRenderTargetCube will be flipped for backwards compatibility
// WebGLRenderTargetCube.texture will be flipped because it's a Texture and NOT a CubeTexture
// this check must be handled differently, or removed entirely, if WebGLRenderTargetCube uses a CubeTexture in the future
uniforms.flipEnvMap.value = ( ! ( material.envMap && material.envMap.isCubeTexture ) ) ? 1 : - 1;
uniforms.reflectivity.value = material.reflectivity;
uniforms.refractionRatio.value = material.refractionRatio;
}
if ( material.lightMap ) { if ( material.lightMap ) {
...@@ -1994,17 +1967,6 @@ function WebGLRenderer( parameters ) { ...@@ -1994,17 +1967,6 @@ function WebGLRenderer( parameters ) {
} }
uniforms.envMap.value = material.envMap;
// don't flip CubeTexture envMaps, flip everything else:
// WebGLRenderTargetCube will be flipped for backwards compatibility
// WebGLRenderTargetCube.texture will be flipped because it's a Texture and NOT a CubeTexture
// this check must be handled differently, or removed entirely, if WebGLRenderTargetCube uses a CubeTexture in the future
uniforms.flipEnvMap.value = ( ! ( material.envMap && material.envMap.isCubeTexture ) ) ? 1 : - 1;
uniforms.reflectivity.value = material.reflectivity;
uniforms.refractionRatio.value = material.refractionRatio;
} }
function refreshUniformsLine( uniforms, material ) { function refreshUniformsLine( uniforms, material ) {
......
...@@ -16,6 +16,8 @@ var ShaderLib = { ...@@ -16,6 +16,8 @@ var ShaderLib = {
uniforms: UniformsUtils.merge( [ uniforms: UniformsUtils.merge( [
UniformsLib.common, UniformsLib.common,
UniformsLib.specularmap,
UniformsLib.envmap,
UniformsLib.aomap, UniformsLib.aomap,
UniformsLib.lightmap, UniformsLib.lightmap,
UniformsLib.fog UniformsLib.fog
...@@ -30,6 +32,8 @@ var ShaderLib = { ...@@ -30,6 +32,8 @@ var ShaderLib = {
uniforms: UniformsUtils.merge( [ uniforms: UniformsUtils.merge( [
UniformsLib.common, UniformsLib.common,
UniformsLib.specularmap,
UniformsLib.envmap,
UniformsLib.aomap, UniformsLib.aomap,
UniformsLib.lightmap, UniformsLib.lightmap,
UniformsLib.emissivemap, UniformsLib.emissivemap,
...@@ -49,6 +53,8 @@ var ShaderLib = { ...@@ -49,6 +53,8 @@ var ShaderLib = {
uniforms: UniformsUtils.merge( [ uniforms: UniformsUtils.merge( [
UniformsLib.common, UniformsLib.common,
UniformsLib.specularmap,
UniformsLib.envmap,
UniformsLib.aomap, UniformsLib.aomap,
UniformsLib.lightmap, UniformsLib.lightmap,
UniformsLib.emissivemap, UniformsLib.emissivemap,
...@@ -74,6 +80,7 @@ var ShaderLib = { ...@@ -74,6 +80,7 @@ var ShaderLib = {
uniforms: UniformsUtils.merge( [ uniforms: UniformsUtils.merge( [
UniformsLib.common, UniformsLib.common,
UniformsLib.envmap,
UniformsLib.aomap, UniformsLib.aomap,
UniformsLib.lightmap, UniformsLib.lightmap,
UniformsLib.emissivemap, UniformsLib.emissivemap,
...@@ -172,15 +179,10 @@ var ShaderLib = { ...@@ -172,15 +179,10 @@ var ShaderLib = {
}, },
/* -------------------------------------------------------------------------
// Cube map shader
------------------------------------------------------------------------- */
equirect: { equirect: {
uniforms: { uniforms: {
tEquirect: { value: null }, tEquirect: { value: null },
tFlip: { value: - 1 }
}, },
vertexShader: ShaderChunk.equirect_vert, vertexShader: ShaderChunk.equirect_vert,
......
...@@ -4,8 +4,6 @@ uniform float opacity; ...@@ -4,8 +4,6 @@ uniform float opacity;
varying vec3 vWorldPosition; varying vec3 vWorldPosition;
#include <common>
void main() { void main() {
gl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) ); gl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );
......
...@@ -5,8 +5,6 @@ varying vec3 vWorldPosition; ...@@ -5,8 +5,6 @@ varying vec3 vWorldPosition;
void main() { void main() {
vWorldPosition = transformDirection( position, modelMatrix ); vWorldPosition = transformDirection( position, modelMatrix );
gl_Position = projectionMatrix * vec4( normalMatrix * position, 1.0 );
#include <begin_vertex>
#include <project_vertex>
} }
uniform sampler2D tEquirect; uniform sampler2D tEquirect;
uniform float tFlip;
varying vec3 vWorldPosition; varying vec3 vWorldPosition;
...@@ -7,11 +6,14 @@ varying vec3 vWorldPosition; ...@@ -7,11 +6,14 @@ varying vec3 vWorldPosition;
void main() { void main() {
// gl_FragColor = textureCube( tCube, vec3( tFlip * vWorldPosition.x, vWorldPosition.yz ) );
vec3 direction = normalize( vWorldPosition ); vec3 direction = normalize( vWorldPosition );
vec2 sampleUV; vec2 sampleUV;
sampleUV.y = saturate( tFlip * direction.y * -0.5 + 0.5 );
sampleUV.y = asin( clamp( direction.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;
sampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5; sampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;
gl_FragColor = texture2D( tEquirect, sampleUV ); gl_FragColor = texture2D( tEquirect, sampleUV );
} }
...@@ -17,9 +17,18 @@ var UniformsLib = { ...@@ -17,9 +17,18 @@ var UniformsLib = {
map: { value: null }, map: { value: null },
offsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) }, offsetRepeat: { value: new Vector4( 0, 0, 1, 1 ) },
specularMap: { value: null },
alphaMap: { value: null }, alphaMap: { value: null },
},
specularmap: {
specularMap: { value: null },
},
envmap: {
envMap: { value: null }, envMap: { value: null },
flipEnvMap: { value: - 1 }, flipEnvMap: { value: - 1 },
reflectivity: { value: 1.0 }, reflectivity: { value: 1.0 },
......
...@@ -19,7 +19,7 @@ function WebGLBackground( renderer, state, geometries, premultipliedAlpha ) { ...@@ -19,7 +19,7 @@ function WebGLBackground( renderer, state, geometries, premultipliedAlpha ) {
var clearAlpha = 0; var clearAlpha = 0;
var planeCamera, planeMesh; var planeCamera, planeMesh;
var boxCamera, boxMesh; var boxMesh;
function render( scene, camera, forceClear ) { function render( scene, camera, forceClear ) {
...@@ -44,9 +44,7 @@ function WebGLBackground( renderer, state, geometries, premultipliedAlpha ) { ...@@ -44,9 +44,7 @@ function WebGLBackground( renderer, state, geometries, premultipliedAlpha ) {
if ( background && background.isCubeTexture ) { if ( background && background.isCubeTexture ) {
if ( boxCamera === undefined ) { if ( boxMesh === undefined ) {
boxCamera = new PerspectiveCamera();
boxMesh = new Mesh( boxMesh = new Mesh(
new BoxBufferGeometry( 5, 5, 5 ), new BoxBufferGeometry( 5, 5, 5 ),
...@@ -63,17 +61,13 @@ function WebGLBackground( renderer, state, geometries, premultipliedAlpha ) { ...@@ -63,17 +61,13 @@ function WebGLBackground( renderer, state, geometries, premultipliedAlpha ) {
} }
boxCamera.projectionMatrix.copy( camera.projectionMatrix );
boxCamera.matrixWorld.extractRotation( camera.matrixWorld );
boxCamera.matrixWorldInverse.getInverse( boxCamera.matrixWorld );
boxMesh.material.uniforms[ "tCube" ].value = background; boxMesh.material.uniforms[ "tCube" ].value = background;
boxMesh.modelViewMatrix.multiplyMatrices( boxCamera.matrixWorldInverse, boxMesh.matrixWorld ); boxMesh.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, boxMesh.matrixWorld );
boxMesh.normalMatrix.getNormalMatrix( boxMesh.modelViewMatrix );
geometries.update( boxMesh.geometry ); geometries.update( boxMesh.geometry );
renderer.renderBufferDirect( boxCamera, null, boxMesh.geometry, boxMesh.material, boxMesh, null ); renderer.renderBufferDirect( camera, null, boxMesh.geometry, boxMesh.material, boxMesh, null );
} else if ( background && background.isTexture ) { } else if ( background && background.isTexture ) {
......
/**
* @author mrdoob / http://mrdoob.com/
*/
function absNumericalSort( a, b ) {
return Math.abs( b[ 1 ] ) - Math.abs( a[ 1 ] );
}
function WebGLMorphtargets( gl ) {
var influencesList = {};
var morphInfluences = new Float32Array( 8 );
function update( object, geometry, material, program ) {
var objectInfluences = object.morphTargetInfluences;
var length = objectInfluences.length;
var influences = influencesList[ geometry.id ];
if ( influences === undefined ) {
// initialise list
influences = [];
for ( var i = 0; i < length; i ++ ) {
influences[ i ] = [ i, 0 ];
}
influencesList[ geometry.id ] = influences;
}
var morphTargets = material.morphTargets && geometry.morphAttributes.position;
var morphNormals = material.morphNormals && geometry.morphAttributes.normal;
// Remove current morphAttributes
for ( var i = 0; i < length; i ++ ) {
var influence = influences[ i ];
if ( influence[ 1 ] !== 0 ) {
if ( morphTargets ) geometry.removeAttribute( 'morphTarget' + i );
if ( morphNormals ) geometry.removeAttribute( 'morphNormal' + i );
}
}
// Collect influences
for ( var i = 0; i < length; i ++ ) {
var influence = influences[ i ];
influence[ 0 ] = i;
influence[ 1 ] = objectInfluences[ i ];
}
influences.sort( absNumericalSort );
// Add morphAttributes
for ( var i = 0; i < 8; i ++ ) {
var influence = influences[ i ];
if ( influence ) {
var index = influence[ 0 ];
var value = influence[ 1 ];
if ( value ) {
if ( morphTargets ) geometry.addAttribute( 'morphTarget' + i, morphTargets[ index ] );
if ( morphNormals ) geometry.addAttribute( 'morphNormal' + i, morphNormals[ index ] );
morphInfluences[ i ] = value;
continue;
}
}
morphInfluences[ i ] = 0;
}
program.getUniforms().setValue( gl, 'morphTargetInfluences', morphInfluences );
}
return {
update: update
}
}
export { WebGLMorphtargets };
...@@ -48,43 +48,42 @@ function reversePainterSortStable( a, b ) { ...@@ -48,43 +48,42 @@ function reversePainterSortStable( a, b ) {
function WebGLRenderList() { function WebGLRenderList() {
var opaque = []; var renderItems = [];
var opaqueLastIndex = - 1; var renderItemsIndex = 0;
var opaque = [];
var transparent = []; var transparent = [];
var transparentLastIndex = - 1;
function init() { function init() {
opaqueLastIndex = - 1; renderItemsIndex = 0;
transparentLastIndex = - 1;
opaque.length = 0;
transparent.length = 0;
} }
function push( object, geometry, material, z, group ) { function push( object, geometry, material, z, group ) {
var array, index; var renderItem = renderItems[ renderItemsIndex ];
// allocate the next position in the appropriate array if ( renderItem === undefined ) {
if ( material.transparent ) { renderItem = {
id: object.id,
object: object,
geometry: geometry,
material: material,
program: material.program,
renderOrder: object.renderOrder,
z: z,
group: group
};
array = transparent; renderItems[ renderItemsIndex ] = renderItem;
index = ++ transparentLastIndex;
} else { } else {
array = opaque;
index = ++ opaqueLastIndex;
}
// recycle existing render item or grow the array
var renderItem = array[ index ];
if ( renderItem ) {
renderItem.id = object.id; renderItem.id = object.id;
renderItem.object = object; renderItem.object = object;
renderItem.geometry = geometry; renderItem.geometry = geometry;
...@@ -94,37 +93,18 @@ function WebGLRenderList() { ...@@ -94,37 +93,18 @@ function WebGLRenderList() {
renderItem.z = z; renderItem.z = z;
renderItem.group = group; renderItem.group = group;
} else {
renderItem = {
id: object.id,
object: object,
geometry: geometry,
material: material,
program: material.program,
renderOrder: object.renderOrder,
z: z,
group: group
};
// assert( index === array.length );
array.push( renderItem );
} }
} ( material.transparent === true ? transparent : opaque ).push( renderItem );
function finish() {
opaque.length = opaqueLastIndex + 1; renderItemsIndex ++;
transparent.length = transparentLastIndex + 1;
} }
function sort() { function sort() {
opaque.sort( painterSortStable ); if ( opaque.length > 1 ) opaque.sort( painterSortStable );
transparent.sort( reversePainterSortStable ); if ( transparent.length > 1 ) transparent.sort( reversePainterSortStable );
} }
...@@ -134,7 +114,6 @@ function WebGLRenderList() { ...@@ -134,7 +114,6 @@ function WebGLRenderList() {
init: init, init: init,
push: push, push: push,
finish: finish,
sort: sort sort: sort
}; };
......
...@@ -116,7 +116,7 @@ def children(obj, valid_types): ...@@ -116,7 +116,7 @@ def children(obj, valid_types):
""" """
logger.debug('object.children(%s, %s)', obj, valid_types) logger.debug('object.children(%s, %s)', obj, valid_types)
for child in obj.children: for child in obj.children:
if child.type in valid_types: if child.type in valid_types and child.THREE_export:
yield child.name yield child.name
...@@ -455,6 +455,10 @@ def extract_mesh(obj, options, recalculate=False): ...@@ -455,6 +455,10 @@ def extract_mesh(obj, options, recalculate=False):
""" """
logger.debug('object.extract_mesh(%s, %s)', obj, options) logger.debug('object.extract_mesh(%s, %s)', obj, options)
bpy.context.scene.objects.active = obj
hidden_state = obj.hide
obj.hide = False
apply_modifiers = options.get(constants.APPLY_MODIFIERS, True) apply_modifiers = options.get(constants.APPLY_MODIFIERS, True)
if apply_modifiers: if apply_modifiers:
bpy.ops.object.mode_set(mode='OBJECT') bpy.ops.object.mode_set(mode='OBJECT')
...@@ -470,8 +474,6 @@ def extract_mesh(obj, options, recalculate=False): ...@@ -470,8 +474,6 @@ def extract_mesh(obj, options, recalculate=False):
opt_buffer = opt_buffer == constants.BUFFER_GEOMETRY opt_buffer = opt_buffer == constants.BUFFER_GEOMETRY
prop_buffer = mesh_node.THREE_geometry_type == constants.BUFFER_GEOMETRY prop_buffer = mesh_node.THREE_geometry_type == constants.BUFFER_GEOMETRY
bpy.context.scene.objects.active = obj
# if doing buffer geometry it is imperative to triangulate the mesh # if doing buffer geometry it is imperative to triangulate the mesh
if opt_buffer or prop_buffer: if opt_buffer or prop_buffer:
original_mesh = obj.data original_mesh = obj.data
...@@ -480,8 +482,6 @@ def extract_mesh(obj, options, recalculate=False): ...@@ -480,8 +482,6 @@ def extract_mesh(obj, options, recalculate=False):
original_mesh.name, original_mesh.name,
mesh_node.name) mesh_node.name)
hidden_state = obj.hide
obj.hide = False
bpy.ops.object.mode_set(mode='OBJECT') bpy.ops.object.mode_set(mode='OBJECT')
obj.select = True obj.select = True
bpy.context.scene.objects.active = obj bpy.context.scene.objects.active = obj
...@@ -491,7 +491,6 @@ def extract_mesh(obj, options, recalculate=False): ...@@ -491,7 +491,6 @@ def extract_mesh(obj, options, recalculate=False):
modifier='Triangulate') modifier='Triangulate')
obj.data = original_mesh obj.data = original_mesh
obj.select = False obj.select = False
obj.hide = hidden_state
# split sharp edges # split sharp edges
original_mesh = obj.data original_mesh = obj.data
...@@ -504,6 +503,7 @@ def extract_mesh(obj, options, recalculate=False): ...@@ -504,6 +503,7 @@ def extract_mesh(obj, options, recalculate=False):
bpy.context.object.modifiers['EdgeSplit'].use_edge_sharp = True bpy.context.object.modifiers['EdgeSplit'].use_edge_sharp = True
bpy.ops.object.modifier_apply(apply_as='DATA', modifier='EdgeSplit') bpy.ops.object.modifier_apply(apply_as='DATA', modifier='EdgeSplit')
obj.hide = hidden_state
obj.select = False obj.select = False
obj.data = original_mesh obj.data = original_mesh
......
...@@ -94,7 +94,9 @@ class Object(base_classes.BaseNode): ...@@ -94,7 +94,9 @@ class Object(base_classes.BaseNode):
material_names = api.object.material(self.node) #manthrax: changes for multimaterial start here material_names = api.object.material(self.node) #manthrax: changes for multimaterial start here
if material_names: if material_names:
logger.info("Got material names for this object:%s",str(material_names)); logger.info("Got material names for this object:%s",str(material_names));
materialArray = [self.scene.material(objname)[constants.UUID] for objname in material_names] materialArray = [self.scene.material(objname)[constants.UUID] for objname in material_names]
if len(materialArray) == 0: # If no materials.. dont export a material entry if len(materialArray) == 0: # If no materials.. dont export a material entry
materialArray = None materialArray = None
...@@ -102,6 +104,7 @@ class Object(base_classes.BaseNode): ...@@ -102,6 +104,7 @@ class Object(base_classes.BaseNode):
materialArray = materialArray[0] materialArray = materialArray[0]
# else export array of material uuids # else export array of material uuids
self[constants.MATERIAL] = materialArray self[constants.MATERIAL] = materialArray
logger.info("Materials:%s",str(self[constants.MATERIAL])); logger.info("Materials:%s",str(self[constants.MATERIAL]));
else: else:
logger.info("%s has no materials", self.node) #manthrax: end multimaterial logger.info("%s has no materials", self.node) #manthrax: end multimaterial
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册