@H_403_0@最近 需要 在 cocos2dx(2.1.4) 引擎下 用 shader 做一些 效果,遇到 一些 在 windows 上 没有问题,但是 移植到 android 就会 出问题的 现象。记录 下来,一为 加深印象 ,二为 提供 遇到 同类 问题 的 博友 参考。 @H_403_0@
@H_403_0@主要 集中 在 两方面: @H_403_0@(1) shader 不支持 不同类型的 数 进行 运算 @H_403_0@例如 @H_403_0@int a ; @H_403_0@float b ; @H_403_0@float c = a + b; @H_403_0@这个 问题 倒是 还行 ,因为 在 eclipse 里 cocos2dx 会 打印 编译 错误的 log @H_403_0@
@H_403_0@(2) 浮点型 溢出问题,这种 问题 会 比较 难解决,我也是 慢慢试出来的 @H_403_0@首先 看看 shader 精度的 一些 最低范围 @H_403_0@
@H_403_0@
@H_403_0@下面 是我的 部分 shader 源码:
<span style="font-size:18px;">//varying vec4 v_fragmentColor; varying vec2 v_texCoord; uniform float u_radius; uniform vec2 u_touchPos; uniform vec2 u_bgSize; uniform sampler2D CC_Texture0; float isInCircle(){ vec2 pos = u_bgSize * v_texCoord; float dis = distance(pos,u_touchPos); if(dis >= u_radius || u_radius == 0.0) return 1.0; else return 0.0; } void main() { vec4 texColor = texture2D(CC_Texture0,v_texCoord); float isIn = isInCircle(); gl_FragColor = texColor * isIn; }</span>@H_403_0@错误 集中在float dis = distance(pos,u_touchPos); @H_403_0@distance是 求 屏幕中的 两个点的 距离, 我估计 它 的 形式 大致 是 这样的 @H_403_0@float distance(vec2 pos1,vec2 pos2){ @H_403_0@vec3 sub = pos1 - pos2; @H_403_0@return sqrt(sub.x * sub.x + sub.y * sub.y); @H_403_0@} @H_403_0@由于 cocos2dx 会 默认 设置 顶点着色器 使用 高精度 float,片元着色器 使用 中等 精度 float,(我这段代码 是 片元着色器的 代码), @H_403_0@所以 float 的 范围 在-16384 ~ 16384 之间, 当 两个 百位数 相乘 很有可能 造成 溢出。 @H_403_0@
@H_403_0@下面 给出 最后 修改的 代码:
<span style="font-size:18px;">//varying vec4 v_fragmentColor; varying vec2 v_texCoord; uniform float u_radius; uniform highp vec2 u_touchPos; uniform vec2 u_bgSize; uniform sampler2D CC_Texture0; float isInCircle(){ highp vec2 pos = u_bgSize * v_texCoord; float dis = distance(pos,u_touchPos); if(dis >= u_radius) return 1.0; else return 0.0; } void main() { vec4 texColor = texture2D(CC_Texture0,v_texCoord); float isIn = isInCircle(); gl_FragColor = texColor * isIn; }</span>