您的位置:首页 > 运维架构

ps 色相/饱和度,描边,外发光算法(opengl)

2014-10-16 20:23 204 查看
做游戏可能需要有些动态的改变图片效果要求,这些用ps做的很容易,但是耗资源,所以在这里列举几个常用的滤镜算法,效果算是一般,没ps的专业 ~~



#ifdef GL_ES

precision mediump float;

#endif

uniform float Hue; //色相

uniform float Sat; //饱和度

uniform float Lig; //明度

uniform float Bri; //亮度

uniform float mode;

uniform vec2 TextureSize;

uniform vec2 resolution;

uniform vec3 GlowColor;//发光色

uniform float GlowRange;//发光范围

uniform float GlowExpand; //发光强度

uniform vec3 OutlineColor;//描边颜色

uniform float OutlineRange;//描边范围

varying vec4 v_fragmentColor;

varying vec2 v_texCoord;

1.色相/饱和度

if( Hue != 0.0 || Sat !=0.0 || Lig != 0.0 )

{

float Cmax, Cmin;

float D;

float H, S, L;

Cmax = max (R, max (G, B));

Cmin = min (R, min (G, B));

L = (Cmax + Cmin) /2.0;

if (Cmax == Cmin)

{

H =0.0;

S =0.0;

}

else

{

D = Cmax - Cmin;

if (L < 0.5)

{

S = D / (Cmax + Cmin);

}

else

{

S = D / (2.0 - (Cmax + Cmin));

}

if (R == Cmax)

{

H = (G - B) / D;

}

else

{

if (G == Cmax)

{

H =2.0 + (B - R) /D;

}

else

{

H =4.0 + (R - G) / D;

}

}

H = H /6.0;

}

// modify H/S/L values

H += Hue;

S += Sat;

L += Lig;

if (H < 0.0)

{

H = H +1.0;

}

H = clamp(H,0.0, 1.0);

S = clamp(S,0.0, 1.0);

L = clamp(L,0.0, 1.0);

// convert back to RGB

float var_2, var_1;

if (S == 0.0)

{

R = L;

G = L;

B = L;

}

else

{

if ( L < 0.5 )

{

var_2 = L * (1.0 + S );

}

else

{

var_2 = ( L + S ) - ( S * L );

}

var_1 =2.0 * L - var_2;

R = Hue_2_RGB( var_1, var_2, H + (1.0 / 3.0 ) );

G = Hue_2_RGB( var_1, var_2, H );

B = Hue_2_RGB( var_1, var_2, H - (1.0 / 3.0 ) );

}

}

if ( Bri != 0.0 )

{

if ( Bri > 0.0 )

{

R = R + (255.0 - R) /255.0 * Bri;

G = G + (255.0 - G) /255.0 * Bri;

B = B + (255.0 - B) /255.0 * Bri;

}

else

{

R = R + R /255.0 * Bri;

G = G + G /255.0 * Bri;

B = B + B /255.0 * Bri;

}

}

2.描边

float radius=0.005;

normal = texture2D(jjxx, vec2(jjv_texCoord.x, jjv_texCoord.y));

accum += texture2D(jjxx, vec2(jjv_texCoord.x - radius, jjv_texCoord.y - radius));

accum += texture2D(jjxx, vec2(jjv_texCoord.x + radius, jjv_texCoord.y - radius));

accum += texture2D(jjxx, vec2(jjv_texCoord.x + radius, jjv_texCoord.y + radius));

accum += texture2D(jjxx, vec2(jjv_texCoord.x - radius, jjv_texCoord.y + radius));

accum *=1.0;

accum.rgb = vec3(1,1,0) * accum.a;

//accum.a = 1;

normal = ( accum * (1.0 - normal.a)) + (normal * normal.a);

gl_FragColor =normal;

3.外发光

float samplerPre = 2.0;

float radiusX = 1.0 / TextureSize.x;

float radiusY = 1.0 / TextureSize.y;

float glowAlpha = 0.0;

float count = 0.0;

for( float i = -GlowRange ; i <= GlowRange ; i += samplerPre )

{

for( float j = -GlowRange ; j <= GlowRange ; j += samplerPre )

{

vec2 samplerTexCoord = vec2( v_texCoord.x + j * radiusX , v_texCoord.y + i * radiusY );

if( samplerTexCoord.x < 0.0 || samplerTexCoord.x > 1.0 || samplerTexCoord.y <0.0 || samplerTexCoord.y > 1.0 )

glowAlpha +=0.0;

else

glowAlpha += texture2D( CC_Texture0, samplerTexCoord ).a;

count +=1.0;

}

}

glowAlpha/= (count+500);

R = GlowColor.r;

G = GlowColor.g;

B = GlowColor.b;

A = glowAlpha *GlowExpand;

描边和外发光主要是滤波算法取附近的颜色算平均色,描边是在颜色alpha为0,也就是没有颜色的时候取附近的颜色,如果附近有颜色,那么就设置为描边色,可以根据alpha算颜色值。外发光,外观上表现为离颜色区域近的发光色多些,远的就慢慢淡了,所以可以根据附近的alpha总和取平均值计算透明度,这样运行的效果有发光的表现,但是与ps的发光效果相比还有一定差距,这个需要更好的完善发光算法吧。~

发光效果图:



色相效果图:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: