X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Fgraphics%2Fshaders%2Fcolor-visual-shader.frag;h=3e3d19d513cc113725a026b5de165685f73a3a43;hp=bf936290f63c3e0a152d67cfdb5f1734305ac4fd;hb=28dbaf3b45fc33f10e44310896d98c9ac16f6882;hpb=0547e874c936c6837e6e4511a7715cf555b0fb68 diff --git a/dali-toolkit/internal/graphics/shaders/color-visual-shader.frag b/dali-toolkit/internal/graphics/shaders/color-visual-shader.frag index bf93629..3e3d19d 100644 --- a/dali-toolkit/internal/graphics/shaders/color-visual-shader.frag +++ b/dali-toolkit/internal/graphics/shaders/color-visual-shader.frag @@ -23,6 +23,7 @@ uniform lowp vec3 mixColor; uniform mediump float borderlineWidth; uniform mediump float borderlineOffset; uniform lowp vec4 borderlineColor; +uniform lowp vec4 uActorColor; #endif #if IS_REQUIRED_BLUR uniform mediump float blurRadius; @@ -121,27 +122,54 @@ lowp vec4 convertBorderlineColor(lowp vec4 textureColor) { // potential is inside borderline range. borderlineOpacity = smoothstep(gMinInlinePotential, gMaxInlinePotential, potential); + + // Muliply borderlineWidth to resolve very thin borderline + borderlineOpacity *= min(1.0, borderlineWidth); } - //calculate inside of borderline when outilneColor.a < 1.0 - if(borderlineColor.a < 1.0) + lowp vec3 borderlineColorRGB = borderlineColor.rgb * uActorColor.rgb; + lowp float borderlineColorAlpha = borderlineColor.a * uActorColor.a; + // NOTE : color-visual is always not preMultiplied. + + // Calculate inside of borderline when alpha is between (0.0 1.0). So we need to apply texture color. + // If borderlineOpacity is exactly 0.0, we always use whole texture color. In this case, we don't need to run below code. + // But if borderlineOpacity > 0.0 and borderlineColor.a == 0.0, we need to apply tCornerRadius. + if(borderlineOpacity > 0.0 && borderlineColor.a * borderlineOpacity < 1.0) { mediump float tCornerRadius = -gCenterPosition; mediump float MaxTexturelinePotential = tCornerRadius + gPotentialRange; mediump float MinTexturelinePotential = tCornerRadius - gPotentialRange; if(potential > MaxTexturelinePotential) { - // potential is out of texture range. use borderline color instead of texture - textureColor = vec4(borderlineColor.xyz, 0.0); + // potential is out of texture range. + textureColor = vec4(0.0); } - else if(potential > MinTexturelinePotential) + else { - // potential is in texture range - textureColor = mix(textureColor, vec4(borderlineColor.xyz, 0.0), smoothstep(MinTexturelinePotential, MaxTexturelinePotential, potential)); + // potential is in texture range. + lowp float textureAlphaScale = mix(1.0, 0.0, smoothstep(MinTexturelinePotential, MaxTexturelinePotential, potential)); + textureColor.a *= textureAlphaScale; + textureColor.rgb *= textureColor.a; } - borderlineOpacity *= borderlineColor.a; + + // NOTE : color-visual is always not preMultiplied. + borderlineColorAlpha *= borderlineOpacity; + borderlineColorRGB *= borderlineColorAlpha; + // We use pre-multiplied color to reduce operations. + // In here, textureColor and borderlineColorRGB is pre-multiplied color now. + + // Manual blend operation with premultiplied colors. + // Final alpha = borderlineColorAlpha + (1.0 - borderlineColorAlpha) * textureColor.a. + // (Final rgb * alpha) = borderlineColorRGB + (1.0 - borderlineColorAlpha) * textureColor.rgb + // If preMultipliedAlpha == 1.0, just return vec4(rgb*alpha, alpha) + // Else, return vec4((rgb*alpha) / alpha, alpha) + + lowp float finalAlpha = mix(textureColor.a, 1.0, borderlineColorAlpha); + lowp vec3 finalMultipliedRGB = borderlineColorRGB + (1.0 - borderlineColorAlpha) * textureColor.rgb; + // TODO : Need to find some way without division + return vec4(finalMultipliedRGB / finalAlpha, finalAlpha); } - return mix(textureColor, vec4(borderlineColor.xyz, 1.0), borderlineOpacity); + return mix(textureColor, vec4(borderlineColorRGB, borderlineColorAlpha), borderlineOpacity); } #endif @@ -156,8 +184,8 @@ mediump float calculateCornerOpacity() // calculate borderline opacity by potential if(potential > gMaxOutlinePotential) { - // potential is out of borderline range - opacity = 0.0; + // potential is out of borderline range. just discard here + discard; } else if(potential > gMinOutlinePotential) { @@ -213,18 +241,18 @@ mediump float calculateBlurOpacity() // solve (v.x - x)^2 + (v.y - x)^2 = (cr / cy * x)^2 #if IS_REQUIRED_ROUNDED_CORNER - // NOTE : lowspec HW cannot calculate here. need to reduce numeric error - mediump float A = (cr * cr - 2.0 * cy * cy); - mediump float B = cy * (v.x + v.y); - mediump float V = dot(v,v); - mediump float D = B * B + A * V; + // Note : lowspec HW cannot calculate here. need to reduce numeric error + highp float A = (cr * cr - 2.0 * cy * cy); + highp float B = cy * (v.x + v.y); + highp float V = dot(v,v); + highp float D = B * B + A * V; potential = V * (cr + cy) / (sqrt(D) + B); #else // We can simplify this value cause cy = 0.8 * blurRadius, cr = 1.2 * blurRadius // potential = 5.0*(sqrt(4.0*(v.x+v.y)^2 + dot(v,v)) - 2.0*(v.x+v.y)); // = 10.0*(v.x+v.y) * (sqrt(1.0 + (length(v) / (2.0*(v.x+v.y)))^2) - 1.0); // = 10.0*(v.x+v.y) * (sqrt(1.25 - x + x^2) - 1.0); - // ~= 10.0*(v.x+v.y) * (0.11803399 - 0.44721360x + 0.35777088x^2 - 0.14310x^3 + O(x^4)) (Taylor series) + // ~= 10.0*(v.x+v.y) * (0.11803399 - 0.44721360x + 0.35777088x^2 - 0.14310x^3 + O(x^5)) (Taylor series) // ~= -1.0557281 * (v.x + v.y) + 2.236068 * length(v) - ~~~ (here, x <= 0.5 * (1.0 - sqrt(0.5)) < 0.1464467) // Note : This simplify need cause we should use it on lowspec HW. mediump float x = 0.5 * (1.0 - length(v) / (v.x + v.y));