From 954e38810ab080ab22f558ae630cab095c72fb93 Mon Sep 17 00:00:00 2001 From: Mr F Date: Thu, 15 Sep 2016 16:40:01 +0300 Subject: [PATCH 1/5] Hejl and ACES (approx) tonemappers --- src/graphics/program-lib/chunks/tonemappingAces.frag | 11 +++++++++++ src/graphics/program-lib/chunks/tonemappingHejl.frag | 9 +++++++++ src/graphics/program-lib/program-lib.js | 4 ++++ src/scene/scene.js | 4 ++++ 4 files changed, 28 insertions(+) create mode 100644 src/graphics/program-lib/chunks/tonemappingAces.frag create mode 100644 src/graphics/program-lib/chunks/tonemappingHejl.frag diff --git a/src/graphics/program-lib/chunks/tonemappingAces.frag b/src/graphics/program-lib/chunks/tonemappingAces.frag new file mode 100644 index 00000000000..2f421fae8f6 --- /dev/null +++ b/src/graphics/program-lib/chunks/tonemappingAces.frag @@ -0,0 +1,11 @@ +uniform float exposure; + +vec3 toneMap(vec3 color) { + float tA = 2.51; + float tB = 0.03; + float tC = 2.43; + float tD = 0.59; + float tE = 0.14; + vec3 x = color * exposure; + return (x*(tA*x+tB))/(x*(tC*x+tD)+tE); +} diff --git a/src/graphics/program-lib/chunks/tonemappingHejl.frag b/src/graphics/program-lib/chunks/tonemappingHejl.frag new file mode 100644 index 00000000000..e12a56cedf8 --- /dev/null +++ b/src/graphics/program-lib/chunks/tonemappingHejl.frag @@ -0,0 +1,9 @@ +uniform float exposure; + +vec3 toneMap(vec3 color) { + color *= exposure; + vec3 x = max(vec3(0.0), color - vec3(0.004)); + color = (x*(6.2*x + 0.5)) / (x*(6.2*x + 1.7) + 0.06); + return gammaCorrectInput(color); +} + diff --git a/src/graphics/program-lib/program-lib.js b/src/graphics/program-lib/program-lib.js index 95310911418..9127307808a 100644 --- a/src/graphics/program-lib/program-lib.js +++ b/src/graphics/program-lib/program-lib.js @@ -9,6 +9,10 @@ pc.programlib = { return pc.shaderChunks.tonemappingFilmicPS; } else if (value===pc.TONEMAP_LINEAR) { return pc.shaderChunks.tonemappingLinearPS; + } else if (value===pc.TONEMAP_HEJL) { + return pc.shaderChunks.tonemappingHejlPS; + } else if (value===pc.TONEMAP_ACES) { + return pc.shaderChunks.tonemappingAcesPS; } return pc.shaderChunks.tonemappingNonePS; }, diff --git a/src/scene/scene.js b/src/scene/scene.js index 544977c8bb4..5a5840803e5 100644 --- a/src/scene/scene.js +++ b/src/scene/scene.js @@ -170,6 +170,8 @@ TONEMAP_LINEAR: 0, TONEMAP_FILMIC: 1, + TONEMAP_HEJL: 2, + TONEMAP_ACES: 3, SPECOCC_NONE: 0, SPECOCC_AO: 1, @@ -250,6 +252,8 @@ pc.extend(pc, function () { * * Defaults to pc.TONEMAP_LINEAR. * @property {pc.Texture} skybox A cube map texture used as the scene's skybox. Defaults to null. From b48b0d85ae7e3573c93bdb3a08862226398beaab Mon Sep 17 00:00:00 2001 From: Mr F Date: Thu, 15 Sep 2016 20:12:22 +0300 Subject: [PATCH 2/5] different ACES --- .../program-lib/chunks/tonemappingAces2.frag | 190 ++++++++++++++++++ src/graphics/program-lib/program-lib.js | 2 + src/scene/scene.js | 1 + 3 files changed, 193 insertions(+) create mode 100644 src/graphics/program-lib/chunks/tonemappingAces2.frag diff --git a/src/graphics/program-lib/chunks/tonemappingAces2.frag b/src/graphics/program-lib/chunks/tonemappingAces2.frag new file mode 100644 index 00000000000..faa536ad27a --- /dev/null +++ b/src/graphics/program-lib/chunks/tonemappingAces2.frag @@ -0,0 +1,190 @@ +uniform float exposure; + +mat3 mul2(mat3 a, mat3 b) { + return b * a; +} + +vec3 mul2(mat3 a, vec3 b) { + return b * a; +} + + +const float PI = 3.1415926535897932384626433832795; + +float rgb_2_saturation( vec3 rgb ) { + float minrgb = min( min(rgb.r, rgb.g ), rgb.b ); + float maxrgb = max( max(rgb.r, rgb.g ), rgb.b ); + return ( max( maxrgb, 1e-10 ) - max( minrgb, 1e-10 ) ) / max( maxrgb, 1e-2 ); +} + +// Transformations from RGB to other color representations +float rgb_2_hue( vec3 rgb ) { + // Returns a geometric hue angle in degrees (0-360) based on RGB values. + // For neutral colors, hue is undefined and the function will return a quiet NaN value. + float hue; + if (rgb[0] == rgb[1] && rgb[1] == rgb[2]) + { + //hue = FLT_NAN; // RGB triplets where RGB are equal have an undefined hue + hue = 0.0; + } + else + { + hue = (180. / PI) * atan(2.0 * rgb[0] - rgb[1] - rgb[2], sqrt(3.0)*(rgb[1] - rgb[2])); + } + + if (hue < 0.) + hue = hue + 360.0; + + return clamp( hue, 0.0, 360.0 ); +} + +float center_hue( float hue, float centerH) +{ + float hueCentered = hue - centerH; + if (hueCentered < -180.) + hueCentered += 360.0; + else if (hueCentered > 180.) + hueCentered -= 360.0; + return hueCentered; +} + +float log10(float x) { + return log(x) / log(10.0); +} + +vec3 log10(vec3 x) { + return log(x) / log(10.0); +} + +vec3 toneMap(vec3 LinearColor) { + LinearColor *= exposure; + + mat3 XYZ_2_AP0_MAT = mat3( + 1.0498110175, 0.0000000000,-0.0000974845, + -0.4959030231, 1.3733130458, 0.0982400361, + 0.0000000000, 0.0000000000, 0.9912520182 + ); + mat3 D65_2_D60_CAT = mat3( + 1.01303, 0.00610531, -0.014971, + 0.00769823, 0.998165, -0.00503203, + -0.00284131, 0.00468516, 0.924507 + ); + mat3 sRGB_2_XYZ_MAT = mat3( + 0.4124564, 0.3575761, 0.1804375, + 0.2126729, 0.7151522, 0.0721750, + 0.0193339, 0.1191920, 0.9503041 + ); + mat3 XYZ_2_AP1_MAT = mat3( + 1.6410233797, -0.3248032942, -0.2364246952, + -0.6636628587, 1.6153315917, 0.0167563477, + 0.0117218943, -0.0082844420, 0.9883948585 + ); + mat3 XYZ_2_sRGB_MAT = mat3( + 3.2409699419, -1.5373831776, -0.4986107603, + -0.9692436363, 1.8759675015, 0.0415550574, + 0.0556300797, -0.2039769589, 1.0569715142 + ); + mat3 D60_2_D65_CAT = mat3( + 0.987224, -0.00611327, 0.0159533, + -0.00759836, 1.00186, 0.00533002, + 0.00307257, -0.00509595, 1.08168 + ); + mat3 AP1_2_XYZ_MAT = mat3( + 0.6624541811, 0.1340042065, 0.1561876870, + 0.2722287168, 0.6740817658, 0.0536895174, + -0.0055746495, 0.0040607335, 1.0103391003 + ); + mat3 AP0_2_AP1_MAT = mat3( + 1.4514393161, -0.2365107469, -0.2149285693, + -0.0765537734, 1.1762296998, -0.0996759264, + 0.0083161484, -0.0060324498, 0.9977163014 + ); + vec3 AP1_RGB2Y = vec3(0.2722287168, 0.6740817658, 0.0536895174); + + float FilmSlope = 0.88; + float FilmToe = 0.55; + float FilmShoulder = 0.26; + float FilmBlackClip = 0.0; + float FilmWhiteClip = 0.04; + + mat3 sRGB_2_AP0 = mul2( XYZ_2_AP0_MAT, mul2( D65_2_D60_CAT, sRGB_2_XYZ_MAT ) ); + mat3 sRGB_2_AP1 = mul2( XYZ_2_AP1_MAT, mul2( D65_2_D60_CAT, sRGB_2_XYZ_MAT ) ); + mat3 AP1_2_sRGB = mul2( XYZ_2_sRGB_MAT, mul2( D60_2_D65_CAT, AP1_2_XYZ_MAT ) ); + + vec3 ACESColor = mul2( sRGB_2_AP0, LinearColor ); + + // --- Red modifier --- // + const float RRT_RED_SCALE = 0.82; + const float RRT_RED_PIVOT = 0.03; + const float RRT_RED_HUE = 0.0; + const float RRT_RED_WIDTH = 135.0; + + float saturation = rgb_2_saturation( ACESColor ); + float hue = rgb_2_hue( ACESColor ); + float centeredHue = center_hue( hue, RRT_RED_HUE ); + float hueWeight = smoothstep( 0.0, 1.0, 1.0 - abs( 2.0 * centeredHue / RRT_RED_WIDTH ) ); + hueWeight *= hueWeight; + + ACESColor.r += hueWeight * saturation * (RRT_RED_PIVOT - ACESColor.r) * (1. - RRT_RED_SCALE); + + // Use ACEScg primaries as working space + vec3 WorkingColor = mul2( AP0_2_AP1_MAT, ACESColor ); + + WorkingColor = max( vec3(0.0), WorkingColor ); + + // Pre desaturate + WorkingColor = mix( vec3(dot( WorkingColor, AP1_RGB2Y )), WorkingColor, 0.96 ); + + float ToeScale = 1.0 + FilmBlackClip - FilmToe; + float ShoulderScale = 1.0 + FilmWhiteClip - FilmShoulder; + + float InMatch = 0.18; + float OutMatch = 0.18; + + float ToeMatch; + if( FilmToe > 0.8 ) + { + // 0.18 will be on straight segment + ToeMatch = ( 1.0 - FilmToe - OutMatch ) / FilmSlope + log10( InMatch ); + } + else + { + // 0.18 will be on toe segment + + // Solve for ToeMatch such that input of InMatch gives output of OutMatch. + float bt = ( OutMatch + FilmBlackClip ) / ToeScale - 1.0; + ToeMatch = log10( InMatch ) - 0.5 * log( (1.0+bt)/(1.0-bt) ) * (ToeScale / FilmSlope); + } + + float StraightMatch = ( 1.0 - FilmToe ) / FilmSlope - ToeMatch; + float ShoulderMatch = FilmShoulder / FilmSlope - StraightMatch; + + vec3 LogColor = log10( WorkingColor ); + vec3 StraightColor = FilmSlope * ( LogColor + StraightMatch ); + + vec3 ToeColor = ( -FilmBlackClip ) + (2.0 * ToeScale) / ( 1.0 + exp( (-2.0 * FilmSlope / ToeScale) * ( LogColor - ToeMatch ) ) ); + vec3 ShoulderColor = ( 1.0 + FilmWhiteClip ) - (2.0 * ShoulderScale) / ( 1.0 + exp( ( 2.0 * FilmSlope / ShoulderScale) * ( LogColor - ShoulderMatch ) ) ); + + ToeColor.x = LogColor.x < ToeMatch ? ToeColor.x : StraightColor.x; + ToeColor.y = LogColor.y < ToeMatch ? ToeColor.y : StraightColor.y; + ToeColor.z = LogColor.z < ToeMatch ? ToeColor.z : StraightColor.z; + + ShoulderColor.x = LogColor.x > ShoulderMatch ? ShoulderColor.x : StraightColor.x; + ShoulderColor.y = LogColor.y > ShoulderMatch ? ShoulderColor.y : StraightColor.y; + ShoulderColor.z = LogColor.z > ShoulderMatch ? ShoulderColor.z : StraightColor.z; + + vec3 t = ( ( LogColor - ToeMatch ) / ( ShoulderMatch - ToeMatch ) ); + t = clamp(t, vec3(0.0), vec3(1.0)); + t = ShoulderMatch < ToeMatch ? vec3(1.0) - t : t; + t = (3.0-2.0*t)*t*t; + vec3 ToneColor = mix( ToeColor, ShoulderColor, t ); + + // Post desaturate + ToneColor = mix( vec3(dot( ToneColor, AP1_RGB2Y )), ToneColor, 0.93 ); + + ToneColor = mul2( AP1_2_sRGB, ToneColor ); + + //return saturate( ToneColor ); + return max( vec3(0.0), ToneColor ); +} + diff --git a/src/graphics/program-lib/program-lib.js b/src/graphics/program-lib/program-lib.js index 9127307808a..4967bc91790 100644 --- a/src/graphics/program-lib/program-lib.js +++ b/src/graphics/program-lib/program-lib.js @@ -13,6 +13,8 @@ pc.programlib = { return pc.shaderChunks.tonemappingHejlPS; } else if (value===pc.TONEMAP_ACES) { return pc.shaderChunks.tonemappingAcesPS; + } else if (value===pc.TONEMAP_ACES2) { + return pc.shaderChunks.tonemappingAces2PS; } return pc.shaderChunks.tonemappingNonePS; }, diff --git a/src/scene/scene.js b/src/scene/scene.js index 5a5840803e5..d71d0e68082 100644 --- a/src/scene/scene.js +++ b/src/scene/scene.js @@ -172,6 +172,7 @@ TONEMAP_FILMIC: 1, TONEMAP_HEJL: 2, TONEMAP_ACES: 3, + TONEMAP_ACES2: 4, SPECOCC_NONE: 0, SPECOCC_AO: 1, From d3e641280e4627f21e4468c706fff2da5d44fba9 Mon Sep 17 00:00:00 2001 From: Mr F Date: Thu, 15 Sep 2016 20:12:58 +0300 Subject: [PATCH 3/5] remove different ACES --- .../program-lib/chunks/tonemappingAces2.frag | 190 ------------------ src/graphics/program-lib/program-lib.js | 2 - src/scene/scene.js | 1 - 3 files changed, 193 deletions(-) delete mode 100644 src/graphics/program-lib/chunks/tonemappingAces2.frag diff --git a/src/graphics/program-lib/chunks/tonemappingAces2.frag b/src/graphics/program-lib/chunks/tonemappingAces2.frag deleted file mode 100644 index faa536ad27a..00000000000 --- a/src/graphics/program-lib/chunks/tonemappingAces2.frag +++ /dev/null @@ -1,190 +0,0 @@ -uniform float exposure; - -mat3 mul2(mat3 a, mat3 b) { - return b * a; -} - -vec3 mul2(mat3 a, vec3 b) { - return b * a; -} - - -const float PI = 3.1415926535897932384626433832795; - -float rgb_2_saturation( vec3 rgb ) { - float minrgb = min( min(rgb.r, rgb.g ), rgb.b ); - float maxrgb = max( max(rgb.r, rgb.g ), rgb.b ); - return ( max( maxrgb, 1e-10 ) - max( minrgb, 1e-10 ) ) / max( maxrgb, 1e-2 ); -} - -// Transformations from RGB to other color representations -float rgb_2_hue( vec3 rgb ) { - // Returns a geometric hue angle in degrees (0-360) based on RGB values. - // For neutral colors, hue is undefined and the function will return a quiet NaN value. - float hue; - if (rgb[0] == rgb[1] && rgb[1] == rgb[2]) - { - //hue = FLT_NAN; // RGB triplets where RGB are equal have an undefined hue - hue = 0.0; - } - else - { - hue = (180. / PI) * atan(2.0 * rgb[0] - rgb[1] - rgb[2], sqrt(3.0)*(rgb[1] - rgb[2])); - } - - if (hue < 0.) - hue = hue + 360.0; - - return clamp( hue, 0.0, 360.0 ); -} - -float center_hue( float hue, float centerH) -{ - float hueCentered = hue - centerH; - if (hueCentered < -180.) - hueCentered += 360.0; - else if (hueCentered > 180.) - hueCentered -= 360.0; - return hueCentered; -} - -float log10(float x) { - return log(x) / log(10.0); -} - -vec3 log10(vec3 x) { - return log(x) / log(10.0); -} - -vec3 toneMap(vec3 LinearColor) { - LinearColor *= exposure; - - mat3 XYZ_2_AP0_MAT = mat3( - 1.0498110175, 0.0000000000,-0.0000974845, - -0.4959030231, 1.3733130458, 0.0982400361, - 0.0000000000, 0.0000000000, 0.9912520182 - ); - mat3 D65_2_D60_CAT = mat3( - 1.01303, 0.00610531, -0.014971, - 0.00769823, 0.998165, -0.00503203, - -0.00284131, 0.00468516, 0.924507 - ); - mat3 sRGB_2_XYZ_MAT = mat3( - 0.4124564, 0.3575761, 0.1804375, - 0.2126729, 0.7151522, 0.0721750, - 0.0193339, 0.1191920, 0.9503041 - ); - mat3 XYZ_2_AP1_MAT = mat3( - 1.6410233797, -0.3248032942, -0.2364246952, - -0.6636628587, 1.6153315917, 0.0167563477, - 0.0117218943, -0.0082844420, 0.9883948585 - ); - mat3 XYZ_2_sRGB_MAT = mat3( - 3.2409699419, -1.5373831776, -0.4986107603, - -0.9692436363, 1.8759675015, 0.0415550574, - 0.0556300797, -0.2039769589, 1.0569715142 - ); - mat3 D60_2_D65_CAT = mat3( - 0.987224, -0.00611327, 0.0159533, - -0.00759836, 1.00186, 0.00533002, - 0.00307257, -0.00509595, 1.08168 - ); - mat3 AP1_2_XYZ_MAT = mat3( - 0.6624541811, 0.1340042065, 0.1561876870, - 0.2722287168, 0.6740817658, 0.0536895174, - -0.0055746495, 0.0040607335, 1.0103391003 - ); - mat3 AP0_2_AP1_MAT = mat3( - 1.4514393161, -0.2365107469, -0.2149285693, - -0.0765537734, 1.1762296998, -0.0996759264, - 0.0083161484, -0.0060324498, 0.9977163014 - ); - vec3 AP1_RGB2Y = vec3(0.2722287168, 0.6740817658, 0.0536895174); - - float FilmSlope = 0.88; - float FilmToe = 0.55; - float FilmShoulder = 0.26; - float FilmBlackClip = 0.0; - float FilmWhiteClip = 0.04; - - mat3 sRGB_2_AP0 = mul2( XYZ_2_AP0_MAT, mul2( D65_2_D60_CAT, sRGB_2_XYZ_MAT ) ); - mat3 sRGB_2_AP1 = mul2( XYZ_2_AP1_MAT, mul2( D65_2_D60_CAT, sRGB_2_XYZ_MAT ) ); - mat3 AP1_2_sRGB = mul2( XYZ_2_sRGB_MAT, mul2( D60_2_D65_CAT, AP1_2_XYZ_MAT ) ); - - vec3 ACESColor = mul2( sRGB_2_AP0, LinearColor ); - - // --- Red modifier --- // - const float RRT_RED_SCALE = 0.82; - const float RRT_RED_PIVOT = 0.03; - const float RRT_RED_HUE = 0.0; - const float RRT_RED_WIDTH = 135.0; - - float saturation = rgb_2_saturation( ACESColor ); - float hue = rgb_2_hue( ACESColor ); - float centeredHue = center_hue( hue, RRT_RED_HUE ); - float hueWeight = smoothstep( 0.0, 1.0, 1.0 - abs( 2.0 * centeredHue / RRT_RED_WIDTH ) ); - hueWeight *= hueWeight; - - ACESColor.r += hueWeight * saturation * (RRT_RED_PIVOT - ACESColor.r) * (1. - RRT_RED_SCALE); - - // Use ACEScg primaries as working space - vec3 WorkingColor = mul2( AP0_2_AP1_MAT, ACESColor ); - - WorkingColor = max( vec3(0.0), WorkingColor ); - - // Pre desaturate - WorkingColor = mix( vec3(dot( WorkingColor, AP1_RGB2Y )), WorkingColor, 0.96 ); - - float ToeScale = 1.0 + FilmBlackClip - FilmToe; - float ShoulderScale = 1.0 + FilmWhiteClip - FilmShoulder; - - float InMatch = 0.18; - float OutMatch = 0.18; - - float ToeMatch; - if( FilmToe > 0.8 ) - { - // 0.18 will be on straight segment - ToeMatch = ( 1.0 - FilmToe - OutMatch ) / FilmSlope + log10( InMatch ); - } - else - { - // 0.18 will be on toe segment - - // Solve for ToeMatch such that input of InMatch gives output of OutMatch. - float bt = ( OutMatch + FilmBlackClip ) / ToeScale - 1.0; - ToeMatch = log10( InMatch ) - 0.5 * log( (1.0+bt)/(1.0-bt) ) * (ToeScale / FilmSlope); - } - - float StraightMatch = ( 1.0 - FilmToe ) / FilmSlope - ToeMatch; - float ShoulderMatch = FilmShoulder / FilmSlope - StraightMatch; - - vec3 LogColor = log10( WorkingColor ); - vec3 StraightColor = FilmSlope * ( LogColor + StraightMatch ); - - vec3 ToeColor = ( -FilmBlackClip ) + (2.0 * ToeScale) / ( 1.0 + exp( (-2.0 * FilmSlope / ToeScale) * ( LogColor - ToeMatch ) ) ); - vec3 ShoulderColor = ( 1.0 + FilmWhiteClip ) - (2.0 * ShoulderScale) / ( 1.0 + exp( ( 2.0 * FilmSlope / ShoulderScale) * ( LogColor - ShoulderMatch ) ) ); - - ToeColor.x = LogColor.x < ToeMatch ? ToeColor.x : StraightColor.x; - ToeColor.y = LogColor.y < ToeMatch ? ToeColor.y : StraightColor.y; - ToeColor.z = LogColor.z < ToeMatch ? ToeColor.z : StraightColor.z; - - ShoulderColor.x = LogColor.x > ShoulderMatch ? ShoulderColor.x : StraightColor.x; - ShoulderColor.y = LogColor.y > ShoulderMatch ? ShoulderColor.y : StraightColor.y; - ShoulderColor.z = LogColor.z > ShoulderMatch ? ShoulderColor.z : StraightColor.z; - - vec3 t = ( ( LogColor - ToeMatch ) / ( ShoulderMatch - ToeMatch ) ); - t = clamp(t, vec3(0.0), vec3(1.0)); - t = ShoulderMatch < ToeMatch ? vec3(1.0) - t : t; - t = (3.0-2.0*t)*t*t; - vec3 ToneColor = mix( ToeColor, ShoulderColor, t ); - - // Post desaturate - ToneColor = mix( vec3(dot( ToneColor, AP1_RGB2Y )), ToneColor, 0.93 ); - - ToneColor = mul2( AP1_2_sRGB, ToneColor ); - - //return saturate( ToneColor ); - return max( vec3(0.0), ToneColor ); -} - diff --git a/src/graphics/program-lib/program-lib.js b/src/graphics/program-lib/program-lib.js index 4967bc91790..9127307808a 100644 --- a/src/graphics/program-lib/program-lib.js +++ b/src/graphics/program-lib/program-lib.js @@ -13,8 +13,6 @@ pc.programlib = { return pc.shaderChunks.tonemappingHejlPS; } else if (value===pc.TONEMAP_ACES) { return pc.shaderChunks.tonemappingAcesPS; - } else if (value===pc.TONEMAP_ACES2) { - return pc.shaderChunks.tonemappingAces2PS; } return pc.shaderChunks.tonemappingNonePS; }, diff --git a/src/scene/scene.js b/src/scene/scene.js index d71d0e68082..5a5840803e5 100644 --- a/src/scene/scene.js +++ b/src/scene/scene.js @@ -172,7 +172,6 @@ TONEMAP_FILMIC: 1, TONEMAP_HEJL: 2, TONEMAP_ACES: 3, - TONEMAP_ACES2: 4, SPECOCC_NONE: 0, SPECOCC_AO: 1, From 8e17d895f27cf3f1d5d73b0e2faa30068912dc8b Mon Sep 17 00:00:00 2001 From: moka Date: Thu, 15 Sep 2016 18:58:39 +0100 Subject: [PATCH 4/5] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index e93d22951dc..54ea64a780c 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,8 @@ The PlayCanvas Engine is a fully featured 3D game engine. * 3D Positional audio via Web Audio API * **Resource Loading** * Simple and powerful resource loading + * Streaming of individual assets + * Asset Variants - loads compressed textures (DXT, PVR, ETC1) based on platform support * **Entity / Component System** * Built-in components: model, sound, animation, camera, collision, light, rigidbody, script, particlesystem * **Scripting system** From 88da359f4822691f56bc7031913867bc42a5c84a Mon Sep 17 00:00:00 2001 From: Mr F Date: Thu, 15 Sep 2016 21:48:16 +0300 Subject: [PATCH 5/5] better texture mem profiling --- src/graphics/device.js | 14 ++++++++++++++ src/graphics/graphics.js | 5 +++++ src/graphics/texture.js | 21 +++++++++++++++++++++ src/resources/texture.js | 6 ++++++ src/scene/forward-renderer.js | 6 ++++++ src/scene/lightmapper.js | 16 +++++++++++----- 6 files changed, 63 insertions(+), 5 deletions(-) diff --git a/src/graphics/device.js b/src/graphics/device.js index 9a558981f04..2d055914bea 100644 --- a/src/graphics/device.js +++ b/src/graphics/device.js @@ -647,6 +647,11 @@ pc.extend(pc, function () { this._renderTargetCreationTime = 0; this._vram = { + // #ifdef PROFILER + texShadow: 0, + texAsset: 0, + texLightmap: 0, + // #endif tex: 0, vb: 0, ib: 0 @@ -1201,6 +1206,15 @@ pc.extend(pc, function () { if (texture._gpuSize) this._vram.tex -= texture._gpuSize; texture._gpuSize = gpuTexSize(gl, texture); this._vram.tex += texture._gpuSize; + // #ifdef PROFILER + if (texture.profilerHint===pc.TEXHINT_SHADOWMAP) { + this._vram.texShadow += texture._gpuSize; + } else if (texture.profilerHint===pc.TEXHINT_ASSET) { + this._vram.texAsset += texture._gpuSize; + } else if (texture.profilerHint===pc.TEXHINT_LIGHTMAP) { + this._vram.texLightmap += texture._gpuSize; + } + // #endif }, setTexture: function (texture, textureUnit) { diff --git a/src/graphics/graphics.js b/src/graphics/graphics.js index 1d39b8b1a95..0bcfa30a0c9 100644 --- a/src/graphics/graphics.js +++ b/src/graphics/graphics.js @@ -667,6 +667,11 @@ */ TEXTURELOCK_WRITE: 2, + TEXHINT_NONE: 0, + TEXHINT_SHADOWMAP: 1, + TEXHINT_ASSET: 2, + TEXHINT_LIGHTMAP: 3, + UNIFORMTYPE_BOOL: 0, UNIFORMTYPE_INT: 1, UNIFORMTYPE_FLOAT: 2, diff --git a/src/graphics/texture.js b/src/graphics/texture.js index f1e2aa0dc14..98235731aa9 100644 --- a/src/graphics/texture.js +++ b/src/graphics/texture.js @@ -69,6 +69,9 @@ pc.extend(pc, function () { var cubemap = false; var rgbm = false; var fixCubemapSeams = false; + // #ifdef PROFILER + var hint = 0; + // #endif if (options !== undefined) { width = (options.width !== undefined) ? options.width : width; @@ -77,6 +80,9 @@ pc.extend(pc, function () { cubemap = (options.cubemap !== undefined) ? options.cubemap : cubemap; rgbm = (options.rgbm !== undefined)? options.rgbm : rgbm; fixCubemapSeams = (options.fixCubemapSeams !== undefined)? options.fixCubemapSeams : fixCubemapSeams; + // #ifdef PROFILER + hint = (options.profilerHint !== undefined)? options.profilerHint : 0; + // #endif } // PUBLIC @@ -84,6 +90,10 @@ pc.extend(pc, function () { this.rgbm = rgbm; this.fixCubemapSeams = fixCubemapSeams; + // #ifdef PROFILER + this.profilerHint = hint; + // #endif + // PRIVATE this._cubemap = cubemap; this._format = format; @@ -348,7 +358,18 @@ pc.extend(pc, function () { if (this._glTextureId) { var gl = this.device.gl; gl.deleteTexture(this._glTextureId); + this.device._vram.tex -= this._gpuSize; + // #ifdef PROFILER + if (this.profilerHint===pc.TEXHINT_SHADOWMAP) { + this.device._vram.texShadow -= this._gpuSize; + } else if (this.profilerHint===pc.TEXHINT_ASSET) { + this.device._vram.texAsset -= this._gpuSize; + } else if (this.profilerHint===pc.TEXHINT_LIGHTMAP) { + this.device._vram.texLightmap -= this._gpuSize; + } + // #endif + this._glTextureId = null; } }, diff --git a/src/resources/texture.js b/src/resources/texture.js index 988813a63d4..0b1e0b72055 100644 --- a/src/resources/texture.js +++ b/src/resources/texture.js @@ -108,6 +108,9 @@ pc.extend(pc, function () { format = (ext === ".jpg" || ext === ".jpeg") ? pc.PIXELFORMAT_R8_G8_B8 : pc.PIXELFORMAT_R8_G8_B8_A8; texture = new pc.Texture(this._device, { + // #ifdef PROFILER + profilerHint: pc.TEXHINT_ASSET, + // #endif width: img.width, height: img.height, format: format @@ -204,6 +207,9 @@ pc.extend(pc, function () { } var texOptions = { + // #ifdef PROFILER + profilerHint: pc.TEXHINT_ASSET, + // #endif width: width, height: height, format: format, diff --git a/src/scene/forward-renderer.js b/src/scene/forward-renderer.js index d1eb40771c4..9c9509b9035 100644 --- a/src/scene/forward-renderer.js +++ b/src/scene/forward-renderer.js @@ -352,6 +352,9 @@ pc.extend(pc, function () { function createShadowMap(device, width, height, shadowType) { var format = getShadowFormat(shadowType); var shadowMap = new pc.Texture(device, { + // #ifdef PROFILER + profilerHint: pc.TEXHINT_SHADOWMAP, + // #endif format: format, width: width, height: height, @@ -367,6 +370,9 @@ pc.extend(pc, function () { function createShadowCubeMap(device, size) { var cubemap = new pc.Texture(device, { + // #ifdef PROFILER + profilerHint: pc.TEXHINT_SHADOWMAP, + // #endif format: pc.PIXELFORMAT_R8_G8_B8_A8, width: size, height: size, diff --git a/src/scene/lightmapper.js b/src/scene/lightmapper.js index c8125fa91ef..e8773e1bdb9 100644 --- a/src/scene/lightmapper.js +++ b/src/scene/lightmapper.js @@ -87,7 +87,6 @@ pc.extend(pc, function () { this._stats = { renderPasses: 0, lightmapCount: 0, - lightmapMem: 0, totalRenderTime: 0, forwardTime: 0, fboTime: 0, @@ -176,7 +175,7 @@ pc.extend(pc, function () { var pass; // #ifdef PROFILER - stats.renderPasses = stats.lightmapMem = stats.shadowMapTime = stats.forwardTime = 0; + stats.renderPasses = stats.shadowMapTime = stats.forwardTime = 0; var startShaders = device._shaderStats.linked; var startFboTime = device._renderTargetCreationTime; var startCompileTime = device._shaderStats.compileTime; @@ -262,7 +261,11 @@ pc.extend(pc, function () { size = this.calculateLightmapSize(nodes[i]); texSize.push(size); for(pass=0; pass