shader 外发光效果

我用的是corona的引擎,所以有点GLSL用法有些不同,不过语言还是相同的。

先放代码:

category = "filter",
name = "outline",
isTimeDependent = true,
vertexData = {
	--CoronaVertexUserData.x //宽度
	{ 
		name = "width",
		default = 1,
		index = 0,
	},
	--CoronaVertexUserData.y //颜色
	{ 
		name = "color",
		default = 0,
		index = 1,
	},
	--CoronaVertexUserData.z //闪烁速度  0为不闪烁
	{ 
		name = "flashSpeed",
		default = 0,
		index = 2,
	},
	--CoronaVertexUserData.w //检测精度
	{ 
		name = "accuracy",
		default = 1,
		index = 3,
	},
},
fragment =
[[
	vec2 textureSize = vec2(CoronaTexelSize.x*1334.0,CoronaTexelSize.y*750.0);
	//红
	vec3 red = vec3(1,0,0);
	//绿
	vec3 green = vec3(0,1,0);
	//蓝
	vec3 blue = vec3(0,0,1);

	vec3 outlineColor = vec3(0,0,0);
			
	float outlineSize = CoronaVertexUserData.x;
	float getIsStrokeWithAngel(float angel,vec2 v_texCoord)
	{
		float stroke = 0.0;
		float rad = angel * 0.01745329252; // 这个浮点数是 pi / 180,角度转弧度
		vec2 unit = 1.0 / textureSize.xy;//单位坐标
		vec2 offset = vec2(outlineSize * cos(rad) * unit.x, outlineSize * sin(rad) * unit.y); //偏移量
		float a = texture2D(CoronaSampler0, v_texCoord + offset).a;
		if (a >= 0.5)// 我把alpha值大于0.5都视为不透明,小于0.5都视为透明
		{
			 stroke = 1.0;
		}
		return stroke;
	}
	P_COLOR vec4 FragmentKernel( P_UV vec2 texCoord )
	{
				outlineColor = red;
				if (CoronaVertexUserData.y==0.0)
				{
					outlineColor = red;
				}
				if(CoronaVertexUserData.y==1.0)
				{
					outlineColor = green;
				}
				if(CoronaVertexUserData.y==2.0)
				{
					outlineColor = blue;
				}

				vec4 texColor = texture2D(CoronaSampler0, texCoord); // 正在处理的这个像素点的颜色
			    if (texColor.a >= 0.5) // 不透明,不管,直接返回
			    {
			        return CoronaColorScale(texColor);
			    }
			    float strokeCount = 0.0;
			    float onceAngel = CoronaVertexUserData.w;//每次检测的角度
			    for(float angel = 0.0; angel < 360.0; angel += onceAngel)  
				{
					strokeCount += getIsStrokeWithAngel(angel,texCoord);
				}

			    if (strokeCount > 0.0) // 四周围至少有一个点是不透明的,这个点要设成描边颜色
			    {
			        texColor.rgb = outlineColor;
			        texColor.a = 1.0;
			        float sumCount = 360.0/onceAngel;
			        texColor.rgba = texColor.rgba*(strokeCount/sumCount);
			    }
			    texColor.rgba = texColor.rgba*cos(CoronaTotalTime*CoronaVertexUserData.z);
		   	 	return CoronaColorScale(texColor );
	}
]]

先解释一下corona引擎可直接获取到变量的意思:

CoronaTexelSize为纹理的大小,范围是0-1,所以真正大小是CoronaTexelSize.x*屏幕高=真实高,CoronaTexelSize.y*屏幕宽=真实宽

CoronaTotalTime为打开应用到现在的运行时间

CoronaVertexUserData.xyzw为外部传入的参数

CoronaSampler0为纹理采样

我是参考了别人用cocos shader写的单纯描边,并且在基础思路上修改。

这个shader的大致思路是:

    1.在片段着色器 检测每个像素点的透明度是否大于0.5,如果大于0.5则不处理像素点的颜色。

    2.如果检测到像素点的透明度小于0.5,就以该像素点为圆心,outlineSize为半径,检测该圆周上透明度大于0.5的像素点有几个。(检测的精度和onceAngel有关,onceAngel每次检测的角度)。如果该圆周上有透明度大于0.5的像素点,(strokeCount为这个圆周上,像素点透明度为0.5的个数),就说明该像素点(圆心)在图片的边缘,可以为他设置边缘的颜色。

    到此为止是设置单纯描边的思路。接下来是让描边又内二外有渐变的效果,类似外发光。

    3.所以当strokeCount越大,我们是不是可以认为,该像素点离图像越近,反之则相反。所以利用

        float sumCount = 360.0/onceAngel;

        strokeCount/sumCount为百分比,去设置透明度。

        这样越边缘的透明度就越低。

    4.并且根据CoronaTotalTime和正余弦函数控制外边缘发光的闪烁速度。

 

    

转载于:https://my.oschina.net/u/3891480/blog/1932347

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您提供一个基于 cocoscreator 2.4.x 的发光 shader。以下是代码: ``` CCEffect %{ techniques: - name: glow passes: - vert: ccShader_PositionTextureColor_vert frag: glow_frag } %} CCProgram glow { CCShader_PositionTextureColor_vert, highp vec4 blurSize; void main() { mat4 mvp; CC_USE_MVP(mvp); gl_Position = mvp * vec4(a_position, 1); v_fragmentColor = a_color; v_texCoord = a_texCoord; } CCShader_Header { uniform highp vec4 blurSize; varying lowp vec4 v_fragmentColor; varying mediump vec2 v_texCoord; const highp float glowPow = 2.0; const highp float glowStrength = 0.5; } CCShader glow_frag { highp vec4 blurSize; highp float blurRadius = 2.0; void main() { highp vec4 sum = vec4(0.0); highp vec2 texcoord = v_texCoord.xy; highp vec2 blur = blurSize.xy; highp float strength = blurSize.z; highp float glow = blurSize.w; highp float samples = 8.0; highp vec4 col = texture2D(CC_Texture0, texcoord); for (highp float i = 0.0; i < samples; i++) { highp float angle = i / samples * 3.14159265 * 2.0; highp vec2 blurDirection = vec2(sin(angle), cos(angle)); highp vec4 blurCol = texture2D(CC_Texture0, texcoord + blurDirection * blurRadius * blur); sum += blurCol; } highp vec4 glowCol = sum / samples; glowCol = (glowCol - col) * glow * glowPow + col; gl_FragColor = mix(col, glowCol, strength) * v_fragmentColor; } } } ``` 您可以将此代码添加到您的 cocoscreator 2.4.x 项目中,然后将此 shader 应用于需要发光效果的 sprite 上。希望这可以帮到您!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值