cocos2dx shader -- Vol.2(blur, frost, bloom)

cocos2dx shader系列一——中级篇

讲完基本篇,现在讲中级篇。主要有这几个效果高斯模糊、冰霜、外发光三个效果。

一、blur

模糊是常用的效果,而高斯模糊是最常见的模糊效果。基本原理就是原pixel需要混合周围pixel生成目标pixel,混合的方式有多种,常用的有四点采样、七点采样和九点采样,这里采用九点采样,采样偏移和权重分别为:

float p_offset = {-4, -3, -2, -1, 0, 1, 2, 3, 4};

float p_weight = {0.05, 0.09, 0.12, 0.15, 0.16, 0.15, 0.12, 0.09, 0.05};

目标像素即为:

	vec4 sample = vec4(0, 0, 0, 0);
	for (int i = 0; i < 9; i ++){
	    sample+= texture2D(u_texture, v_texCoord - p_offset[i] * pix_size) * p_weight[i];
	}
	gl_FragColor = sample;
pix_size是目标texture的像素点单位即为(1/texture宽, 1/texture高)。

水平上blur和垂直上blur的效果分别为:




经过两轮blur后的效果:




二、frost

这是个霜冻效果,


进过blur后:


shader:

#ifdef GL_ES
precision mediump float;
#endif

uniform sampler2D u_texture;
uniform sampler2D tex_noise;

uniform vec2 pix_size;
uniform float PixelX = 0.5;
uniform float PixelY = 0.5;
uniform float Freq = 0.115;

varying vec2 v_texCoord;
varying vec4 v_fragmentColor;


vec4 spline(float x, vec4 c1, vec4 c2, vec4 c3, vec4 c4, vec4 c5, vec4 c6, vec4 c7, vec4 c8, vec4 c9)
{
	float w1, w2, w3, w4, w5, w6, w7, w8, w9;
	w1 = 0.0;
	w2 = 0.0;
	w3 = 0.0;
	w4 = 0.0;
	w5 = 0.0;
	w6 = 0.0;
	w7 = 0.0;
	w8 = 0.0;
	w9 = 0.0;
	float tmp = x * 8.0;
	if (tmp<=1.0) {
	w1 = 1.0 - tmp;
	w2 = tmp;
	}
	else if (tmp<=2.0) {
	tmp = tmp - 1.0;
	w2 = 1.0 - tmp;
	w3 = tmp;
	}
	else if (tmp<=3.0) {
	tmp = tmp - 2.0;
	w3 = 1.0-tmp;
	w4 = tmp;
	}
	else if (tmp<=4.0) {
	tmp = tmp - 3.0;
	w4 = 1.0-tmp;
	w5 = tmp;
	}
	else if (tmp<=5.0) {
	tmp = tmp - 4.0;
	w5 = 1.0-tmp;
	w6 = tmp;
	}
	else if (tmp<=6.0) {
	tmp = tmp - 5.0;
	w6 = 1.0-tmp;
	w7 = tmp;
	}
	else if (tmp<=7.0) {
	tmp = tmp - 6.0;
	w7 = 1.0 - tmp;
	w8 = tmp;
	}
	else 
	{
	//tmp = saturate(tmp - 7.0);
	// http://www.ozone3d.net/blogs/lab/20080709/saturate-function-in-glsl/
	tmp = clamp(tmp - 7.0, 0.0, 1.0);
	w8 = 1.0-tmp;
	w9 = tmp;
	}
	return w1*c1 + w2*c2 + w3*c3 + w4*c4 + w5*c5 + w6*c6 + w7*c7 + w8*c8 + w9*c9;
}

vec3 noise(vec2 p)
{
	return texture2D(tex_noise,p).xyz; 
}

