From 65019c7217e189de3a68fd34acdb94e43b0c18e1 Mon Sep 17 00:00:00 2001 From: Mr F Date: Thu, 25 Jun 2015 15:48:30 +0300 Subject: [PATCH 1/8] getUniform --- src/graphics/programlib/chunks/normalMap.frag | 2 +- .../programlib/chunks/normalMapFloat.frag | 4 +- .../chunks/normalMapFloatTBNfast.frag | 4 +- .../programlib/chunks/reflectionCube.frag | 4 +- .../programlib/chunks/reflectionDpAtlas.frag | 4 +- .../chunks/reflectionPrefilteredCube.frag | 4 +- .../chunks/reflectionPrefilteredCubeLod.frag | 4 +- .../programlib/chunks/reflectionSphere.frag | 4 +- .../chunks/reflectionSphereLow.frag | 4 +- .../programlib/chunks/refraction.frag | 4 +- .../chunks/specularAaToksvigFloat.frag | 2 +- .../programlib/programlib_programlib.js | 2 +- src/scene/scene_phongmaterial.js | 119 +++++++++++++++--- 13 files changed, 124 insertions(+), 37 deletions(-) diff --git a/src/graphics/programlib/chunks/normalMap.frag b/src/graphics/programlib/chunks/normalMap.frag index 00e430dc498..4eef1169ddf 100644 --- a/src/graphics/programlib/chunks/normalMap.frag +++ b/src/graphics/programlib/chunks/normalMap.frag @@ -1,5 +1,5 @@ uniform sampler2D texture_normalMap; -uniform float material_bumpMapFactor; +uniform float material_bumpiness; void getNormal(inout psInternalData data) { vec3 normalMap = unpackNormal(texture2D(texture_normalMap, $UV)); data.normalMap = normalMap; diff --git a/src/graphics/programlib/chunks/normalMapFloat.frag b/src/graphics/programlib/chunks/normalMapFloat.frag index 0d4e5c45cef..4ecafdaee98 100644 --- a/src/graphics/programlib/chunks/normalMapFloat.frag +++ b/src/graphics/programlib/chunks/normalMapFloat.frag @@ -1,9 +1,9 @@ uniform sampler2D texture_normalMap; -uniform float material_bumpMapFactor; +uniform float material_bumpiness; void getNormal(inout psInternalData data) { vec3 normalMap = unpackNormal(texture2D(texture_normalMap, $UV)); data.normalMap = normalMap; - normalMap = normalize(mix(vec3(0.0, 0.0, 1.0), normalMap, material_bumpMapFactor)); + normalMap = normalize(mix(vec3(0.0, 0.0, 1.0), normalMap, material_bumpiness)); data.normalW = data.TBN * normalMap; } diff --git a/src/graphics/programlib/chunks/normalMapFloatTBNfast.frag b/src/graphics/programlib/chunks/normalMapFloatTBNfast.frag index 184659757e0..cbb10b38a48 100644 --- a/src/graphics/programlib/chunks/normalMapFloatTBNfast.frag +++ b/src/graphics/programlib/chunks/normalMapFloatTBNfast.frag @@ -1,9 +1,9 @@ uniform sampler2D texture_normalMap; -uniform float material_bumpMapFactor; +uniform float material_bumpiness; void getNormal(inout psInternalData data) { vec3 normalMap = unpackNormal(texture2D(texture_normalMap, $UV)); data.normalMap = normalMap; - normalMap = mix(vec3(0.0, 0.0, 1.0), normalMap, material_bumpMapFactor); + normalMap = mix(vec3(0.0, 0.0, 1.0), normalMap, material_bumpiness); data.normalW = normalize(data.TBN * normalMap); } diff --git a/src/graphics/programlib/chunks/reflectionCube.frag b/src/graphics/programlib/chunks/reflectionCube.frag index e7fde0badd9..44d31d73289 100644 --- a/src/graphics/programlib/chunks/reflectionCube.frag +++ b/src/graphics/programlib/chunks/reflectionCube.frag @@ -1,7 +1,7 @@ uniform samplerCube texture_cubeMap; -uniform float material_reflectionFactor; +uniform float material_reflectivity; void addReflection(inout psInternalData data) { vec3 lookupVec = fixSeams(cubeMapProject(data.reflDirW)); lookupVec.x *= -1.0; - data.reflection += vec4($textureCubeSAMPLE(texture_cubeMap, lookupVec).rgb, material_reflectionFactor); + data.reflection += vec4($textureCubeSAMPLE(texture_cubeMap, lookupVec).rgb, material_reflectivity); } diff --git a/src/graphics/programlib/chunks/reflectionDpAtlas.frag b/src/graphics/programlib/chunks/reflectionDpAtlas.frag index 22e4474916c..f58bf82c195 100644 --- a/src/graphics/programlib/chunks/reflectionDpAtlas.frag +++ b/src/graphics/programlib/chunks/reflectionDpAtlas.frag @@ -1,5 +1,5 @@ uniform sampler2D texture_sphereMap; -uniform float material_reflectionFactor; +uniform float material_reflectivity; vec2 getDpAtlasUv(vec2 uv, float mip) { @@ -50,7 +50,7 @@ void addReflection(inout psInternalData data) { tex1 = mix(tex1, tex2, fract(bias)); tex1 = processEnvironment(tex1); - data.reflection += vec4(tex1, material_reflectionFactor); + data.reflection += vec4(tex1, material_reflectivity); } diff --git a/src/graphics/programlib/chunks/reflectionPrefilteredCube.frag b/src/graphics/programlib/chunks/reflectionPrefilteredCube.frag index 1a596c15add..16ce108f357 100644 --- a/src/graphics/programlib/chunks/reflectionPrefilteredCube.frag +++ b/src/graphics/programlib/chunks/reflectionPrefilteredCube.frag @@ -4,7 +4,7 @@ uniform samplerCube texture_prefilteredCubeMap32; uniform samplerCube texture_prefilteredCubeMap16; uniform samplerCube texture_prefilteredCubeMap8; uniform samplerCube texture_prefilteredCubeMap4; -uniform float material_reflectionFactor; +uniform float material_reflectivity; void addReflection(inout psInternalData data) { @@ -56,6 +56,6 @@ void addReflection(inout psInternalData data) { vec4 cubeFinal = mix(cube[0], cube[1], fract(bias)); vec3 refl = processEnvironment($DECODE(cubeFinal).rgb); - data.reflection += vec4(refl, material_reflectionFactor); + data.reflection += vec4(refl, material_reflectivity); } diff --git a/src/graphics/programlib/chunks/reflectionPrefilteredCubeLod.frag b/src/graphics/programlib/chunks/reflectionPrefilteredCubeLod.frag index f24e0bf82f7..dffd6b43e77 100644 --- a/src/graphics/programlib/chunks/reflectionPrefilteredCubeLod.frag +++ b/src/graphics/programlib/chunks/reflectionPrefilteredCubeLod.frag @@ -1,7 +1,7 @@ #extension GL_EXT_shader_texture_lod : enable uniform samplerCube texture_prefilteredCubeMap128; -uniform float material_reflectionFactor; +uniform float material_reflectivity; void addReflection(inout psInternalData data) { @@ -11,6 +11,6 @@ void addReflection(inout psInternalData data) { vec3 refl = processEnvironment($DECODE( textureCubeLodEXT(texture_prefilteredCubeMap128, fixedReflDir, bias) ).rgb); - data.reflection += vec4(refl, material_reflectionFactor); + data.reflection += vec4(refl, material_reflectivity); } diff --git a/src/graphics/programlib/chunks/reflectionSphere.frag b/src/graphics/programlib/chunks/reflectionSphere.frag index 4fc69a35070..fde5188acbc 100644 --- a/src/graphics/programlib/chunks/reflectionSphere.frag +++ b/src/graphics/programlib/chunks/reflectionSphere.frag @@ -1,6 +1,6 @@ uniform mat4 matrix_view; uniform sampler2D texture_sphereMap; -uniform float material_reflectionFactor; +uniform float material_reflectivity; void addReflection(inout psInternalData data) { vec3 reflDirV = (mat3(matrix_view) * data.reflDirW).xyz; @@ -8,7 +8,7 @@ void addReflection(inout psInternalData data) { float m = 2.0 * sqrt( dot(reflDirV.xy, reflDirV.xy) + (reflDirV.z+1.0)*(reflDirV.z+1.0) ); vec2 sphereMapUv = reflDirV.xy / m + 0.5; - data.reflection += vec4($texture2DSAMPLE(texture_sphereMap, sphereMapUv).rgb, material_reflectionFactor); + data.reflection += vec4($texture2DSAMPLE(texture_sphereMap, sphereMapUv).rgb, material_reflectivity); } diff --git a/src/graphics/programlib/chunks/reflectionSphereLow.frag b/src/graphics/programlib/chunks/reflectionSphereLow.frag index d38416cb7cb..a119fa0fded 100644 --- a/src/graphics/programlib/chunks/reflectionSphereLow.frag +++ b/src/graphics/programlib/chunks/reflectionSphereLow.frag @@ -1,10 +1,10 @@ uniform sampler2D texture_sphereMap; -uniform float material_reflectionFactor; +uniform float material_reflectivity; void addReflection(inout psInternalData data) { vec3 reflDirV = vNormalV; vec2 sphereMapUv = reflDirV.xy * 0.5 + 0.5; - data.reflection += vec4($texture2DSAMPLE(texture_sphereMap, sphereMapUv).rgb, material_reflectionFactor); + data.reflection += vec4($texture2DSAMPLE(texture_sphereMap, sphereMapUv).rgb, material_reflectivity); } diff --git a/src/graphics/programlib/chunks/refraction.frag b/src/graphics/programlib/chunks/refraction.frag index 2c0f3615bd1..fa1c92565fa 100644 --- a/src/graphics/programlib/chunks/refraction.frag +++ b/src/graphics/programlib/chunks/refraction.frag @@ -1,4 +1,4 @@ -uniform float material_refraction, material_refractionIor; +uniform float material_refraction, material_refractionIndex; vec3 refract2(vec3 viewVec, vec3 Normal, float IOR) { float vn = dot(viewVec, Normal); @@ -13,7 +13,7 @@ void addRefraction(inout psInternalData data) { vec3 tmp = data.reflDirW; vec4 tmp2 = data.reflection; data.reflection = vec4(0.0); - data.reflDirW = refract2(-data.viewDirW, data.normalW, material_refractionIor); + data.reflDirW = refract2(-data.viewDirW, data.normalW, material_refractionIndex); addReflection(data); diff --git a/src/graphics/programlib/chunks/specularAaToksvigFloat.frag b/src/graphics/programlib/chunks/specularAaToksvigFloat.frag index b421fc05d02..d134524bb21 100644 --- a/src/graphics/programlib/chunks/specularAaToksvigFloat.frag +++ b/src/graphics/programlib/chunks/specularAaToksvigFloat.frag @@ -1,6 +1,6 @@ float antiAliasGlossiness(inout psInternalData data, float power) { float rlen = 1.0 / saturate(length(data.normalMap)); float toksvig = 1.0 / (1.0 + power * (rlen - 1.0)); - return power * mix(1.0, toksvig, material_bumpMapFactor); + return power * mix(1.0, toksvig, material_bumpiness); } diff --git a/src/graphics/programlib/programlib_programlib.js b/src/graphics/programlib/programlib_programlib.js index 72d135a2bd8..7cb32f0cc76 100644 --- a/src/graphics/programlib/programlib_programlib.js +++ b/src/graphics/programlib/programlib_programlib.js @@ -115,7 +115,7 @@ pc.programlib = { // V, the view vector (vertex to eye) code += ' vec3 map = texture2D( texture_normalMap, uv ).xyz;\n'; code += ' map = map * 255./127. - 128./127.;\n'; - code += ' map.xy = map.xy * material_bumpMapFactor;\n'; + code += ' map.xy = map.xy * material_bumpiness;\n'; code += ' mat3 TBN = cotangent_frame( N, -V, uv );\n'; code += ' return normalize( TBN * map );\n'; code += '}\n\n'; diff --git a/src/scene/scene_phongmaterial.js b/src/scene/scene_phongmaterial.js index 5f2913b59e2..4928e8fbfde 100644 --- a/src/scene/scene_phongmaterial.js +++ b/src/scene/scene_phongmaterial.js @@ -144,12 +144,13 @@ pc.extend(pc, function () { var _propsSerialDefaultVal = []; var _propsInternalNull = []; var _propsInternalVec3 = []; + var _prop2Uniform = {}; var _defineTex2D = function (obj, name, uv, channels) { var privMap = "_" + name + "Map"; var privMapTiling = privMap + "Tiling"; var privMapOffset = privMap + "Offset"; - var privMapTransform = privMap + "Transform"; + var privMapTransform = privMap.substring(1) + "Transform"; var privMapUv = privMap + "Uv"; var privMapChannel = privMap + "Channel"; var privMapVertexColor = privMap + "VertexColor"; @@ -173,7 +174,13 @@ pc.extend(pc, function () { this[privMap] = value; } }); - Object.defineProperty(PhongMaterial.prototype, privMapTiling.substring(1), { + + var mapTiling = privMapTiling.substring(1); + var mapOffset = privMapOffset.substring(1); + var mapTransform = privMapTransform.substring(1); + + + Object.defineProperty(PhongMaterial.prototype, mapTiling, { get: function() { this.dirtyShader = true; return this[privMapTiling]; @@ -183,7 +190,17 @@ pc.extend(pc, function () { this[privMapTiling] = value; } }); - Object.defineProperty(PhongMaterial.prototype, privMapOffset.substring(1), { + _prop2Uniform[mapTiling] = function (mat, val) { + var tform = mat._updateMapTransform( + null, + val, + mat[privMapOffset] + ); + return {name:("texture_" + mapTransform), value:tform}; + } + + + Object.defineProperty(PhongMaterial.prototype, mapOffset, { get: function() { this.dirtyShader = true; return this[privMapOffset]; @@ -193,6 +210,16 @@ pc.extend(pc, function () { this[privMapOffset] = value; } }); + _prop2Uniform[mapOffset] = function (mat, val) { + var tform = mat._updateMapTransform( + null, + this[privMapTiling], + val + ); + return {name:("texture_" + mapTransform), value:tform}; + } + + Object.defineProperty(PhongMaterial.prototype, privMapUv.substring(1), { get: function() { return this[privMapUv]; }, set: function (value) { @@ -225,7 +252,7 @@ pc.extend(pc, function () { }; var _propsColor = []; - var _defineColor = function (obj, name, defaultValue) { + var _defineColor = function (obj, name, defaultValue, multiplier) { var priv = "_" + name; var uform = name + "Uniform"; obj[priv] = defaultValue; @@ -248,9 +275,21 @@ pc.extend(pc, function () { _propsSerial.push(name); _propsInternalVec3.push(uform); _propsColor.push(name); + _prop2Uniform[name] = function (mat, val) { + var arr = new Float32Array(3); + for(var c=0; c<3; c++) { + if (mat._scene.gammaCorrection) { + arr[c] = Math.pow(val.data[c], 2.2); + } else { + arr[c] = val.data[c]; + } + if (multiplier) arr[c] *= mat[multiplier]; + } + return {name:("material_" + name), value:arr} + } }; - var _defineFloat = function (obj, name, defaultValue) { + var _defineFloat = function (obj, name, defaultValue, func) { var priv = "_" + name; obj[priv] = defaultValue; Object.defineProperty(PhongMaterial.prototype, name, { @@ -264,9 +303,12 @@ pc.extend(pc, function () { } }); _propsSerial.push(name); + _prop2Uniform[name] = func!==undefined? func : (function (mat, val) { + return {name:("material_" + name), value:val} + }); }; - var _defineObject = function (obj, name) { + var _defineObject = function (obj, name, func) { var priv = "_" + name; obj[priv] = null; Object.defineProperty(PhongMaterial.prototype, name, { @@ -278,6 +320,7 @@ pc.extend(pc, function () { } }); _propsSerial.push(name); + _prop2Uniform[name] = func; }; var _defineChunks = function (obj) { @@ -443,6 +486,14 @@ pc.extend(pc, function () { } }, + getUniform: function(varName, value) { + var func = _prop2Uniform[varName]; + if (func) { + return func(this, value); + } + return null; + }, + update: function () { this.clearParameters(); @@ -477,7 +528,7 @@ pc.extend(pc, function () { if (this.refraction>0) { this.setParameter('material_refraction', this.refraction); - this.setParameter('material_refractionIor', this.refractionIndex); + this.setParameter('material_refractionIndex', this.refractionIndex); } this.setParameter('material_opacity', this.opacity); @@ -508,7 +559,7 @@ pc.extend(pc, function () { } if (this.normalMap) { - this.setParameter('material_bumpMapFactor', this.bumpiness); + this.setParameter('material_bumpiness', this.bumpiness); } if (this.heightMap) { @@ -543,7 +594,7 @@ pc.extend(pc, function () { this.setParameter('texture_sphereMap', this.dpAtlas); } //if (this.sphereMap || this.cubeMap || this.prefilteredCubeMap128) { - this.setParameter('material_reflectionFactor', this.reflectivity); + this.setParameter('material_reflectivity', this.reflectivity); //} if (this.dirtyShader || !this._scene) { @@ -802,24 +853,60 @@ pc.extend(pc, function () { _defineColor(obj, "ambient", new pc.Color(0.7, 0.7, 0.7)); _defineColor(obj, "diffuse", new pc.Color(1, 1, 1)); _defineColor(obj, "specular", new pc.Color(0, 0, 0)); - _defineColor(obj, "emissive", new pc.Color(0, 0, 0)); + _defineColor(obj, "emissive", new pc.Color(0, 0, 0), "emissiveIntensity"); - _defineFloat(obj, "shininess", 25); + _defineFloat(obj, "shininess", 25, function(mat, shininess) { + var value; + if (this.shadingModel===pc.SPECULAR_PHONG) { + value = Math.pow(2, shininess * 0.01 * 11); // legacy: expand back to specular power + } else { + value = shininess * 0.01; // correct + } + return {name:"material_shininess", value:value}; + }); + _defineFloat(obj, "heightMapFactor", 1, function(mat, height) { + return {name:'material_heightMapFactor', value:height * 0.025}; + }); _defineFloat(obj, "opacity", 1); _defineFloat(obj, "alphaTest", 0); _defineFloat(obj, "bumpiness", 1); - _defineFloat(obj, "heightMapFactor", 1); _defineFloat(obj, "reflectivity", 1); _defineFloat(obj, "occludeSpecularIntensity", 1); - _defineFloat(obj, "emissiveIntensity", 1); + _defineFloat(obj, "emissiveIntensity", 1, function (mat, intensity) { + var arr = new Float32Array(3); + for(var c=0; c<3; c++) { + if (mat._scene.gammaCorrection) { + arr[c] = Math.pow(mat.emissive.data[c], 2.2); + } else { + arr[c] = mat.emissive.data[c]; + } + arr[c] *= intensity; + } + return {name:("material_emissive"), value:arr}; + }); _defineFloat(obj, "refraction", 0); _defineFloat(obj, "refractionIndex", 1.0 / 1.5); // approx. (air ior / glass ior) _defineFloat(obj, "metalness", 1); - _defineFloat(obj, "aoUvSet", 0); // legacy + _defineFloat(obj, "aoUvSet", 0, null); // legacy + + _defineObject(obj, "ambientSH", function (mat, val) { + return {name:"ambientSH[0]", value:val}; + }); + + _defineObject(obj, "cubeMapProjectionBox", function (mat, val) { + var bmin = new Float32Array(3); + var bmax = new Float32Array(3); - _defineObject(obj, "ambientSH"); + bmin[0] = val.center.x - val.halfExtents.x; + bmin[1] = val.center.y - val.halfExtents.y; + bmin[2] = val.center.z - val.halfExtents.z; - _defineObject(obj, "cubeMapProjectionBox"); + bmax[0] = val.center.x + val.halfExtents.x; + bmax[1] = val.center.y + val.halfExtents.y; + bmax[2] = val.center.z + val.halfExtents.z; + + return [{name:"envBoxMin", value:bmin}, {name:"envBoxMax", value:bmax}]; + }); _defineChunks(obj); From 226eaf4eb36b8a72272df47246e44c9afc097ec0 Mon Sep 17 00:00:00 2001 From: Mr F Date: Thu, 25 Jun 2015 15:58:43 +0300 Subject: [PATCH 2/8] setParameter accepts uniform objects --- src/scene/scene_material.js | 12 +++++++++++- src/scene/scene_phongmaterial.js | 12 ++++-------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/scene/scene_material.js b/src/scene/scene_material.js index e696fb59da4..553aafd91ff 100644 --- a/src/scene/scene_material.js +++ b/src/scene/scene_material.js @@ -220,7 +220,17 @@ pc.extend(pc, function () { * @name {number|Array|pc.Texture} data The value for the specified parameter. * @author Will Eastcott */ - Material.prototype.setParameter = function (name, data) { + Material.prototype.setParameter = function (arg, data) { + + var name; + if (data===undefined) { + var uniformObject = arg; + name = uniformObject.name; + data = uniformObject.value; + } else { + name = arg; + } + var param = this.parameters[name]; if (param) { param.data = data; diff --git a/src/scene/scene_phongmaterial.js b/src/scene/scene_phongmaterial.js index 4928e8fbfde..f5723b61b34 100644 --- a/src/scene/scene_phongmaterial.js +++ b/src/scene/scene_phongmaterial.js @@ -513,14 +513,7 @@ pc.extend(pc, function () { } } - // Shininess is 0-100 value - // which is actually a 0-1 glosiness value. - // Can be converted to specular power using exp2(shininess * 0.01 * 11) - if (this.shadingModel===pc.SPECULAR_PHONG) { - this.setParameter('material_shininess', Math.pow(2, this.shininess * 0.01 * 11)); // legacy: expand back to specular power - } else { - this.setParameter('material_shininess', this.shininess * 0.01); // correct - } + this.setParameter(this.getUniform("shininess", this.shininess)); if (!this.emissiveMap || this.emissiveMapTint) { this.setParameter('material_emissive', this.emissiveUniform); @@ -856,6 +849,9 @@ pc.extend(pc, function () { _defineColor(obj, "emissive", new pc.Color(0, 0, 0), "emissiveIntensity"); _defineFloat(obj, "shininess", 25, function(mat, shininess) { + // Shininess is 0-100 value + // which is actually a 0-1 glosiness value. + // Can be converted to specular power using exp2(shininess * 0.01 * 11) var value; if (this.shadingModel===pc.SPECULAR_PHONG) { value = Math.pow(2, shininess * 0.01 * 11); // legacy: expand back to specular power From ac5cc5ca3565c7459bca2ea47a3d021c704082bc Mon Sep 17 00:00:00 2001 From: Mr F Date: Thu, 25 Jun 2015 16:56:52 +0300 Subject: [PATCH 3/8] fixes, removed excessive allocations --- src/scene/scene_material.js | 8 ++- src/scene/scene_phongmaterial.js | 106 +++++++++++++++++-------------- 2 files changed, 64 insertions(+), 50 deletions(-) diff --git a/src/scene/scene_material.js b/src/scene/scene_material.js index 553aafd91ff..086eff3420b 100644 --- a/src/scene/scene_material.js +++ b/src/scene/scene_material.js @@ -225,8 +225,12 @@ pc.extend(pc, function () { var name; if (data===undefined) { var uniformObject = arg; - name = uniformObject.name; - data = uniformObject.value; + if (uniformObject.length) { + for(var i=0; i 0) obj[privMapChannel] = channels > 1? "rgb" : "g"; obj[privMapVertexColor] = false; @@ -177,7 +177,6 @@ pc.extend(pc, function () { var mapTiling = privMapTiling.substring(1); var mapOffset = privMapOffset.substring(1); - var mapTransform = privMapTransform.substring(1); Object.defineProperty(PhongMaterial.prototype, mapTiling, { @@ -190,9 +189,9 @@ pc.extend(pc, function () { this[privMapTiling] = value; } }); - _prop2Uniform[mapTiling] = function (mat, val) { + _prop2Uniform[mapTiling] = function (mat, val, changeMat) { var tform = mat._updateMapTransform( - null, + changeMat? mat[mapTransform] : null, val, mat[privMapOffset] ); @@ -210,9 +209,9 @@ pc.extend(pc, function () { this[privMapOffset] = value; } }); - _prop2Uniform[mapOffset] = function (mat, val) { + _prop2Uniform[mapOffset] = function (mat, val, changeMat) { var tform = mat._updateMapTransform( - null, + changeMat? mat[mapTransform] : null, this[privMapTiling], val ); @@ -248,13 +247,15 @@ pc.extend(pc, function () { _propsSerial.push(privMapUv); _propsSerial.push(privMapChannel); _propsSerial.push(privMapVertexColor); - _propsInternalNull.push(privMapTransform) + _propsInternalNull.push(mapTransform) }; var _propsColor = []; - var _defineColor = function (obj, name, defaultValue, multiplier) { + var _defineColor = function (obj, name, defaultValue, hasMultiplier) { var priv = "_" + name; var uform = name + "Uniform"; + var mult = name + "Intensity"; + var pmult = "_" + mult; obj[priv] = defaultValue; obj[uform] = new Float32Array(3); Object.defineProperty(PhongMaterial.prototype, name, { @@ -275,18 +276,48 @@ pc.extend(pc, function () { _propsSerial.push(name); _propsInternalVec3.push(uform); _propsColor.push(name); - _prop2Uniform[name] = function (mat, val) { - var arr = new Float32Array(3); + _prop2Uniform[name] = function (mat, val, changeMat) { + var arr = changeMat? mat[uform] : new Float32Array(3); for(var c=0; c<3; c++) { if (mat._scene.gammaCorrection) { arr[c] = Math.pow(val.data[c], 2.2); } else { arr[c] = val.data[c]; } - if (multiplier) arr[c] *= mat[multiplier]; + if (hasMultiplier) arr[c] *= mat[pmult]; } return {name:("material_" + name), value:arr} } + + if (hasMultiplier) { + obj[pmult] = 1; + Object.defineProperty(PhongMaterial.prototype, mult, { + get: function() { + return this[pmult]; + }, + set: function (value) { + var oldVal = this[pmult]; + var wasBw = oldVal===0 || oldVal===1; + var isBw = value===0 || value===1; + if (wasBw || isBw) this.dirtyShader = true; + this.dirtyColor = true; + this[pmult] = value; + } + }); + _propsSerial.push(mult); + _prop2Uniform[mult] = function (mat, val, changeMat) { + var arr = changeMat? mat[uform] : new Float32Array(3); + for(var c=0; c<3; c++) { + if (mat._scene.gammaCorrection) { + arr[c] = Math.pow(mat[priv].data[c], 2.2); + } else { + arr[c] = mat[priv].data[c]; + } + arr[c] *= mat[pmult]; + } + return {name:("material_" + name), value:arr} + } + } }; var _defineFloat = function (obj, name, defaultValue, func) { @@ -303,7 +334,7 @@ pc.extend(pc, function () { } }); _propsSerial.push(name); - _prop2Uniform[name] = func!==undefined? func : (function (mat, val) { + _prop2Uniform[name] = func!==undefined? func : (function (mat, val, changeMat) { return {name:("material_" + name), value:val} }); }; @@ -486,10 +517,10 @@ pc.extend(pc, function () { } }, - getUniform: function(varName, value) { + getUniform: function(varName, value, changeMat) { var func = _prop2Uniform[varName]; if (func) { - return func(this, value); + return func(this, value, changeMat); } return null; }, @@ -513,7 +544,7 @@ pc.extend(pc, function () { } } - this.setParameter(this.getUniform("shininess", this.shininess)); + this.setParameter(this.getUniform("shininess", this.shininess, true)); if (!this.emissiveMap || this.emissiveMapTint) { this.setParameter('material_emissive', this.emissiveUniform); @@ -531,32 +562,23 @@ pc.extend(pc, function () { } if (this.cubeMapProjection===pc.CUBEPROJ_BOX) { - this.cubeMapMinUniform[0] = this.cubeMapProjectionBox.center.x - this.cubeMapProjectionBox.halfExtents.x; - this.cubeMapMinUniform[1] = this.cubeMapProjectionBox.center.y - this.cubeMapProjectionBox.halfExtents.y; - this.cubeMapMinUniform[2] = this.cubeMapProjectionBox.center.z - this.cubeMapProjectionBox.halfExtents.z; - - this.cubeMapMaxUniform[0] = this.cubeMapProjectionBox.center.x + this.cubeMapProjectionBox.halfExtents.x; - this.cubeMapMaxUniform[1] = this.cubeMapProjectionBox.center.y + this.cubeMapProjectionBox.halfExtents.y; - this.cubeMapMaxUniform[2] = this.cubeMapProjectionBox.center.z + this.cubeMapProjectionBox.halfExtents.z; + this.setParameter(this.getUniform("cubeMapProjectionBox", this.cubeMapProjectionBox, true)); + } - this.setParameter('envBoxMin', this.cubeMapMinUniform); - this.setParameter('envBoxMax', this.cubeMapMaxUniform); + for(var p in pc._matTex2D) { + this._updateMap(p); } if (this.ambientSH) { this.setParameter('ambientSH[0]', this.ambientSH); } - for(var p in pc._matTex2D) { - this._updateMap(p); - } - if (this.normalMap) { this.setParameter('material_bumpiness', this.bumpiness); } if (this.heightMap) { - this.setParameter('material_heightMapFactor', this.heightMapFactor * 0.025); + this.setParameter(this.getUniform('heightMapFactor', this.heightMapFactor, true)); } if (this.cubeMap) { @@ -846,14 +868,14 @@ pc.extend(pc, function () { _defineColor(obj, "ambient", new pc.Color(0.7, 0.7, 0.7)); _defineColor(obj, "diffuse", new pc.Color(1, 1, 1)); _defineColor(obj, "specular", new pc.Color(0, 0, 0)); - _defineColor(obj, "emissive", new pc.Color(0, 0, 0), "emissiveIntensity"); + _defineColor(obj, "emissive", new pc.Color(0, 0, 0), true); _defineFloat(obj, "shininess", 25, function(mat, shininess) { // Shininess is 0-100 value // which is actually a 0-1 glosiness value. // Can be converted to specular power using exp2(shininess * 0.01 * 11) var value; - if (this.shadingModel===pc.SPECULAR_PHONG) { + if (mat.shadingModel===pc.SPECULAR_PHONG) { value = Math.pow(2, shininess * 0.01 * 11); // legacy: expand back to specular power } else { value = shininess * 0.01; // correct @@ -868,30 +890,18 @@ pc.extend(pc, function () { _defineFloat(obj, "bumpiness", 1); _defineFloat(obj, "reflectivity", 1); _defineFloat(obj, "occludeSpecularIntensity", 1); - _defineFloat(obj, "emissiveIntensity", 1, function (mat, intensity) { - var arr = new Float32Array(3); - for(var c=0; c<3; c++) { - if (mat._scene.gammaCorrection) { - arr[c] = Math.pow(mat.emissive.data[c], 2.2); - } else { - arr[c] = mat.emissive.data[c]; - } - arr[c] *= intensity; - } - return {name:("material_emissive"), value:arr}; - }); _defineFloat(obj, "refraction", 0); _defineFloat(obj, "refractionIndex", 1.0 / 1.5); // approx. (air ior / glass ior) _defineFloat(obj, "metalness", 1); _defineFloat(obj, "aoUvSet", 0, null); // legacy - _defineObject(obj, "ambientSH", function (mat, val) { + _defineObject(obj, "ambientSH", function (mat, val, changeMat) { return {name:"ambientSH[0]", value:val}; }); - _defineObject(obj, "cubeMapProjectionBox", function (mat, val) { - var bmin = new Float32Array(3); - var bmax = new Float32Array(3); + _defineObject(obj, "cubeMapProjectionBox", function (mat, val, changeMat) { + var bmin = changeMat? this.cubeMapMinUniform : new Float32Array(3); + var bmax = changeMat? this.cubeMapMaxUniform : new Float32Array(3); bmin[0] = val.center.x - val.halfExtents.x; bmin[1] = val.center.y - val.halfExtents.y; From ce8b8308098a43f393ed24260194de5de6d38000 Mon Sep 17 00:00:00 2001 From: Mr F Date: Thu, 25 Jun 2015 17:18:07 +0300 Subject: [PATCH 4/8] fix --- src/scene/scene_phongmaterial.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scene/scene_phongmaterial.js b/src/scene/scene_phongmaterial.js index 47b24a0959d..beb1d204494 100644 --- a/src/scene/scene_phongmaterial.js +++ b/src/scene/scene_phongmaterial.js @@ -212,7 +212,7 @@ pc.extend(pc, function () { _prop2Uniform[mapOffset] = function (mat, val, changeMat) { var tform = mat._updateMapTransform( changeMat? mat[mapTransform] : null, - this[privMapTiling], + mat[privMapTiling], val ); return {name:("texture_" + mapTransform), value:tform}; From 0863a619b6ff972f6437409b86535a60b990c4b4 Mon Sep 17 00:00:00 2001 From: Mr F Date: Thu, 25 Jun 2015 17:19:41 +0300 Subject: [PATCH 5/8] fix2 --- src/scene/scene_material.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/scene/scene_material.js b/src/scene/scene_material.js index 086eff3420b..f6d22b03526 100644 --- a/src/scene/scene_material.js +++ b/src/scene/scene_material.js @@ -227,6 +227,7 @@ pc.extend(pc, function () { var uniformObject = arg; if (uniformObject.length) { for(var i=0; i Date: Thu, 25 Jun 2015 17:24:29 +0300 Subject: [PATCH 6/8] fix3 --- src/scene/scene_phongmaterial.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/scene/scene_phongmaterial.js b/src/scene/scene_phongmaterial.js index beb1d204494..194a29d5041 100644 --- a/src/scene/scene_phongmaterial.js +++ b/src/scene/scene_phongmaterial.js @@ -195,7 +195,7 @@ pc.extend(pc, function () { val, mat[privMapOffset] ); - return {name:("texture_" + mapTransform), value:tform}; + return {name:("texture_" + mapTransform), value:tform.data}; } @@ -215,7 +215,7 @@ pc.extend(pc, function () { mat[privMapTiling], val ); - return {name:("texture_" + mapTransform), value:tform}; + return {name:("texture_" + mapTransform), value:tform.data}; } From 448d5fe64b8181a50898c2e09cf5afc41796007e Mon Sep 17 00:00:00 2001 From: Mr F Date: Thu, 25 Jun 2015 17:30:41 +0300 Subject: [PATCH 7/8] fix3 --- src/scene/scene_phongmaterial.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/scene/scene_phongmaterial.js b/src/scene/scene_phongmaterial.js index 194a29d5041..26a9c999011 100644 --- a/src/scene/scene_phongmaterial.js +++ b/src/scene/scene_phongmaterial.js @@ -278,8 +278,9 @@ pc.extend(pc, function () { _propsColor.push(name); _prop2Uniform[name] = function (mat, val, changeMat) { var arr = changeMat? mat[uform] : new Float32Array(3); + var scene = mat._scene || pc.Application.getApplication().scene; for(var c=0; c<3; c++) { - if (mat._scene.gammaCorrection) { + if (scene.gammaCorrection) { arr[c] = Math.pow(val.data[c], 2.2); } else { arr[c] = val.data[c]; @@ -307,8 +308,9 @@ pc.extend(pc, function () { _propsSerial.push(mult); _prop2Uniform[mult] = function (mat, val, changeMat) { var arr = changeMat? mat[uform] : new Float32Array(3); + var scene = mat._scene || pc.Application.getApplication().scene; for(var c=0; c<3; c++) { - if (mat._scene.gammaCorrection) { + if (scene.gammaCorrection) { arr[c] = Math.pow(mat[priv].data[c], 2.2); } else { arr[c] = mat[priv].data[c]; From 0398a24e8a7f4c5765edfd0cf2158b29a4c597ed Mon Sep 17 00:00:00 2001 From: Mr F Date: Thu, 25 Jun 2015 17:37:04 +0300 Subject: [PATCH 8/8] fix4 --- src/scene/scene_phongmaterial.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/scene/scene_phongmaterial.js b/src/scene/scene_phongmaterial.js index 26a9c999011..6a2541b7d47 100644 --- a/src/scene/scene_phongmaterial.js +++ b/src/scene/scene_phongmaterial.js @@ -902,8 +902,8 @@ pc.extend(pc, function () { }); _defineObject(obj, "cubeMapProjectionBox", function (mat, val, changeMat) { - var bmin = changeMat? this.cubeMapMinUniform : new Float32Array(3); - var bmax = changeMat? this.cubeMapMaxUniform : new Float32Array(3); + var bmin = changeMat? mat.cubeMapMinUniform : new Float32Array(3); + var bmax = changeMat? mat.cubeMapMaxUniform : new Float32Array(3); bmin[0] = val.center.x - val.halfExtents.x; bmin[1] = val.center.y - val.halfExtents.y;