From 9c21432a3adf200081edd2edf3399249f4f36ef7 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 2 Mar 2016 11:45:29 -0500 Subject: [PATCH 01/21] add TextureSlot support to MeshStandardMaterial with perfect backwards compatibility. --- src/materials/MeshStandardMaterial.js | 202 +++++++++++++++++++++----- src/materials/TextureSlot.js | 67 +++++++++ utils/build/includes/common.json | 1 + 3 files changed, 237 insertions(+), 33 deletions(-) create mode 100644 src/materials/TextureSlot.js diff --git a/src/materials/MeshStandardMaterial.js b/src/materials/MeshStandardMaterial.js index 5acf79d67e5f98..a39b75e311cc84 100644 --- a/src/materials/MeshStandardMaterial.js +++ b/src/materials/MeshStandardMaterial.js @@ -1,5 +1,6 @@ /** * @author WestLangley / http://github.com/WestLangley + * @author Ben Houston / bhouston / http://clara.io * * parameters = { * color: , @@ -41,7 +42,7 @@ * refractionRatio: , * * shading: THREE.SmoothShading, - * blending: THREE.PremultipliedAlphaBlending, + * blending: THREE.PremultipliedAlphaNormalBlending, * depthTest: , * depthWrite: , * @@ -68,33 +69,46 @@ THREE.MeshStandardMaterial = function ( parameters ) { this.roughness = 0.5; this.metalness = 0.5; - this.map = null; + //this.map = null; + this.mapSlot = new THREE.TextureSlot( "map", 0, false, false ); - this.lightMap = null; - this.lightMapIntensity = 1.0; + //this.lightMap = null; + //this.lightMapIntensity = 1.0; + this.lightMapSlot = new THREE.TextureSlot( "lightMap", 1, false, true ); - this.aoMap = null; - this.aoMapIntensity = 1.0; + //this.aoMap = null; + //this.aoMapIntensity = 1.0; + this.aoMapSlot = new THREE.TextureSlot( "aoMap", 1, false, true ); this.emissive = new THREE.Color( 0x000000 ); this.emissiveIntensity = 1.0; - this.emissiveMap = null; + //this.emissiveMap = null; + this.emissiveMapSlot = new THREE.TextureSlot( "emissiveMap", 0, false, false ); - this.bumpMap = null; - this.bumpScale = 1; + //this.bumpMap = null; + //this.bumpScale = 1; + this.bumpMapSlot = new THREE.TextureSlot( "bumpMap", 0, false, true ); - this.normalMap = null; + //this.normalMap = null; this.normalScale = new THREE.Vector2( 1, 1 ); + this.normalMapSlot = new THREE.TextureSlot( "normalMap", 0, false, false ); - this.displacementMap = null; - this.displacementScale = 1; - this.displacementBias = 0; + //this.displacementMap = null; + //this.displacementScale = 1; + //this.displacementBias = 0; + this.displacementMapSlot = new THREE.TextureSlot( "displacementMap", 0, false, true ); - this.roughnessMap = null; + //this.roughnessMap = null; + this.roughnessMapSlot = new THREE.TextureSlot( "roughnessMap", 0, false, false ); - this.metalnessMap = null; + //this.metalnessMap = null; + this.metalnessMapSlot = new THREE.TextureSlot( "metalnessMap", 0, false, false ); - this.alphaMap = null; + //this.alphaMap = null; + this.alphaMapSlot = new THREE.TextureSlot( "alphaMap", 0, false, false ); + + this.slots = [ this.mapSlot, this.lightMapSlot, this.aoMapSlot, this.emissiveMapSlot, this.bumpMapSlot, + this.normalMapSlot, this.roughnessMapSlot, this.metalnessMapSlot, this.alphaMapSlot ]; this.envMap = null; this.envMapIntensity = 1.0; @@ -104,7 +118,7 @@ THREE.MeshStandardMaterial = function ( parameters ) { this.fog = true; this.shading = THREE.SmoothShading; - this.blending = THREE.PremultipliedAlphaBlending; + this.blending = THREE.PremultipliedAlphaNormalBlending; this.wireframe = false; this.wireframeLinewidth = 1; @@ -124,6 +138,134 @@ THREE.MeshStandardMaterial = function ( parameters ) { THREE.MeshStandardMaterial.prototype = Object.create( THREE.Material.prototype ); THREE.MeshStandardMaterial.prototype.constructor = THREE.MeshStandardMaterial; +var closure = function () { + var propertyMappings = { + "map": { + get: function() { + return this.mapSlot.texture; + }, + set: function( value ) { + this.mapSlot.texture = value; + } + }, + "lightMap": { + get: function() { + return this.lightMapSlot.texture; + }, + set: function( value ) { + this.lightMapSlot.texture = value; + } + }, + "lightMapIntensity": { + get: function() { + return this.lightMapSlot.texelScale; + }, + set: function( value ) { + this.lightMapSlot.texelScale = value; + } + }, + "aoMap": { + get: function() { + return this.aoMapSlot.texture; + }, + set: function( value ) { + this.aoMapSlot.texture = value; + } + }, + "aoMapIntensity": { + get: function() { + return this.aoMapSlot.texelScale; + }, + set: function( value ) { + this.aoMapSlot.texelScale = value; + } + }, + "emissiveMap": { + get: function() { + return this.emissiveMapSlot.texture; + }, + set: function( value ) { + this.emissiveMapSlot.texture = value; + } + }, + "bumpMap": { + get: function() { + return this.bumpMapSlot.texture; + }, + set: function( value ) { + this.bumpMapSlot.texture = value; + } + }, + "bumpScale": { + get: function() { + return this.emissiveMapSlot.texelScale; + }, + set: function( value ) { + this.emissiveMapSlot.texelScale = value; + } + }, + "normalMap": { + get: function() { + return this.normalMapSlot.texture; + }, + set: function( value ) { + this.normalMapSlot.texture = value; + } + }, + "displacementMap": { + get: function() { + return this.displacementMapSlot.texture; + }, + set: function( value ) { + this.displacementMapSlot.texture = value; + } + }, + "displacementScale": { + get: function() { + return this.displacementMapSlot.texelScale; + }, + set: function( value ) { + this.displacementMapSlot.texelScale = value; + } + }, + "displacementBias": { + get: function() { + return this.displacementMapSlot.texelOffset; + }, + set: function( value ) { + this.displacementMapSlot.texelOffset = value; + } + }, + "roughnessMap": { + get: function() { + return this.roughnessMapSlot.texture; + }, + set: function( value ) { + this.roughnessMapSlot.texture = value; + } + }, + "metalnessMap": { + get: function() { + return this.metalnessMapSlot.texture; + }, + set: function( value ) { + this.metalnessMapSlot.texture = value; + } + }, + "alphaMap": { + get: function() { + return this.alphaMapSlot.texture; + }, + set: function( value ) { + this.alphaMapSlot.texture = value; + } + } + }; + for( var propertyName in propertyMappings ) { + Object.defineProperty(THREE.MeshStandardMaterial.prototype, propertyName, propertyMappings[ propertyName ] ); + } +}(); + THREE.MeshStandardMaterial.prototype.copy = function ( source ) { THREE.Material.prototype.copy.call( this, source ); @@ -132,28 +274,22 @@ THREE.MeshStandardMaterial.prototype.copy = function ( source ) { this.roughness = source.roughness; this.metalness = source.metalness; - this.map = source.map; - - this.lightMap = source.lightMap; - this.lightMapIntensity = source.lightMapIntensity; - - this.aoMap = source.aoMap; - this.aoMapIntensity = source.aoMapIntensity; + this.mapSlot.copy( source.mapSlot ); + this.lightMapSlot.copy( source.lightMapSlot ); + this.aoMapSlot.copy( source.aoMapSlot ); + this.emissiveMapSlot.copy( source.emissiveMapSlot ); + this.bumpMapSlot.copy( source.bumpMapSlot ); + this.normalMapSlot.copy( source.normalMapSlot ); + this.displacementMapSlot.copy( source.displacementMapSlot ); + this.roughnessMapSlot.copy( source.roughnessMapSlot ); + this.metalnessMapSlot.copy( source.metalnessMapSlot ); + this.alphaMapSlot.copy( source.alphaMapSlot ); this.emissive.copy( source.emissive ); - this.emissiveMap = source.emissiveMap; this.emissiveIntensity = source.emissiveIntensity; - this.bumpMap = source.bumpMap; - this.bumpScale = source.bumpScale; - - this.normalMap = source.normalMap; this.normalScale.copy( source.normalScale ); - this.displacementMap = source.displacementMap; - this.displacementScale = source.displacementScale; - this.displacementBias = source.displacementBias; - this.roughnessMap = source.roughnessMap; this.metalnessMap = source.metalnessMap; diff --git a/src/materials/TextureSlot.js b/src/materials/TextureSlot.js new file mode 100644 index 00000000000000..d24942361b57e0 --- /dev/null +++ b/src/materials/TextureSlot.js @@ -0,0 +1,67 @@ +/** + * @author Ben Houston / bhouston / http://clara.io + * + */ + +THREE.TextureSlot = function ( name, uvChannel, uvTransform, texelTransform ) { + + this.name = name || "unnamed"; + + this.texture = null; + + this.uvChannel = uvChannel || 0; + + this.uvTransform = uvTransform || false; + this.uvOffset = new THREE.Vector2( 0, 0 ); + this.uvRepeat = new THREE.Vector2( 1.0, 1.0 ); + this.uvRotation = 0; + + this.texelTransform = uvTransform || false; + this.texelScale = 1.0; + this.texelOffset = 0.0; + this.texelInvert = false; + +}; + +THREE.TextureSlot.prototype = { + + constructor: THREE.TextureSlot, + + copy: function ( source ) { + + this.name = source.name; + + this.texture = source.texture; + + this.uvChannel = source.uvChannel; + + this.uvTransform = source.uvTransform; + this.uvOffset = source.uvOffset; + this.uvRepeat = source.uvRepeat; + this.uvRotation = source.uvRotation; + + this.texelTransform = source.texelTransform; + this.texelScale = source.texelScale; + this.texelOffset = source.texelOffset; + this.texelInvert = source.texelInvert; + + return this; + + }, + + // bakes all the input texel parameters into just two. + getFlattenedTexelTransform: function() { + + if( this.texelInvert ) { + return { + texelScale: -this.texelScale, + texelOffset: this.texelScale + this.texelOffset + }; + } + return { + texelScale: this.texelScale, + texelOffset: this.texelOffset + }; + } + +}; diff --git a/utils/build/includes/common.json b/utils/build/includes/common.json index 7f41bb3de126be..1fa15729f37bb8 100644 --- a/utils/build/includes/common.json +++ b/utils/build/includes/common.json @@ -82,6 +82,7 @@ "src/loaders/CubeTextureLoader.js", "src/loaders/BinaryTextureLoader.js", "src/loaders/CompressedTextureLoader.js", + "src/materials/TextureSlot.js", "src/materials/Material.js", "src/materials/LineBasicMaterial.js", "src/materials/LineDashedMaterial.js", From 03eeb550779d0869a73d9d1f3c4a88c7a0cfb911 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 2 Mar 2016 11:45:48 -0500 Subject: [PATCH 02/21] convert WebGLPrograms to auto-generate parameters based on slots with perfect backwards compatibility. --- src/renderers/webgl/WebGLPrograms.js | 43 +++++++++++++++++----------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/src/renderers/webgl/WebGLPrograms.js b/src/renderers/webgl/WebGLPrograms.js index 7e99a2c0f5eba0..47dcbbfe7d91c8 100644 --- a/src/renderers/webgl/WebGLPrograms.js +++ b/src/renderers/webgl/WebGLPrograms.js @@ -14,11 +14,14 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) { PointsMaterial: 'points' }; + var slots = [ + 'map', 'lightMap', 'aoMap', 'emissiveMap', 'specularMap', 'bumpMap', 'normalMap', 'roughnessMap', 'metalnessMap', 'alphaMap' + ]; + var parameterNames = [ - "precision", "supportsVertexTextures", "map", "mapEncoding", "envMap", "envMapMode", "envMapEncoding", - "lightMap", "aoMap", "emissiveMap", "emissiveMapEncoding", "bumpMap", "normalMap", "displacementMap", "specularMap", - "roughnessMap", "metalnessMap", - "alphaMap", "combine", "vertexColors", "fog", "useFog", "fogExp", + "precision", "supportsVertexTextures", "mapEncoding", "envMap", "envMapMode", "envMapEncoding", + "emissiveMapEncoding", + "combine", "vertexColors", "fog", "useFog", "fogExp", "flatShading", "sizeAttenuation", "logarithmicDepthBuffer", "skinning", "maxBones", "useVertexTexture", "morphTargets", "morphNormals", "maxMorphTargets", "maxMorphNormals", "premultipliedAlpha", @@ -28,6 +31,13 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) { "alphaTest", "doubleSided", "flipSided" ]; + for( var i = 0; i < slots.length; i ++ ) { + var name = slots[i]; + parameterNames.push( name ); + parameterNames.push( name + 'UVChannel' ); + parameterNames.push( name + 'UVTransform' ); + parameterNames.push( name + 'TexelTransform' ); + } function allocateBones ( object ) { @@ -125,23 +135,12 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) { precision: precision, supportsVertexTextures: capabilities.vertexTextures, outputEncoding: getTextureEncodingFromMap( renderer.getCurrentRenderTarget(), renderer.gammaOutput ), - map: !! material.map, mapEncoding: getTextureEncodingFromMap( material.map, renderer.gammaInput ), - envMap: !! material.envMap, + envMap: !!material.envMap, envMapMode: material.envMap && material.envMap.mapping, envMapEncoding: getTextureEncodingFromMap( material.envMap, renderer.gammaInput ), envMapCubeUV: ( !! material.envMap ) && ( ( material.envMap.mapping === THREE.CubeUVReflectionMapping ) || ( material.envMap.mapping === THREE.CubeUVRefractionMapping ) ), - lightMap: !! material.lightMap, - aoMap: !! material.aoMap, - emissiveMap: !! material.emissiveMap, emissiveMapEncoding: getTextureEncodingFromMap( material.emissiveMap, renderer.gammaInput ), - bumpMap: !! material.bumpMap, - normalMap: !! material.normalMap, - displacementMap: !! material.displacementMap, - roughnessMap: !! material.roughnessMap, - metalnessMap: !! material.metalnessMap, - specularMap: !! material.specularMap, - alphaMap: !! material.alphaMap, combine: material.combine, @@ -184,6 +183,18 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) { }; + for( var i = 0; i < slots.length; i ++ ) { + var name = slots[i]; + // backwards compatibility + parameters[name] = !! material[ name ]; + + // new functional for slot-based maps + var slot = material[ name + 'Slot' ]; + parameters[name + "UVChannel" ] = ( slot !== undefined ) ? slot.uvChannel : 0; + parameters[name + "UVTransform" ] = ( slot !== undefined ) ? slot.uvTransform : false; + parameters[name + "TexelTransform" ] = ( slot !== undefined ) ? slot.texelTransform : false; + } + return parameters; }; From d21f843706aaf94a101fa53df8331f68c0172ed8 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 2 Mar 2016 12:11:29 -0500 Subject: [PATCH 03/21] create glsl injectors for slot UV and Texel transforms. --- .../slot_texel_transform_template.glsl | 7 ++++ .../slot_uv_transform_template.glsl | 8 +++++ src/renderers/webgl/WebGLProgram.js | 32 +++++++++++++++++++ utils/build/includes/common.json | 2 ++ 4 files changed, 49 insertions(+) create mode 100644 src/renderers/shaders/ShaderChunk/slot_texel_transform_template.glsl create mode 100644 src/renderers/shaders/ShaderChunk/slot_uv_transform_template.glsl diff --git a/src/renderers/shaders/ShaderChunk/slot_texel_transform_template.glsl b/src/renderers/shaders/ShaderChunk/slot_texel_transform_template.glsl new file mode 100644 index 00000000000000..1f58160d13fb68 --- /dev/null +++ b/src/renderers/shaders/ShaderChunk/slot_texel_transform_template.glsl @@ -0,0 +1,7 @@ +uniform vec2 TexelTransformParams; + +vec4 TexelTransform( vec4 value ) { + value.rgb *= TexelTransformParams.x; + value.rgb += vec3( TexelTransformParams.y ); + return value; +} diff --git a/src/renderers/shaders/ShaderChunk/slot_uv_transform_template.glsl b/src/renderers/shaders/ShaderChunk/slot_uv_transform_template.glsl new file mode 100644 index 00000000000000..e709c801cc310f --- /dev/null +++ b/src/renderers/shaders/ShaderChunk/slot_uv_transform_template.glsl @@ -0,0 +1,8 @@ +uniform vec4 UVTransformParams; + +vec2 UV() { + vec2 value = ; + value.xy *= UVTransformParams.xy; + value.xy += UVTransformParams.zw; + return value; +} diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js index 2d5d9da22f4ac7..8ced1dedf482f4 100644 --- a/src/renderers/webgl/WebGLProgram.js +++ b/src/renderers/webgl/WebGLProgram.js @@ -46,6 +46,38 @@ THREE.WebGLProgram = ( function () { } + function getTexelTransformFunction( slot ) { + + if( ! slot.texelTransform ) { + return "vec4 " + slot.name + "TexelTransform( vec4 value ) { return value; }"; + } + + var transform = slot.getFlattenedTexelTransform(); + var template = THREE.ShaderChunk[ 'slot_texel_transform_template' ]; + var result = template.replace( "", slot.name ); + return result; + + } + + function getUVFunction( slot, isVertexShader ) { + + var uvVariableName = ( isVertexShader ) ? "vUv" : "uv"; + if( slot.uvChannel > 0 ) { + uvVariableName += slot.uvChannel; + } + + if( ! slot.uvTransform ) { + return "vec2 " + slot.name + "UV() { return " + uvName + "; }"; + } + + var transform = slot.getFlattenedTexelTransform(); + var template = THREE.ShaderChunk[ 'slot_texel_transform_template' ]; + var result = template.replace( "", slot.name ); + result = result.replace( "", uvVariableName ); + return result; + + } + function getToneMappingFunction( functionName, toneMapping ) { var toneMappingName; diff --git a/utils/build/includes/common.json b/utils/build/includes/common.json index 1fa15729f37bb8..109a8b69813fbd 100644 --- a/utils/build/includes/common.json +++ b/utils/build/includes/common.json @@ -187,6 +187,8 @@ "src/renderers/shaders/ShaderChunk/skinnormal_vertex.glsl", "src/renderers/shaders/ShaderChunk/specularmap_fragment.glsl", "src/renderers/shaders/ShaderChunk/specularmap_pars_fragment.glsl", + "src/renderers/shaders/ShaderChunk/slot_texel_transform_template.glsl", + "src/renderers/shaders/ShaderChunk/slot_uv_transform_template.glsl", "src/renderers/shaders/ShaderChunk/tonemapping_fragment.glsl", "src/renderers/shaders/ShaderChunk/tonemapping_pars_fragment.glsl", "src/renderers/shaders/ShaderChunk/uv2_pars_fragment.glsl", From c36a7b95e3e08290e66c310cb3211b9c070a189e Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 2 Mar 2016 13:24:02 -0500 Subject: [PATCH 04/21] do code glsl injection when there are texture slots used. --- .../shaders/ShaderChunk/uv_pars_fragment.glsl | 10 ++-- src/renderers/webgl/WebGLProgram.js | 46 +++++++++++++++---- src/renderers/webgl/WebGLPrograms.js | 10 ++-- 3 files changed, 49 insertions(+), 17 deletions(-) diff --git a/src/renderers/shaders/ShaderChunk/uv_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/uv_pars_fragment.glsl index d1bb9548cb14f0..cffae01560b4a9 100644 --- a/src/renderers/shaders/ShaderChunk/uv_pars_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/uv_pars_fragment.glsl @@ -1,5 +1,9 @@ -#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP ) +#if ! defined( TEXTURE_SLOTS ) - varying vec2 vUv; + #if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP ) -#endif \ No newline at end of file + varying vec2 vUv; + + #endif + +#endif diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js index 8ced1dedf482f4..7fdfde61b5d0fc 100644 --- a/src/renderers/webgl/WebGLProgram.js +++ b/src/renderers/webgl/WebGLProgram.js @@ -7,6 +7,10 @@ THREE.WebGLProgram = ( function () { var arrayStructRe = /^([\w\d_]+)\[(\d+)\]\.([\w\d_]+)$/; var arrayRe = /^([\w\d_]+)\[0\]$/; + var supportedSlots = [ + 'map', 'lightMap', 'aoMap', 'emissiveMap', 'specularMap', 'bumpMap', 'normalMap', 'roughnessMap', 'metalnessMap', 'alphaMap' + ]; + function getEncodingComponents( encoding ) { switch ( encoding ) { @@ -46,10 +50,10 @@ THREE.WebGLProgram = ( function () { } - function getTexelTransformFunction( slot ) { + function getTexelTransformFunction( slotName, slot ) { - if( ! slot.texelTransform ) { - return "vec4 " + slot.name + "TexelTransform( vec4 value ) { return value; }"; + if( ! slot || ! slot.texelTransform ) { + return "vec4 " + slotName + "TexelTransform( vec4 value ) { return value; }\n"; } var transform = slot.getFlattenedTexelTransform(); @@ -59,15 +63,15 @@ THREE.WebGLProgram = ( function () { } - function getUVFunction( slot, isVertexShader ) { + function getUVFunction( slotName, slot, isVertexShader ) { - var uvVariableName = ( isVertexShader ) ? "vUv" : "uv"; - if( slot.uvChannel > 0 ) { - uvVariableName += slot.uvChannel; + var uvVariableName = ( isVertexShader ) ? "uv" : "vUv"; + if( slot && slot.uvChannel > 0 ) { + uvVariableName += ( slot.uvChannel + 1 ); } - if( ! slot.uvTransform ) { - return "vec2 " + slot.name + "UV() { return " + uvName + "; }"; + if( ! slot || ! slot.uvTransform ) { + return "vec2 " + slotName + "UV() { return " + uvVariableName + "; }\n"; } var transform = slot.getFlattenedTexelTransform(); @@ -572,6 +576,30 @@ THREE.WebGLProgram = ( function () { ].filter( filterEmptyLine ).join( '\n' ); + var slotCode = ""; + var slotUvChannels = []; + for( var i = 0; i < supportedSlots.length; i ++ ) { + var slotName = supportedSlots[i]; + var slot = material[ slotName + 'Slot' ]; + if( slot || material[ slotName ] ) { + if( slot && ! slotUvChannels[ slot.uvChannel ]) slotUvChannels[ slot.uvChannel ] = true; + slotCode += getTexelTransformFunction( slotName, slot ); + slotCode += getUVFunction( slotName, slot, false ); + } + } + if( Object.keys( slotUvChannels ).length > 0 ) { + var slotPrefix = ""; + slotPrefix += "#define TEXTURE_SLOTS\n"; + for( var uvChannel in slotUvChannels ) { + uvChannel = parseInt( uvChannel ); + var uvChannelName = "vUv"; + if( uvChannel > 0 ) uvChannelName += '' + ( uvChannel + 1 ); + slotPrefix += "varying vec2 " + uvChannelName + ";\n"; + } + console.log( slotPrefix ); + console.log( slotCode ); + prefixFragment += slotPrefix + slotCode; + } } vertexShader = parseIncludes( vertexShader, parameters ); diff --git a/src/renderers/webgl/WebGLPrograms.js b/src/renderers/webgl/WebGLPrograms.js index 47dcbbfe7d91c8..0841e93f572811 100644 --- a/src/renderers/webgl/WebGLPrograms.js +++ b/src/renderers/webgl/WebGLPrograms.js @@ -14,7 +14,7 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) { PointsMaterial: 'points' }; - var slots = [ + var supportedSlots = [ 'map', 'lightMap', 'aoMap', 'emissiveMap', 'specularMap', 'bumpMap', 'normalMap', 'roughnessMap', 'metalnessMap', 'alphaMap' ]; @@ -31,8 +31,8 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) { "alphaTest", "doubleSided", "flipSided" ]; - for( var i = 0; i < slots.length; i ++ ) { - var name = slots[i]; + for( var i = 0; i < supportedSlots.length; i ++ ) { + var name = supportedSlots[i]; parameterNames.push( name ); parameterNames.push( name + 'UVChannel' ); parameterNames.push( name + 'UVTransform' ); @@ -183,8 +183,8 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) { }; - for( var i = 0; i < slots.length; i ++ ) { - var name = slots[i]; + for( var i = 0; i < supportedSlots.length; i ++ ) { + var name = supportedSlots[i]; // backwards compatibility parameters[name] = !! material[ name ]; From 6f220826bd158e9b8b23fae9a6308a71d0b5b13d Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 2 Mar 2016 14:35:44 -0500 Subject: [PATCH 05/21] integrated in TEXTURE_SLOTS into fragment shaders. --- src/materials/MeshStandardMaterial.js | 24 +++++------------ .../ShaderChunk/alphamap_fragment.glsl | 8 +++++- .../ShaderChunk/alphamap_pars_fragment.glsl | 6 +++-- .../shaders/ShaderChunk/aomap_fragment.glsl | 8 +++++- .../ShaderChunk/aomap_pars_fragment.glsl | 5 +++- .../ShaderChunk/bumpmap_pars_fragment.glsl | 20 ++++++++++---- .../ShaderChunk/emissivemap_fragment.glsl | 10 +++++-- .../emissivemap_pars_fragment.glsl | 6 +++-- .../ShaderChunk/lightmap_fragment.glsl | 8 +++++- .../ShaderChunk/lightmap_pars_fragment.glsl | 10 ++++--- .../shaders/ShaderChunk/map_fragment.glsl | 10 +++++-- .../ShaderChunk/map_pars_fragment.glsl | 6 +++-- .../ShaderChunk/metalnessmap_fragment.glsl | 8 +++++- .../metalnessmap_pars_fragment.glsl | 8 +++--- .../ShaderChunk/normalmap_pars_fragment.glsl | 18 +++++++++---- .../ShaderChunk/roughnessmap_fragment.glsl | 8 +++++- .../roughnessmap_pars_fragment.glsl | 8 +++--- .../slot_texel_transform_template.glsl | 8 +++--- .../slot_uv_transform_template.glsl | 10 +++---- .../ShaderChunk/specularmap_fragment.glsl | 10 +++++-- .../specularmap_pars_fragment.glsl | 8 +++--- src/renderers/webgl/WebGLProgram.js | 27 ++++++++++--------- 22 files changed, 154 insertions(+), 80 deletions(-) diff --git a/src/materials/MeshStandardMaterial.js b/src/materials/MeshStandardMaterial.js index a39b75e311cc84..43fa11934d9b4f 100644 --- a/src/materials/MeshStandardMaterial.js +++ b/src/materials/MeshStandardMaterial.js @@ -77,7 +77,7 @@ THREE.MeshStandardMaterial = function ( parameters ) { this.lightMapSlot = new THREE.TextureSlot( "lightMap", 1, false, true ); //this.aoMap = null; - //this.aoMapIntensity = 1.0; + this.aoMapIntensity = 1.0; this.aoMapSlot = new THREE.TextureSlot( "aoMap", 1, false, true ); this.emissive = new THREE.Color( 0x000000 ); @@ -107,8 +107,8 @@ THREE.MeshStandardMaterial = function ( parameters ) { //this.alphaMap = null; this.alphaMapSlot = new THREE.TextureSlot( "alphaMap", 0, false, false ); - this.slots = [ this.mapSlot, this.lightMapSlot, this.aoMapSlot, this.emissiveMapSlot, this.bumpMapSlot, - this.normalMapSlot, this.roughnessMapSlot, this.metalnessMapSlot, this.alphaMapSlot ]; + //this.slots = [ this.mapSlot, this.lightMapSlot, this.aoMapSlot, this.emissiveMapSlot, this.bumpMapSlot, + // this.normalMapSlot, this.roughnessMapSlot, this.metalnessMapSlot, this.alphaMapSlot ]; this.envMap = null; this.envMapIntensity = 1.0; @@ -161,6 +161,7 @@ var closure = function () { return this.lightMapSlot.texelScale; }, set: function( value ) { + this.lightMapSlot.texelTransform = true; this.lightMapSlot.texelScale = value; } }, @@ -172,14 +173,6 @@ var closure = function () { this.aoMapSlot.texture = value; } }, - "aoMapIntensity": { - get: function() { - return this.aoMapSlot.texelScale; - }, - set: function( value ) { - this.aoMapSlot.texelScale = value; - } - }, "emissiveMap": { get: function() { return this.emissiveMapSlot.texture; @@ -201,6 +194,7 @@ var closure = function () { return this.emissiveMapSlot.texelScale; }, set: function( value ) { + this.emissiveMapSlot.texelTransform = true; this.emissiveMapSlot.texelScale = value; } }, @@ -225,6 +219,7 @@ var closure = function () { return this.displacementMapSlot.texelScale; }, set: function( value ) { + this.displacementMapSlot.texelTransform = true; this.displacementMapSlot.texelScale = value; } }, @@ -233,6 +228,7 @@ var closure = function () { return this.displacementMapSlot.texelOffset; }, set: function( value ) { + this.displacementMapSlot.texelTransform = true; this.displacementMapSlot.texelOffset = value; } }, @@ -290,12 +286,6 @@ THREE.MeshStandardMaterial.prototype.copy = function ( source ) { this.normalScale.copy( source.normalScale ); - this.roughnessMap = source.roughnessMap; - - this.metalnessMap = source.metalnessMap; - - this.alphaMap = source.alphaMap; - this.envMap = source.envMap; this.envMapIntensity = source.envMapIntensity; diff --git a/src/renderers/shaders/ShaderChunk/alphamap_fragment.glsl b/src/renderers/shaders/ShaderChunk/alphamap_fragment.glsl index 1aa712eb3aaa9c..7bd8b1129f1796 100644 --- a/src/renderers/shaders/ShaderChunk/alphamap_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/alphamap_fragment.glsl @@ -1,5 +1,11 @@ #ifdef USE_ALPHAMAP - diffuseColor.a *= texture2D( alphaMap, vUv ).g; +#if defined( TEXTURE_SLOTS ) + vec2 alphaUv = alphaMapUV(); +#else + vec2 alphaUv = vUv; +#endif + + diffuseColor.a *= alphaMapTexelTransform( texture2D( alphaMap, alphaUv ) ).g; #endif diff --git a/src/renderers/shaders/ShaderChunk/alphamap_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/alphamap_pars_fragment.glsl index 4a84b4997f9749..3915adfeb48d04 100644 --- a/src/renderers/shaders/ShaderChunk/alphamap_pars_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/alphamap_pars_fragment.glsl @@ -1,5 +1,7 @@ -#ifdef USE_ALPHAMAP +#if ! defined( TEXTURE_SLOTS ) + #ifdef USE_ALPHAMAP - uniform sampler2D alphaMap; + uniform sampler2D alphaMap; + #endif #endif diff --git a/src/renderers/shaders/ShaderChunk/aomap_fragment.glsl b/src/renderers/shaders/ShaderChunk/aomap_fragment.glsl index 84d644a195edcb..bcc5590017c7ae 100644 --- a/src/renderers/shaders/ShaderChunk/aomap_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/aomap_fragment.glsl @@ -1,6 +1,12 @@ #ifdef USE_AOMAP - float ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0; +#if defined( TEXTURE_SLOTS ) + vec2 aoUv = aoMapUV(); +#else + vec2 aoUv = vUv2; +#endif + + float ambientOcclusion = ( aoMapTexelTransform( texture2D( aoMap, aoUv ) ).r - 1.0 ) * aoMapIntensity + 1.0; reflectedLight.indirectDiffuse *= ambientOcclusion; diff --git a/src/renderers/shaders/ShaderChunk/aomap_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/aomap_pars_fragment.glsl index 73277ab4b1eba9..ac7ce1d4512a83 100644 --- a/src/renderers/shaders/ShaderChunk/aomap_pars_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/aomap_pars_fragment.glsl @@ -1,6 +1,9 @@ #ifdef USE_AOMAP +#if ! defined( TEXTURE_SLOTS ) uniform sampler2D aoMap; +#endif + uniform float aoMapIntensity; -#endif \ No newline at end of file +#endif diff --git a/src/renderers/shaders/ShaderChunk/bumpmap_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/bumpmap_pars_fragment.glsl index c901f0b0135cc5..7f289d523e04c5 100644 --- a/src/renderers/shaders/ShaderChunk/bumpmap_pars_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/bumpmap_pars_fragment.glsl @@ -1,8 +1,12 @@ #ifdef USE_BUMPMAP +#if ! defined( TEXTURE_SLOTS ) + uniform sampler2D bumpMap; uniform float bumpScale; +#endif + // Derivative maps - bump mapping unparametrized surfaces by Morten Mikkelsen // http://mmikkelsen3d.blogspot.sk/2011/07/derivative-maps.html @@ -10,12 +14,18 @@ vec2 dHdxy_fwd() { - vec2 dSTdx = dFdx( vUv ); - vec2 dSTdy = dFdy( vUv ); +#if defined( TEXTURE_SLOTS ) + vec2 bumpUv = bumpMapUV(); +#else + vec2 bumpUv = vUv; +#endif + + vec2 dSTdx = dFdx( bumpUv ); + vec2 dSTdy = dFdy( bumpUv ); - float Hll = bumpScale * texture2D( bumpMap, vUv ).x; - float dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll; - float dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll; + float Hll = bumpMapTexelTransform( texture2D( bumpMap, bumpUv ) ).x; + float dBx = bumpMapTexelTransform( texture2D( bumpMap, bumpUv + dSTdx ) ).x - Hll; + float dBy = bumpMapTexelTransform( texture2D( bumpMap, bumpUv + dSTdy ) ).x - Hll; return vec2( dBx, dBy ); diff --git a/src/renderers/shaders/ShaderChunk/emissivemap_fragment.glsl b/src/renderers/shaders/ShaderChunk/emissivemap_fragment.glsl index c0951b050bda16..5df8f949a8c9d5 100644 --- a/src/renderers/shaders/ShaderChunk/emissivemap_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/emissivemap_fragment.glsl @@ -1,8 +1,14 @@ #ifdef USE_EMISSIVEMAP - vec4 emissiveColor = texture2D( emissiveMap, vUv ); +#if defined( TEXTURE_SLOTS ) + vec2 emissiveUv = emissiveMapUV(); +#else + vec2 emissiveUv = vUv; +#endif + + vec4 emissiveColor = texture2D( emissiveMap, emissiveUv ); - emissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb; + emissiveColor.rgb = emissiveMapTexelTransform( emissiveMapTexelToLinear( emissiveColor ) ).rgb; totalEmissiveLight *= emissiveColor.rgb; diff --git a/src/renderers/shaders/ShaderChunk/emissivemap_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/emissivemap_pars_fragment.glsl index c05bb7f55180a0..44e88f24accb4f 100644 --- a/src/renderers/shaders/ShaderChunk/emissivemap_pars_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/emissivemap_pars_fragment.glsl @@ -1,5 +1,7 @@ -#ifdef USE_EMISSIVEMAP +#if ! defined( TEXTURE_SLOTS ) + #ifdef USE_EMISSIVEMAP - uniform sampler2D emissiveMap; + uniform sampler2D emissiveMap; + #endif #endif diff --git a/src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl b/src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl index 1392a6097c96e5..c595a170559c96 100644 --- a/src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl @@ -1,5 +1,11 @@ #ifdef USE_LIGHTMAP - reflectedLight.indirectDiffuse += PI * texture2D( lightMap, vUv2 ).xyz * lightMapIntensity; // factor of PI should not be present; included here to prevent breakage +#if defined( TEXTURE_SLOTS ) + vec2 lightUv = lightMapUV(); +#else + vec2 lightUv = vUv2; +#endif + + reflectedLight.indirectDiffuse += PI * emissiveMapTexelTransform( texture2D( lightMap, lightUv ) ).xyz; // factor of PI should not be present; included here to prevent breakage #endif diff --git a/src/renderers/shaders/ShaderChunk/lightmap_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/lightmap_pars_fragment.glsl index a75c38f7edc244..712aa75cdc1d28 100644 --- a/src/renderers/shaders/ShaderChunk/lightmap_pars_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/lightmap_pars_fragment.glsl @@ -1,6 +1,8 @@ -#ifdef USE_LIGHTMAP +#if ! defined( TEXTURE_SLOTS ) + #ifdef USE_LIGHTMAP - uniform sampler2D lightMap; - uniform float lightMapIntensity; + uniform sampler2D lightMap; + uniform float lightMapIntensity; -#endif \ No newline at end of file + #endif +#endif diff --git a/src/renderers/shaders/ShaderChunk/map_fragment.glsl b/src/renderers/shaders/ShaderChunk/map_fragment.glsl index b5fb51b16c7ecf..ddc6657568daed 100644 --- a/src/renderers/shaders/ShaderChunk/map_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/map_fragment.glsl @@ -1,8 +1,14 @@ #ifdef USE_MAP - vec4 texelColor = texture2D( map, vUv ); +#if defined( TEXTURE_SLOTS ) + vec2 mapUv = mapUV(); +#else + vec2 mapUv = vUv; +#endif + + vec4 texelColor = texture2D( map, mapUv ); - texelColor = mapTexelToLinear( texelColor ); + texelColor = mapTexelTransform( mapTexelToLinear( texelColor ) ); diffuseColor *= texelColor; #endif diff --git a/src/renderers/shaders/ShaderChunk/map_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/map_pars_fragment.glsl index d9a03464ba71ec..ff22d8699ce6ed 100644 --- a/src/renderers/shaders/ShaderChunk/map_pars_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/map_pars_fragment.glsl @@ -1,5 +1,7 @@ -#ifdef USE_MAP +#if ! defined( TEXTURE_SLOTS ) + #ifdef USE_MAP - uniform sampler2D map; + uniform sampler2D map; + #endif #endif diff --git a/src/renderers/shaders/ShaderChunk/metalnessmap_fragment.glsl b/src/renderers/shaders/ShaderChunk/metalnessmap_fragment.glsl index be8f3694c752f4..423752cf3ad3f5 100644 --- a/src/renderers/shaders/ShaderChunk/metalnessmap_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/metalnessmap_fragment.glsl @@ -2,7 +2,13 @@ float metalnessFactor = metalness; #ifdef USE_METALNESSMAP - vec4 texelMetalness = texture2D( metalnessMap, vUv ); + #if defined( TEXTURE_SLOTS ) + vec2 metalnessUv = metalnessMapUV(); + #else + vec2 metalnessUv = vUv; + #endif + + vec4 texelMetalness = metalnessTexelTransform( texture2D( metalnessMap, metalnessUv ) ); metalnessFactor *= texelMetalness.r; #endif diff --git a/src/renderers/shaders/ShaderChunk/metalnessmap_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/metalnessmap_pars_fragment.glsl index 1d9c869e0e10b4..3bf9cf03355391 100644 --- a/src/renderers/shaders/ShaderChunk/metalnessmap_pars_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/metalnessmap_pars_fragment.glsl @@ -1,5 +1,7 @@ -#ifdef USE_METALNESSMAP +#if ! defined( TEXTURE_SLOTS ) + #ifdef USE_METALNESSMAP - uniform sampler2D metalnessMap; + uniform sampler2D metalnessMap; -#endif \ No newline at end of file + #endif +#endif diff --git a/src/renderers/shaders/ShaderChunk/normalmap_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/normalmap_pars_fragment.glsl index 54b93eb59fb3d4..0381288630835b 100644 --- a/src/renderers/shaders/ShaderChunk/normalmap_pars_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/normalmap_pars_fragment.glsl @@ -1,23 +1,31 @@ #ifdef USE_NORMALMAP - uniform sampler2D normalMap; - uniform vec2 normalScale; + #if ! defined( TEXTURE_SLOTS ) + uniform sampler2D normalMap; + #endif + uniform vec2 normalScale; // Per-Pixel Tangent Space Normal Mapping // http://hacksoflife.blogspot.ch/2009/11/per-pixel-tangent-space-normal-mapping.html vec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) { + #if defined( TEXTURE_SLOTS ) + vec2 normalUv = normalMapUV(); + #else + vec2 normalUv = vUv; + #endif + vec3 q0 = dFdx( eye_pos.xyz ); vec3 q1 = dFdy( eye_pos.xyz ); - vec2 st0 = dFdx( vUv.st ); - vec2 st1 = dFdy( vUv.st ); + vec2 st0 = dFdx( normalUv.st ); + vec2 st1 = dFdy( normalUv.st ); vec3 S = normalize( q0 * st1.t - q1 * st0.t ); vec3 T = normalize( -q0 * st1.s + q1 * st0.s ); vec3 N = normalize( surf_norm ); - vec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0; + vec3 mapN = texture2D( normalMap, normalUv ).xyz * 2.0 - 1.0; mapN.xy = normalScale * mapN.xy; mat3 tsn = mat3( S, T, N ); return normalize( tsn * mapN ); diff --git a/src/renderers/shaders/ShaderChunk/roughnessmap_fragment.glsl b/src/renderers/shaders/ShaderChunk/roughnessmap_fragment.glsl index a2d24ad8c9360f..bbcbf6df8f6e4e 100644 --- a/src/renderers/shaders/ShaderChunk/roughnessmap_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/roughnessmap_fragment.glsl @@ -2,7 +2,13 @@ float roughnessFactor = roughness; #ifdef USE_ROUGHNESSMAP - vec4 texelRoughness = texture2D( roughnessMap, vUv ); + #if defined( TEXTURE_SLOTS ) + vec2 roughnessUv = roughnessMapUV(); + #else + vec2 roughnessUv = vUv; + #endif + + vec4 texelRoughness = roughnessMapTexelTransform( texture2D( roughnessMap, roughnessUv ) ); roughnessFactor *= texelRoughness.r; #endif diff --git a/src/renderers/shaders/ShaderChunk/roughnessmap_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/roughnessmap_pars_fragment.glsl index 0f257121d1a11a..982684e9d02563 100644 --- a/src/renderers/shaders/ShaderChunk/roughnessmap_pars_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/roughnessmap_pars_fragment.glsl @@ -1,5 +1,7 @@ -#ifdef USE_ROUGHNESSMAP +#if ! defined( TEXTURE_SLOTS ) + #ifdef USE_ROUGHNESSMAP - uniform sampler2D roughnessMap; + uniform sampler2D roughnessMap; -#endif \ No newline at end of file + #endif +#endif diff --git a/src/renderers/shaders/ShaderChunk/slot_texel_transform_template.glsl b/src/renderers/shaders/ShaderChunk/slot_texel_transform_template.glsl index 1f58160d13fb68..b1bfe1a6fdf76c 100644 --- a/src/renderers/shaders/ShaderChunk/slot_texel_transform_template.glsl +++ b/src/renderers/shaders/ShaderChunk/slot_texel_transform_template.glsl @@ -1,7 +1,7 @@ -uniform vec2 TexelTransformParams; +uniform vec2 $SLOT_NAME$TexelTransformParams; -vec4 TexelTransform( vec4 value ) { - value.rgb *= TexelTransformParams.x; - value.rgb += vec3( TexelTransformParams.y ); +vec4 $SLOT_NAME$TexelTransform( vec4 value ) { + value.rgb *= $SLOT_NAME$TexelTransformParams.x; + value.rgb += vec3( $SLOT_NAME$TexelTransformParams.y ); return value; } diff --git a/src/renderers/shaders/ShaderChunk/slot_uv_transform_template.glsl b/src/renderers/shaders/ShaderChunk/slot_uv_transform_template.glsl index e709c801cc310f..dc85bea47f699b 100644 --- a/src/renderers/shaders/ShaderChunk/slot_uv_transform_template.glsl +++ b/src/renderers/shaders/ShaderChunk/slot_uv_transform_template.glsl @@ -1,8 +1,8 @@ -uniform vec4 UVTransformParams; +uniform vec4 $SLOT_NAME$UVTransformParams; -vec2 UV() { - vec2 value = ; - value.xy *= UVTransformParams.xy; - value.xy += UVTransformParams.zw; +vec2 $SLOT_NAME$UV() { + vec2 value = $UV_VAR_NAME$; + value.xy *= $SLOT_NAME$UVTransformParams.xy; + value.xy += $SLOT_NAME$UVTransformParams.zw; return value; } diff --git a/src/renderers/shaders/ShaderChunk/specularmap_fragment.glsl b/src/renderers/shaders/ShaderChunk/specularmap_fragment.glsl index 8afac608c5ee00..8f35703c61c2d8 100644 --- a/src/renderers/shaders/ShaderChunk/specularmap_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/specularmap_fragment.glsl @@ -2,11 +2,17 @@ float specularStrength; #ifdef USE_SPECULARMAP - vec4 texelSpecular = texture2D( specularMap, vUv ); + #if defined( TEXTURE_SLOTS ) + vec2 specularUv = specularMapUV(); + #else + vec2 specularUv = vUv; + #endif + + vec4 texelSpecular = specularMapTexelTransform( texture2D( specularMap, specularUv ) ); specularStrength = texelSpecular.r; #else specularStrength = 1.0; -#endif \ No newline at end of file +#endif diff --git a/src/renderers/shaders/ShaderChunk/specularmap_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/specularmap_pars_fragment.glsl index 3df2e4269f6ddb..2916f326d64776 100644 --- a/src/renderers/shaders/ShaderChunk/specularmap_pars_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/specularmap_pars_fragment.glsl @@ -1,5 +1,7 @@ -#ifdef USE_SPECULARMAP +#if ! defined( TEXTURE_SLOTS ) + #ifdef USE_SPECULARMAP - uniform sampler2D specularMap; + uniform sampler2D specularMap; -#endif \ No newline at end of file + #endif +#endif diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js index 7fdfde61b5d0fc..d807c376893e27 100644 --- a/src/renderers/webgl/WebGLProgram.js +++ b/src/renderers/webgl/WebGLProgram.js @@ -58,7 +58,7 @@ THREE.WebGLProgram = ( function () { var transform = slot.getFlattenedTexelTransform(); var template = THREE.ShaderChunk[ 'slot_texel_transform_template' ]; - var result = template.replace( "", slot.name ); + var result = template.replace( /\$SLOT_NAME\$/g, slotName ); return result; } @@ -75,9 +75,9 @@ THREE.WebGLProgram = ( function () { } var transform = slot.getFlattenedTexelTransform(); - var template = THREE.ShaderChunk[ 'slot_texel_transform_template' ]; - var result = template.replace( "", slot.name ); - result = result.replace( "", uvVariableName ); + var template = THREE.ShaderChunk[ 'slot_uv_transform_template' ]; + var result = template.replace( /\$SLOT_NAME\$/g, slotName ); + result = result.replace( /\$UV_VAR_NAME\$/g, uvVariableName ); return result; } @@ -576,30 +576,31 @@ THREE.WebGLProgram = ( function () { ].filter( filterEmptyLine ).join( '\n' ); - var slotCode = ""; + var slotUVChannelsCode = ""; + var slotTexelTransformCode = ""; var slotUvChannels = []; for( var i = 0; i < supportedSlots.length; i ++ ) { var slotName = supportedSlots[i]; var slot = material[ slotName + 'Slot' ]; if( slot || material[ slotName ] ) { if( slot && ! slotUvChannels[ slot.uvChannel ]) slotUvChannels[ slot.uvChannel ] = true; - slotCode += getTexelTransformFunction( slotName, slot ); - slotCode += getUVFunction( slotName, slot, false ); + slotTexelTransformCode += getTexelTransformFunction( slotName, slot ); + slotUVChannelsCode += "uniform sampler2D " + slotName + ";\n"; + slotUVChannelsCode += getUVFunction( slotName, slot, false ); } } if( Object.keys( slotUvChannels ).length > 0 ) { - var slotPrefix = ""; - slotPrefix += "#define TEXTURE_SLOTS\n"; + var slotUVPrefix = ""; + slotUVPrefix += "#define TEXTURE_SLOTS\n"; for( var uvChannel in slotUvChannels ) { uvChannel = parseInt( uvChannel ); var uvChannelName = "vUv"; if( uvChannel > 0 ) uvChannelName += '' + ( uvChannel + 1 ); - slotPrefix += "varying vec2 " + uvChannelName + ";\n"; + slotUVPrefix += "varying vec2 " + uvChannelName + ";\n"; } - console.log( slotPrefix ); - console.log( slotCode ); - prefixFragment += slotPrefix + slotCode; + prefixFragment += slotUVPrefix + slotUVChannelsCode; } + prefixFragment += slotTexelTransformCode; } vertexShader = parseIncludes( vertexShader, parameters ); From 5d4a1860e34d3497a97815717a5773b1a95461bf Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 2 Mar 2016 15:11:17 -0500 Subject: [PATCH 06/21] fix cut and paste mistake. --- src/materials/MeshStandardMaterial.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/materials/MeshStandardMaterial.js b/src/materials/MeshStandardMaterial.js index 43fa11934d9b4f..8670159ac5bc90 100644 --- a/src/materials/MeshStandardMaterial.js +++ b/src/materials/MeshStandardMaterial.js @@ -191,11 +191,11 @@ var closure = function () { }, "bumpScale": { get: function() { - return this.emissiveMapSlot.texelScale; + return this.bumpMapSlot.texelScale; }, set: function( value ) { - this.emissiveMapSlot.texelTransform = true; - this.emissiveMapSlot.texelScale = value; + this.bumpMapSlot.texelTransform = true; + this.bumpMapSlot.texelScale = value; } }, "normalMap": { From 4a41dc6c70c1a23759b4ec882543e7b03e961785 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 2 Mar 2016 15:17:53 -0500 Subject: [PATCH 07/21] allow slows to work on all materials. set parameters. --- src/renderers/WebGLRenderer.js | 35 ++++++++++++-- .../ShaderChunk/metalnessmap_fragment.glsl | 2 +- .../ShaderChunk/uv2_pars_fragment.glsl | 8 ++-- src/renderers/shaders/UniformsLib.js | 38 ++++++++++++--- src/renderers/webgl/WebGLProgram.js | 47 ++++++++++--------- 5 files changed, 92 insertions(+), 38 deletions(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index e1cbf7de62aad2..1b48abd794b737 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -1894,6 +1894,10 @@ THREE.WebGLRenderer = function ( parameters ) { // Uniforms (refresh uniforms objects) + var supportedSlots = [ + 'map', 'lightMap', 'aoMap', 'emissiveMap', 'specularMap', 'bumpMap', 'normalMap', 'roughnessMap', 'metalnessMap', 'alphaMap' + ]; + function refreshUniformsCommon ( uniforms, material ) { uniforms.opacity.value = material.opacity; @@ -1906,13 +1910,36 @@ THREE.WebGLRenderer = function ( parameters ) { } - uniforms.map.value = material.map; - uniforms.specularMap.value = material.specularMap; - uniforms.alphaMap.value = material.alphaMap; + for( var i = 0; i < supportedSlots.length; i ++ ) { + var slotName = supportedSlots[i]; + var slot = material[ slotName + 'Slot' ]; + if( slot ) { + uniforms[slotName].value = slot.texture; + if( slot.uvTransform ) { + uniforms[slotName +"UVTransformParams"].value.set( + slot.uvOffset.x, + slot.uvOffset.y, + slot.uvRepeat.x, + slot.uvRepeat.y ); + } + if( slot.texelTransform ) { + var texelTransform = slot.getFlattenedTexelTransform(); + uniforms[slotName +"TexelTransformParams"].value.set( + texelTransform.texelScale, + texelTransform.texelOffset ); + } + } + else if( material[ slotName ] ) { + uniforms[slotName].value = material[slotName]; + } + } + //uniforms.map.value = material.map; + //uniforms.specularMap.value = material.specularMap; + //uniforms.alphaMap.value = material.alphaMap; if ( material.aoMap ) { - uniforms.aoMap.value = material.aoMap; + //uniforms.aoMap.value = material.aoMap; uniforms.aoMapIntensity.value = material.aoMapIntensity; } diff --git a/src/renderers/shaders/ShaderChunk/metalnessmap_fragment.glsl b/src/renderers/shaders/ShaderChunk/metalnessmap_fragment.glsl index 423752cf3ad3f5..1a3124e93884d8 100644 --- a/src/renderers/shaders/ShaderChunk/metalnessmap_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/metalnessmap_fragment.glsl @@ -8,7 +8,7 @@ float metalnessFactor = metalness; vec2 metalnessUv = vUv; #endif - vec4 texelMetalness = metalnessTexelTransform( texture2D( metalnessMap, metalnessUv ) ); + vec4 texelMetalness = metalnessMapTexelTransform( texture2D( metalnessMap, metalnessUv ) ); metalnessFactor *= texelMetalness.r; #endif diff --git a/src/renderers/shaders/ShaderChunk/uv2_pars_fragment.glsl b/src/renderers/shaders/ShaderChunk/uv2_pars_fragment.glsl index 37274dbbfbaecf..ea343ad7ea5669 100644 --- a/src/renderers/shaders/ShaderChunk/uv2_pars_fragment.glsl +++ b/src/renderers/shaders/ShaderChunk/uv2_pars_fragment.glsl @@ -1,5 +1,7 @@ -#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP ) +#if ! defined( TEXTURE_SLOTS ) + #if defined( USE_LIGHTMAP ) || defined( USE_AOMAP ) - varying vec2 vUv2; + varying vec2 vUv2; -#endif \ No newline at end of file + #endif +#endif diff --git a/src/renderers/shaders/UniformsLib.js b/src/renderers/shaders/UniformsLib.js index d50f89fad55827..f3e1e801d3a1bf 100644 --- a/src/renderers/shaders/UniformsLib.js +++ b/src/renderers/shaders/UniformsLib.js @@ -10,10 +10,17 @@ THREE.UniformsLib = { "opacity": { type: "f", value: 1.0 }, "map": { type: "t", value: null }, + "mapUVTransformParams": { type: "v4", value: new THREE.Vector4( 0, 0, 1, 1 ) }, + "mapTexelTransformParams": { type: "v2", value: new THREE.Vector2( 1, 0 ) }, "offsetRepeat": { type: "v4", value: new THREE.Vector4( 0, 0, 1, 1 ) }, "specularMap": { type: "t", value: null }, + "specularMapUVTransformParams": { type: "v4", value: new THREE.Vector4( 0, 0, 1, 1 ) }, + "specularMapTexelTransformParams": { type: "v2", value: new THREE.Vector2( 1, 0 ) }, + "alphaMap": { type: "t", value: null }, + "alphaMapUVTransformParams": { type: "v4", value: new THREE.Vector4( 0, 0, 1, 1 ) }, + "alphaMapTexelTransformParams": { type: "v2", value: new THREE.Vector2( 1, 0 ) }, "envMap": { type: "t", value: null }, "flipEnvMap": { type: "f", value: - 1 }, @@ -25,6 +32,8 @@ THREE.UniformsLib = { aomap: { "aoMap": { type: "t", value: null }, + "aoMapUVTransformParams": { type: "v4", value: new THREE.Vector4( 0, 0, 1, 1 ) }, + "aoMapTexelTransformParams": { type: "v2", value: new THREE.Vector2( 1, 0 ) }, "aoMapIntensity": { type: "f", value: 1 } }, @@ -32,47 +41,62 @@ THREE.UniformsLib = { lightmap: { "lightMap": { type: "t", value: null }, + "lightMapUVTransformParams": { type: "v4", value: new THREE.Vector4( 0, 0, 1, 1 ) }, + "lightMapTexelTransformParams": { type: "v2", value: new THREE.Vector2( 1, 0 ) }, "lightMapIntensity": { type: "f", value: 1 } }, emissivemap: { - "emissiveMap": { type: "t", value: null } + "emissiveMap": { type: "t", value: null }, + "emissiveMapUVTransformParams": { type: "v4", value: new THREE.Vector4( 0, 0, 1, 1 ) }, + "emissiveMapTexelTransformParams": { type: "v2", value: new THREE.Vector2( 1, 0 ) } }, bumpmap: { "bumpMap": { type: "t", value: null }, - "bumpScale": { type: "f", value: 1 } + "bumpScale": { type: "f", value: 1 }, // for backwards compatibility + "bumpMapUVTransformParams": { type: "v4", value: new THREE.Vector4( 0, 0, 1, 1 ) }, + "bumpMapTexelTransformParams": { type: "v2", value: new THREE.Vector2( 1, 0 ) } }, normalmap: { "normalMap": { type: "t", value: null }, - "normalScale": { type: "v2", value: new THREE.Vector2( 1, 1 ) } + "normalScale": { type: "v2", value: new THREE.Vector2( 1, 1 ) }, // for backwards compatibility + "normalScale": { type: "v2", value: new THREE.Vector2( 1, 1 ) }, + "normalMapUVTransformParams": { type: "v4", value: new THREE.Vector4( 0, 0, 1, 1 ) }, + "normalMapTexelTransformParams": { type: "v2", value: new THREE.Vector2( 1, 0 ) } }, displacementmap: { "displacementMap": { type: "t", value: null }, - "displacementScale": { type: "f", value: 1 }, - "displacementBias": { type: "f", value: 0 } + "displacementScale": { type: "f", value: 1 }, // for backwards compatibility + "displacementBias": { type: "f", value: 0 }, // for backwards compatibility + "displacementMapUVTransformParams": { type: "v4", value: new THREE.Vector4( 0, 0, 1, 1 ) }, + "displacementMapTexelTransformParams": { type: "v2", value: new THREE.Vector2( 1, 0 ) } }, roughnessmap: { - "roughnessMap": { type: "t", value: null } + "roughnessMap": { type: "t", value: null }, + "roughnessMapUVTransformParams": { type: "v4", value: new THREE.Vector4( 0, 0, 1, 1 ) }, + "roughnessMapTexelTransformParams": { type: "v2", value: new THREE.Vector2( 1, 0 ) } }, metalnessmap: { - "metalnessMap": { type: "t", value: null } + "metalnessMap": { type: "t", value: null }, + "metalnessMapUVTransformParams": { type: "v4", value: new THREE.Vector4( 0, 0, 1, 1 ) }, + "metalnessMapTexelTransformParams": { type: "v2", value: new THREE.Vector2( 1, 0 ) } }, diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js index d807c376893e27..6ba61499545539 100644 --- a/src/renderers/webgl/WebGLProgram.js +++ b/src/renderers/webgl/WebGLProgram.js @@ -575,33 +575,34 @@ THREE.WebGLProgram = ( function () { '\n' ].filter( filterEmptyLine ).join( '\n' ); + } - var slotUVChannelsCode = ""; - var slotTexelTransformCode = ""; - var slotUvChannels = []; - for( var i = 0; i < supportedSlots.length; i ++ ) { - var slotName = supportedSlots[i]; - var slot = material[ slotName + 'Slot' ]; - if( slot || material[ slotName ] ) { - if( slot && ! slotUvChannels[ slot.uvChannel ]) slotUvChannels[ slot.uvChannel ] = true; - slotTexelTransformCode += getTexelTransformFunction( slotName, slot ); - slotUVChannelsCode += "uniform sampler2D " + slotName + ";\n"; - slotUVChannelsCode += getUVFunction( slotName, slot, false ); - } + + var slotUVChannelsCode = ""; + var slotTexelTransformCode = ""; + var slotUvChannels = []; + for( var i = 0; i < supportedSlots.length; i ++ ) { + var slotName = supportedSlots[i]; + var slot = material[ slotName + 'Slot' ]; + if( material[ slotName ] || ( slot && slot.texture ) ) { + if( slot && ! slotUvChannels[ slot.uvChannel ]) slotUvChannels[ slot.uvChannel ] = true; + slotTexelTransformCode += getTexelTransformFunction( slotName, slot ); + slotUVChannelsCode += "uniform sampler2D " + slotName + ";\n"; + slotUVChannelsCode += getUVFunction( slotName, slot, false ); } - if( Object.keys( slotUvChannels ).length > 0 ) { - var slotUVPrefix = ""; - slotUVPrefix += "#define TEXTURE_SLOTS\n"; - for( var uvChannel in slotUvChannels ) { - uvChannel = parseInt( uvChannel ); - var uvChannelName = "vUv"; - if( uvChannel > 0 ) uvChannelName += '' + ( uvChannel + 1 ); - slotUVPrefix += "varying vec2 " + uvChannelName + ";\n"; - } - prefixFragment += slotUVPrefix + slotUVChannelsCode; + } + if( Object.keys( slotUvChannels ).length > 0 ) { + var slotUVPrefix = ""; + slotUVPrefix += "#define TEXTURE_SLOTS\n"; + for( var uvChannel in slotUvChannels ) { + uvChannel = parseInt( uvChannel ); + var uvChannelName = "vUv"; + if( uvChannel > 0 ) uvChannelName += '' + ( uvChannel + 1 ); + slotUVPrefix += "varying vec2 " + uvChannelName + ";\n"; } - prefixFragment += slotTexelTransformCode; + prefixFragment += slotUVPrefix + slotUVChannelsCode; } + prefixFragment += slotTexelTransformCode; vertexShader = parseIncludes( vertexShader, parameters ); vertexShader = replaceLightNums( vertexShader, parameters ); From a230324828d3f70414af6f50341724b242805197 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 2 Mar 2016 15:30:40 -0500 Subject: [PATCH 08/21] comment out feature not yet implemented. --- src/materials/TextureSlot.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/materials/TextureSlot.js b/src/materials/TextureSlot.js index d24942361b57e0..d4d6eb9c9d40db 100644 --- a/src/materials/TextureSlot.js +++ b/src/materials/TextureSlot.js @@ -14,7 +14,7 @@ THREE.TextureSlot = function ( name, uvChannel, uvTransform, texelTransform ) { this.uvTransform = uvTransform || false; this.uvOffset = new THREE.Vector2( 0, 0 ); this.uvRepeat = new THREE.Vector2( 1.0, 1.0 ); - this.uvRotation = 0; + //this.uvRotation = 0; this.texelTransform = uvTransform || false; this.texelScale = 1.0; @@ -38,7 +38,7 @@ THREE.TextureSlot.prototype = { this.uvTransform = source.uvTransform; this.uvOffset = source.uvOffset; this.uvRepeat = source.uvRepeat; - this.uvRotation = source.uvRotation; + //this.uvRotation = source.uvRotation; this.texelTransform = source.texelTransform; this.texelScale = source.texelScale; From 92850e9ef7674a25fa99b573802d2b4ef51233ab Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 2 Mar 2016 15:34:50 -0500 Subject: [PATCH 09/21] only defined the supported slots once. --- src/materials/TextureSlot.js | 4 ++++ src/renderers/WebGLRenderer.js | 5 +---- src/renderers/webgl/WebGLProgram.js | 6 ++---- src/renderers/webgl/WebGLPrograms.js | 7 +++---- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/materials/TextureSlot.js b/src/materials/TextureSlot.js index d4d6eb9c9d40db..cea17d77a1f576 100644 --- a/src/materials/TextureSlot.js +++ b/src/materials/TextureSlot.js @@ -65,3 +65,7 @@ THREE.TextureSlot.prototype = { } }; + +THREE.TextureSlot.SupportedSlotNames = [ + 'map', 'lightMap', 'aoMap', 'emissiveMap', 'specularMap', 'bumpMap', 'normalMap', 'roughnessMap', 'metalnessMap', 'alphaMap' +]; diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index 1b48abd794b737..df89a0a29c3780 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -1894,10 +1894,6 @@ THREE.WebGLRenderer = function ( parameters ) { // Uniforms (refresh uniforms objects) - var supportedSlots = [ - 'map', 'lightMap', 'aoMap', 'emissiveMap', 'specularMap', 'bumpMap', 'normalMap', 'roughnessMap', 'metalnessMap', 'alphaMap' - ]; - function refreshUniformsCommon ( uniforms, material ) { uniforms.opacity.value = material.opacity; @@ -1910,6 +1906,7 @@ THREE.WebGLRenderer = function ( parameters ) { } + var supportedSlots = THREE.TextureSlot.SupportedSlotNames; for( var i = 0; i < supportedSlots.length; i ++ ) { var slotName = supportedSlots[i]; var slot = material[ slotName + 'Slot' ]; diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js index 6ba61499545539..ef89e0bc07c83c 100644 --- a/src/renderers/webgl/WebGLProgram.js +++ b/src/renderers/webgl/WebGLProgram.js @@ -7,10 +7,6 @@ THREE.WebGLProgram = ( function () { var arrayStructRe = /^([\w\d_]+)\[(\d+)\]\.([\w\d_]+)$/; var arrayRe = /^([\w\d_]+)\[0\]$/; - var supportedSlots = [ - 'map', 'lightMap', 'aoMap', 'emissiveMap', 'specularMap', 'bumpMap', 'normalMap', 'roughnessMap', 'metalnessMap', 'alphaMap' - ]; - function getEncodingComponents( encoding ) { switch ( encoding ) { @@ -578,6 +574,8 @@ THREE.WebGLProgram = ( function () { } + var supportedSlots = THREE.TextureSlot.SupportedSlotNames; + var slotUVChannelsCode = ""; var slotTexelTransformCode = ""; var slotUvChannels = []; diff --git a/src/renderers/webgl/WebGLPrograms.js b/src/renderers/webgl/WebGLPrograms.js index 0841e93f572811..698fabe8694c3c 100644 --- a/src/renderers/webgl/WebGLPrograms.js +++ b/src/renderers/webgl/WebGLPrograms.js @@ -14,10 +14,6 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) { PointsMaterial: 'points' }; - var supportedSlots = [ - 'map', 'lightMap', 'aoMap', 'emissiveMap', 'specularMap', 'bumpMap', 'normalMap', 'roughnessMap', 'metalnessMap', 'alphaMap' - ]; - var parameterNames = [ "precision", "supportsVertexTextures", "mapEncoding", "envMap", "envMapMode", "envMapEncoding", "emissiveMapEncoding", @@ -31,6 +27,7 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) { "alphaTest", "doubleSided", "flipSided" ]; + var supportedSlots = THREE.TextureSlot.SupportedSlotNames; for( var i = 0; i < supportedSlots.length; i ++ ) { var name = supportedSlots[i]; parameterNames.push( name ); @@ -183,6 +180,8 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) { }; + var supportedSlots = THREE.TextureSlot.SupportedSlotNames; + for( var i = 0; i < supportedSlots.length; i ++ ) { var name = supportedSlots[i]; // backwards compatibility From 6d67678e6f4c04c94c0930979021cc9fb070da60 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 2 Mar 2016 15:37:20 -0500 Subject: [PATCH 10/21] other PR leaking into this one. --- src/materials/MeshStandardMaterial.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/materials/MeshStandardMaterial.js b/src/materials/MeshStandardMaterial.js index 8670159ac5bc90..772c78780605bd 100644 --- a/src/materials/MeshStandardMaterial.js +++ b/src/materials/MeshStandardMaterial.js @@ -118,7 +118,7 @@ THREE.MeshStandardMaterial = function ( parameters ) { this.fog = true; this.shading = THREE.SmoothShading; - this.blending = THREE.PremultipliedAlphaNormalBlending; + this.blending = THREE.PremultipliedAlphaBlending; this.wireframe = false; this.wireframeLinewidth = 1; From d829a1d28223a18c411eae03ba4a3021f3d34cb2 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 2 Mar 2016 15:43:33 -0500 Subject: [PATCH 11/21] forgotten 'displacementMap' texture slot name. --- src/materials/TextureSlot.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/materials/TextureSlot.js b/src/materials/TextureSlot.js index cea17d77a1f576..ff7ae69d7c52f6 100644 --- a/src/materials/TextureSlot.js +++ b/src/materials/TextureSlot.js @@ -67,5 +67,5 @@ THREE.TextureSlot.prototype = { }; THREE.TextureSlot.SupportedSlotNames = [ - 'map', 'lightMap', 'aoMap', 'emissiveMap', 'specularMap', 'bumpMap', 'normalMap', 'roughnessMap', 'metalnessMap', 'alphaMap' + 'map', 'lightMap', 'aoMap', 'emissiveMap', 'specularMap', 'bumpMap', 'normalMap', 'roughnessMap', 'metalnessMap', 'alphaMap', 'displacementMap' ]; From 9b17d3fbcd6c94cf19ef9dd0da848a2d4dddceca Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 2 Mar 2016 20:16:47 -0500 Subject: [PATCH 12/21] remove duplicate map entry. --- src/renderers/shaders/UniformsLib.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/renderers/shaders/UniformsLib.js b/src/renderers/shaders/UniformsLib.js index f3e1e801d3a1bf..b447ae893fe52f 100644 --- a/src/renderers/shaders/UniformsLib.js +++ b/src/renderers/shaders/UniformsLib.js @@ -68,7 +68,6 @@ THREE.UniformsLib = { "normalMap": { type: "t", value: null }, "normalScale": { type: "v2", value: new THREE.Vector2( 1, 1 ) }, // for backwards compatibility - "normalScale": { type: "v2", value: new THREE.Vector2( 1, 1 ) }, "normalMapUVTransformParams": { type: "v4", value: new THREE.Vector4( 0, 0, 1, 1 ) }, "normalMapTexelTransformParams": { type: "v2", value: new THREE.Vector2( 1, 0 ) } From db208806de700605de8fb85210a2150b31214f28 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 2 Mar 2016 21:15:59 -0500 Subject: [PATCH 13/21] better organization of mesh standard material. --- src/materials/MeshStandardMaterial.js | 51 ++++++++++++++------------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/src/materials/MeshStandardMaterial.js b/src/materials/MeshStandardMaterial.js index 772c78780605bd..67dde440f0736c 100644 --- a/src/materials/MeshStandardMaterial.js +++ b/src/materials/MeshStandardMaterial.js @@ -66,19 +66,16 @@ THREE.MeshStandardMaterial = function ( parameters ) { this.type = 'MeshStandardMaterial'; this.color = new THREE.Color( 0xffffff ); // diffuse - this.roughness = 0.5; - this.metalness = 0.5; - //this.map = null; this.mapSlot = new THREE.TextureSlot( "map", 0, false, false ); - //this.lightMap = null; - //this.lightMapIntensity = 1.0; - this.lightMapSlot = new THREE.TextureSlot( "lightMap", 1, false, true ); + this.roughness = 0.5; + //this.roughnessMap = null; + this.roughnessMapSlot = new THREE.TextureSlot( "roughnessMap", 0, false, false ); - //this.aoMap = null; - this.aoMapIntensity = 1.0; - this.aoMapSlot = new THREE.TextureSlot( "aoMap", 1, false, true ); + this.metalness = 0.5; + //this.metalnessMap = null; + this.metalnessMapSlot = new THREE.TextureSlot( "metalnessMap", 0, false, false ); this.emissive = new THREE.Color( 0x000000 ); this.emissiveIntensity = 1.0; @@ -98,18 +95,17 @@ THREE.MeshStandardMaterial = function ( parameters ) { //this.displacementBias = 0; this.displacementMapSlot = new THREE.TextureSlot( "displacementMap", 0, false, true ); - //this.roughnessMap = null; - this.roughnessMapSlot = new THREE.TextureSlot( "roughnessMap", 0, false, false ); + //this.lightMap = null; + //this.lightMapIntensity = 1.0; + this.lightMapSlot = new THREE.TextureSlot( "lightMap", 1, false, true ); - //this.metalnessMap = null; - this.metalnessMapSlot = new THREE.TextureSlot( "metalnessMap", 0, false, false ); + //this.aoMap = null; + this.aoMapIntensity = 1.0; + this.aoMapSlot = new THREE.TextureSlot( "aoMap", 1, false, true ); //this.alphaMap = null; this.alphaMapSlot = new THREE.TextureSlot( "alphaMap", 0, false, false ); - //this.slots = [ this.mapSlot, this.lightMapSlot, this.aoMapSlot, this.emissiveMapSlot, this.bumpMapSlot, - // this.normalMapSlot, this.roughnessMapSlot, this.metalnessMapSlot, this.alphaMapSlot ]; - this.envMap = null; this.envMapIntensity = 1.0; @@ -267,24 +263,31 @@ THREE.MeshStandardMaterial.prototype.copy = function ( source ) { THREE.Material.prototype.copy.call( this, source ); this.color.copy( source.color ); + this.mapSlot.copy( source.mapSlot ); + this.roughness = source.roughness; + this.roughnessMapSlot.copy( source.roughnessMapSlot ); + this.metalness = source.metalness; + this.metalnessMapSlot.copy( source.metalnessMapSlot ); - this.mapSlot.copy( source.mapSlot ); this.lightMapSlot.copy( source.lightMapSlot ); + + this.aoMapIntensity = source.aoMapIntensity; this.aoMapSlot.copy( source.aoMapSlot ); - this.emissiveMapSlot.copy( source.emissiveMapSlot ); - this.bumpMapSlot.copy( source.bumpMapSlot ); - this.normalMapSlot.copy( source.normalMapSlot ); - this.displacementMapSlot.copy( source.displacementMapSlot ); - this.roughnessMapSlot.copy( source.roughnessMapSlot ); - this.metalnessMapSlot.copy( source.metalnessMapSlot ); - this.alphaMapSlot.copy( source.alphaMapSlot ); this.emissive.copy( source.emissive ); this.emissiveIntensity = source.emissiveIntensity; + this.emissiveMapSlot.copy( source.emissiveMapSlot ); + + this.bumpMapSlot.copy( source.bumpMapSlot ); this.normalScale.copy( source.normalScale ); + this.normalMapSlot.copy( source.normalMapSlot ); + + this.displacementMapSlot.copy( source.displacementMapSlot ); + + this.alphaMapSlot.copy( source.alphaMapSlot ); this.envMap = source.envMap; this.envMapIntensity = source.envMapIntensity; From c1baf2228f722a67c3cfd96be43abdba25165d52 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 2 Mar 2016 21:16:22 -0500 Subject: [PATCH 14/21] fix ordering of uvrepeat/uvoffset when loading TextureSlot uniforms. --- src/renderers/WebGLRenderer.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/renderers/WebGLRenderer.js b/src/renderers/WebGLRenderer.js index df89a0a29c3780..19098adb8527a6 100644 --- a/src/renderers/WebGLRenderer.js +++ b/src/renderers/WebGLRenderer.js @@ -1914,10 +1914,10 @@ THREE.WebGLRenderer = function ( parameters ) { uniforms[slotName].value = slot.texture; if( slot.uvTransform ) { uniforms[slotName +"UVTransformParams"].value.set( - slot.uvOffset.x, - slot.uvOffset.y, slot.uvRepeat.x, - slot.uvRepeat.y ); + slot.uvRepeat.y, + slot.uvOffset.x, + slot.uvOffset.y ); } if( slot.texelTransform ) { var texelTransform = slot.getFlattenedTexelTransform(); From 708268ae8ad863671ac6e795dc19038eac9f4dbd Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 2 Mar 2016 21:18:39 -0500 Subject: [PATCH 15/21] add texture slot example. --- examples/webgl_materials_slots.html | 309 ++++++++++++++++++++++++++++ 1 file changed, 309 insertions(+) create mode 100644 examples/webgl_materials_slots.html diff --git a/examples/webgl_materials_slots.html b/examples/webgl_materials_slots.html new file mode 100644 index 00000000000000..8524f75eb0f7d8 --- /dev/null +++ b/examples/webgl_materials_slots.html @@ -0,0 +1,309 @@ + + + + threejs webgl - inline tone mapping + + + + + + +
+
threejs - Per-Map Per-Material UV Repeat/Offset, Texel Scale/Offset via
THREE.TextureSlot by Ben Houston.
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From e7afdef3b70d30c064beed7707e67cb39054dc3c Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 2 Mar 2016 21:25:49 -0500 Subject: [PATCH 16/21] polishing example. --- examples/webgl_materials_slots.html | 30 ++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/examples/webgl_materials_slots.html b/examples/webgl_materials_slots.html index 8524f75eb0f7d8..c17a65c2656dbb 100644 --- a/examples/webgl_materials_slots.html +++ b/examples/webgl_materials_slots.html @@ -29,7 +29,7 @@
-
threejs - Per-Map Per-Material UV Repeat/Offset, Texel Scale/Offset via
THREE.TextureSlot by Ben Houston.
+
threejs - Per-Map Per-Material UV Repeat/Offset, Texel Scale/Offset/Invert
via THREE.TextureSlot by Ben Houston.
@@ -212,7 +212,7 @@ var slotParams = function( slotName ) { params[ slotName + 'TexelInvert'] = false; gui.add( params, slotName + 'TexelInvert' ); - if( slotName === "bumpMap" ) { + if( slotName === "bump" ) { params[ slotName + 'TexelOffset'] = 0; params[ slotName + 'TexelScale'] = 0.05; gui.add( params, slotName + 'TexelScale', -0.1, 0.1 ); @@ -233,8 +233,8 @@ gui.add( params, slotName + 'UVRepeatY', -5, 5 ); }; slotParams( "map" ); - slotParams( "bumpMap" ); - slotParams( "roughnessMap" ); + slotParams( "bump" ); + slotParams( "rough" ); gui.open(); } @@ -267,20 +267,20 @@ if ( standardMaterial !== undefined ) { - var setSlot = function( slot ) { + var setSlot = function( slot, name ) { slot.texelTransform = true; - slot.texelScale = params[ slot.name + 'TexelScale']; - slot.texelOffset = params[ slot.name + 'TexelOffset']; - slot.texelInvert = params[ slot.name + 'TexelInvert']; + slot.texelScale = params[ name + 'TexelScale']; + slot.texelOffset = params[ name + 'TexelOffset']; + slot.texelInvert = params[ name + 'TexelInvert']; slot.uvTransform = true; - slot.uvRepeat.x = params[ slot.name + 'UVRepeatX']; - slot.uvRepeat.y = params[ slot.name + 'UVRepeatY']; - slot.uvOffset.x = params[ slot.name + 'UVOffsetX']; - slot.uvOffset.y = params[ slot.name + 'UVOffsetY']; + slot.uvRepeat.x = params[ name + 'UVRepeatX']; + slot.uvRepeat.y = params[ name + 'UVRepeatY']; + slot.uvOffset.x = params[ name + 'UVOffsetX']; + slot.uvOffset.y = params[ name + 'UVOffsetY']; } - setSlot( standardMaterial.mapSlot ); - setSlot( standardMaterial.bumpMapSlot ); - setSlot( standardMaterial.roughnessMapSlot ); + setSlot( standardMaterial.mapSlot, "map" ); + setSlot( standardMaterial.bumpMapSlot, "bump" ); + setSlot( standardMaterial.roughnessMapSlot, "rough" ); } var timer = Date.now() * 0.00025; From 7c782a1d4ffd5b4d74b53ddb25dd1d2a255e3790 Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 2 Mar 2016 21:50:48 -0500 Subject: [PATCH 17/21] more example tweaking to get something decent. --- examples/webgl_materials_slots.html | 70 ++++++++++++++--------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/examples/webgl_materials_slots.html b/examples/webgl_materials_slots.html index c17a65c2656dbb..09c313e3b87614 100644 --- a/examples/webgl_materials_slots.html +++ b/examples/webgl_materials_slots.html @@ -75,7 +75,7 @@ document.body.appendChild( container ); camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 2000 ); - camera.position.set( 0.0, 40, 40 * 3.5 ); + camera.position.set( 0.0, 80, 40 * 3.5 ); scene = new THREE.Scene(); @@ -85,40 +85,47 @@ standardMaterial = new THREE.MeshStandardMaterial( { bumpScale: - 0.05, color: 0xffffff, + emissive: 0xffffff, metalness: 0.9, roughness: 0.8, + normalScale: new THREE.Vector2( 1, -1 ), shading: THREE.SmoothShading, transparent: true, blending: THREE.PremultipliedAlphaBlending } ); var textureLoader = new THREE.TextureLoader(); - textureLoader.load( "../examples/textures/brick_diffuse.jpg", function( map ) { + textureLoader.load( "../examples/textures/planets/earth_atmos_2048.jpg", function( map ) { map.wrapS = THREE.RepeatWrapping; map.wrapT = THREE.RepeatWrapping; map.anisotropy = 4; - standardMaterial.mapSlot.uvRepeat.set( 9, 0.5 ); standardMaterial.map = map; standardMaterial.needsUpdate = true; } ); - textureLoader.load( "../examples/textures/brick_bump.jpg", function( map ) { + textureLoader.load( "../examples/textures/planets/earth_normal_2048.jpg", function( map ) { map.wrapS = THREE.RepeatWrapping; map.wrapT = THREE.RepeatWrapping; map.anisotropy = 4; - standardMaterial.bumpMapSlot.uvRepeat.set( 9, 0.5 ); - standardMaterial.bumpMap = map; + standardMaterial.normalMap = map; standardMaterial.needsUpdate = true; } ); - textureLoader.load( "../examples/textures/brick_roughness.jpg", function( map ) { + textureLoader.load( "../examples/textures/planets/earth_specular_2048.jpg", function( map ) { map.wrapS = THREE.RepeatWrapping; map.wrapT = THREE.RepeatWrapping; map.anisotropy = 4; - standardMaterial.roughnessMapSlot.uvRepeat.set( 9, 0.5 ); standardMaterial.roughnessMap = map; standardMaterial.needsUpdate = true; } ); + textureLoader.load( "../examples/textures/planets/earth_lights_2048.png", function( map ) { + map.wrapS = THREE.RepeatWrapping; + map.wrapT = THREE.RepeatWrapping; + map.anisotropy = 4; + standardMaterial.emissiveMap = map; + standardMaterial.needsUpdate = true; + } ); + - var geometry = new THREE.TorusKnotGeometry( 18, 8, 150, 20 );; + var geometry = new THREE.SphereGeometry( 35, 36, 36 ); var torusMesh1 = new THREE.Mesh( geometry, standardMaterial ); torusMesh1.position.x = 0.0; torusMesh1.castShadow = true; @@ -126,22 +133,6 @@ scene.add( torusMesh1 ); objects.push( torusMesh1 ); - floorMaterial = new THREE.MeshStandardMaterial( { - map: null, - roughnessMap: null, - color: 0xffffff, - metalness: 0.0, - roughness: 0.0, - shading: THREE.SmoothShading - } ); - - var planeGeometry = new THREE.PlaneBufferGeometry( 200, 200 ); - var planeMesh1 = new THREE.Mesh( planeGeometry, floorMaterial ); - planeMesh1.position.y = - 50; - planeMesh1.rotation.x = - Math.PI * 0.5; - planeMesh1.receiveShadow = true; - scene.add( planeMesh1 ); - // Materials var hdrpath = "../examples/textures/cube/hdrPisa/"; var hdrformat = '.hdr'; @@ -160,6 +151,7 @@ pmremCubeUVPacker.update( renderer ); standardMaterial.envMap = pmremCubeUVPacker.CubeUVRenderTarget; + standardMaterial.envMapIntensity = 3; standardMaterial.needsUpdate = true; } ); @@ -180,6 +172,8 @@ renderer.shadowMap.enabled = true; container.appendChild( renderer.domElement ); + renderer.toneMapping = THREE.ReinhardToneMapping; + renderer.toneMappingExposure = 4; renderer.gammaInput = true; renderer.gammaOutput = true; @@ -210,7 +204,7 @@ params = {}; var slotParams = function( slotName ) { - params[ slotName + 'TexelInvert'] = false; + params[ slotName + 'TexelInvert'] = ( slotName === 'rough' ); gui.add( params, slotName + 'TexelInvert' ); if( slotName === "bump" ) { params[ slotName + 'TexelOffset'] = 0; @@ -218,23 +212,28 @@ gui.add( params, slotName + 'TexelScale', -0.1, 0.1 ); } else { - params[ slotName + 'TexelOffset'] = 0; - gui.add( params, slotName + 'TexelOffset', -1, 1 ); - params[ slotName + 'TexelScale'] = 1; - gui.add( params, slotName + 'TexelScale', -1, 1 ); + params[ slotName + 'TexelOffset'] = ( slotName === 'rough' ) ? 0.4 : 0; + if( slotName === 'rough' ) params[ slotName + 'TexelScale'] = 0.6; + else if( slotName === 'emissive' ) params[ slotName + 'TexelScale'] = 0.3; + else params[ slotName + 'TexelScale'] = 1.0; + if( slotName !== "normal" ) { + gui.add( params, slotName + 'TexelOffset', -1, 1 ); + gui.add( params, slotName + 'TexelScale', -1, 1 ); + } } params[ slotName + 'UVOffsetX'] = 0; gui.add( params, slotName + 'UVOffsetX', 0, 1 ); params[ slotName + 'UVOffsetY'] = 0; gui.add( params, slotName + 'UVOffsetY', 0, 1 ); - params[ slotName + 'UVRepeatX'] = 4; - gui.add( params, slotName + 'UVRepeatX', -5, 5 ); + params[ slotName + 'UVRepeatX'] = 1; + gui.add( params, slotName + 'UVRepeatX', 0.01, 5 ); params[ slotName + 'UVRepeatY'] = 1; - gui.add( params, slotName + 'UVRepeatY', -5, 5 ); + gui.add( params, slotName + 'UVRepeatY', 0.01, 5 ); }; slotParams( "map" ); - slotParams( "bump" ); + slotParams( "normal" ); slotParams( "rough" ); + slotParams( "emissive" ); gui.open(); } @@ -279,8 +278,9 @@ slot.uvOffset.y = params[ name + 'UVOffsetY']; } setSlot( standardMaterial.mapSlot, "map" ); - setSlot( standardMaterial.bumpMapSlot, "bump" ); + setSlot( standardMaterial.normalMapSlot, "normal" ); setSlot( standardMaterial.roughnessMapSlot, "rough" ); + setSlot( standardMaterial.emissiveMapSlot, "emissive" ); } var timer = Date.now() * 0.00025; From 78d4e699843f352011e857697a08632d51d5343c Mon Sep 17 00:00:00 2001 From: Ben Houston Date: Wed, 2 Mar 2016 21:57:36 -0500 Subject: [PATCH 18/21] better title. --- examples/webgl_materials_slots.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/webgl_materials_slots.html b/examples/webgl_materials_slots.html index 09c313e3b87614..8e6aa2e0e33e1d 100644 --- a/examples/webgl_materials_slots.html +++ b/examples/webgl_materials_slots.html @@ -1,7 +1,7 @@ - threejs webgl - inline tone mapping + threejs webgl - per-mat per-material uv offset/repeat and texel scale/offset/invert