void main() 
{ 
	vec2 uv = v_texCoord.xy;
	vec3 tc = vec3(1.0, 0.0, 0.0);
    
	float DeltaX = PixelX * pix_size.x;
	float DeltaY = PixelY * pix_size.y;
	vec2 ox = vec2(DeltaX,0.0);
	vec2 oy = vec2(0.0,DeltaY);
	vec2 PP = uv - oy;
	vec4 C00 = texture2D(u_texture,PP - ox);
	vec4 C01 = texture2D(u_texture,PP);
	vec4 C02 = texture2D(u_texture,PP + ox);
	PP = uv;
	vec4 C10 = texture2D(u_texture,PP - ox);
	vec4 C11 = texture2D(u_texture,PP);
	vec4 C12 = texture2D(u_texture,PP + ox);
	PP = uv + oy;
	vec4 C20 = texture2D(u_texture,PP - ox);
	vec4 C21 = texture2D(u_texture,PP);
	vec4 C22 = texture2D(u_texture,PP + ox);

	float n = noise(Freq*uv).x;
	n = mod(n, 0.111111)/0.111111;
	vec4 result = spline(n,C00,C01,C02,C10,C11,C12,C20,C21,C22);
	tc = result.rgb;    
  
	gl_FragColor = vec4(tc, 1.0);
}

三、bloom

外发光的做法也是个依赖blur的效果,常见的做法是先生成一张高亮图,然后再将该高亮图blur,得到扩大模糊的边缘也就得到了我们想要的效果,


生成高亮图:


blur后效果对比:


叠加原图的效果:


shader里的blur和上边的一样,高亮的shader,根据灰度值改变亮度:

#ifdef GL_ES
precision mediump float;
#endif

uniform sampler2D u_texture;
varying vec2 v_texCoord;
varying vec4 v_fragmentColor;

uniform float intensity_offset = 1.0;
uniform float intensity_scale = 2.0;

void main(void)  
{   
    vec4 texColor = texture2D(u_texture, v_texCoord);
	// gray value
	float gray = dot(texColor.rgb, vec3(0.3f, 0.59f, 0.11f));
	// new gray
	float new_intensity = (gray + intensity_offset) * intensity_scale;
	
	// fixed color
	gl_FragColor = texColor * new_intensity;
} 

当然我们可以不一样原图的rgb,自定义颜色,如:


两个步骤的shader可以和在一起写,也可采用取巧的方法。


Repository: 代码

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Cocos2d-x 中的富文本可以通过 RichText 类来实现。RichText 类提供了一种简单的方式来创建并渲染富文本。通过 RichText 可以添加不同的字体、颜色、大小和对齐方式等属性,同时还支持添加图片和超链接等元素。 以下是一个简单的使用 RichText 的示例: ``` auto label = cocos2d::ui::RichText::create(); label->ignoreContentAdaptWithSize(false); label->setContentSize(Size(200, 100)); // 添加文字 auto text = cocos2d::ui::RichElementText::create(1, Color3B::WHITE, 255, "Hello World", "Arial", 12); label->pushBackElement(text); // 添加图片 auto image = cocos2d::ui::RichElementImage::create(2, Color3B::WHITE, 255, "path/to/image.png"); label->pushBackElement(image); // 添加超链接 auto link = cocos2d::ui::RichElementText::create(3, Color3B::YELLOW, 255, "click me", "Arial", 12); link->setUnderline(true); link->setUrl("http://www.example.com"); label->pushBackElement(link); label->setPosition(Vec2(100, 100)); addChild(label); ``` 在上面的示例中,我们创建了一个 RichText 对象,并添加了一些不同类型的元素:文本、图片和超链接。可以通过设置 setContentSize() 方法来指定 RichText 的大小,并使用 pushBackElement() 方法添加元素。元素的类型可以通过创建不同类型的 RichElement 对象来实现。在示例中,我们创建了 RichElementText 、RichElementImage 和 RichElementText 对象,分别表示文本、图片和超链接。 在创建 RichElementText 和 RichElementImage 对象时,需要指定一些属性,例如字体、颜色、大小和路径等。对于超链接,可以使用 setUrl() 方法来指定链接地址,同时还可以设置下划线等样式。 最后,我们将 RichText 添加到场景中,并设置其位置。通过这种方式,就可以轻松地创建和渲染富文本。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值