Shader 和 RenderTexture先贴上两张效果图(Shader) (RenderTexture)说一下实现的原因,因为项目中需要夜景,光影的效果。最初想到使用Shader来实现。实现之后。效果还不错。因为最初的测试是在Mac上跑的客户端,效果不错。但是放到手机端上 ...
Shader 和 RenderTexture
先贴上两张效果图
(Shader)
(RenderTexture)
说一下实现的原因,因为项目中需要夜景,光影的效果。最初想到使用Shader来实现。实现之后。效果还不错。因为最初的测试是在Mac上跑的客户端,效果不错。但是放到手机端上之后。发现效率太低。超过3个光源之后,效率下降的太严重。不过既然做了,就拿出来分享一下。另一个则是用RenderTexture来实现的。效率则比Shader效率高很多。
Shader篇
思路讲解
- Shader中的所有的数据都是真实像素点来进项渲染的,而程序中则更多的是逻辑像素点来进行的,所以代码中又关于Zoom相关的字段都是处理相关的位置转换的代码
- 前文提到过关于光源超过三个的时候出现的问题。主要原因是,所有的渲染点都需要跟不同的光点位置进行运算。然后计算出他最后的使用哪个光电最亮(不透明度最低),然后取用这个值,所以一个光点运行一次,两个光点运行两次,以此类推。所以我做出的优化是减少判断的个数
- 能够减少的位置有 全透明区域 全黑区域。其实全透明区域最容易判断,下文中的等于0就直接Break则是对于全透明区域的优化。全黑区域则相对复杂一些。
- 全黑区域的优化。在C++代码中,我吧屏幕分成了24*16的网格,然后用C++代码与光点进行运算,初始化网格。然后把网格传入Shader中。Shader中则判定自己是不是处于全黑网格,如果处于全黑网格,则直接渲染为黑色不做后续处理
- 其他内容应该非常容易理解了。不做赘述
Shader 代码
1 #ifdef GL_ES 2 precision highp float; 3 #endif 4 5 int screen_width = 24; 6 int screen_height = 16; 7 uniform float shader_zoom; 8 uniform vec4 night_color; 9 uniform vec2 light_pos[10];10 uniform float light_lenght[10];11 uniform float light_glare_lenght[10];12 uniform float light_all_length[10];13 uniform float light_all_length_sq[10];14 uniform float light_glare_lenght_sq[10];15 uniform int light_count;16 uniform float screen_zoom;17 uniform float screen_mapping[24 * 16];18 //uniform sampler2D screen_mapping;19 20 float po_2_light_lenght[10];21 22 void main(void)23 {24 float f = 1.0;25 26 int i = 0;27 vec2 p;28 float color;29 float color_f;30 float length_sq;31 float length_f;32 33 int type = 0;34 35 int x = int(gl_FragCoord.x / screen_zoom / shader_zoom);36 int y = int(gl_FragCoord.y / screen_zoom / shader_zoom);37 38 while (i < light_count)39 {40 if(screen_mapping[y * screen_width + x] == 1.0)41 {42 break;43 }44 45 if(f == 0.0)46 {47 break;48 }49 50 p = gl_FragCoord.xy - light_pos[i].xy;51 52 length_sq = dot(p, p);53 54 55 if(length_sq >= light_all_length_sq[i])56 {57 i++;58 continue;59 }60 61 if(length_sq <= light_glare_lenght_sq[i])62 {63 f = 0.0;64 i++;65 continue;66 }67 68 color = length(p) - light_glare_lenght[i];69 color_f = clamp(color / light_lenght[i], 0.0, 1.0);70 71 if(color_f < f)72 {73 f = color_f;74 }75 76 i++;77 }78 79 gl_FragColor = vec4(f * night_color);80 }
原标题:Cocos2dx实现光影效果的两种方式
关键词:
*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们:
admin#shaoqun.com
(#换成@)。