前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >cocos2dx 编写shader 遇到 溢出问题[通俗易懂]

cocos2dx 编写shader 遇到 溢出问题[通俗易懂]

作者头像
全栈程序员站长
发布2022-07-08 21:21:37
3080
发布2022-07-08 21:21:37
举报

大家好,又见面了,我是全栈君。

在 编程语言中,不论什么 数据类型 都有 各种 的 局限,无法 表示 现实世界中的 不论什么 情况。 比如 int ,char 会 溢出,float 会 有 溢出 以及 精度 不准确的 情况。

所以 我们 在 开发 中 须要 特别 注意 这些事。

近期 须要 在 cocos2dx(2.1.4) 引擎下 用 shader 做一些 效果。遇到 一些 在 windows 上 没有问题,可是 移植到 android 就会 出问题的 现象。

记录 下来。一为 加深印象 。二为 提供 遇到 同类 问题 的 博友 參考。

主要 集中 在 双方面:

(1) shader 不支持 不同类型的 数 进行 运算

比如

int a ;

float b ;

float c = a + b;

这个 问题 倒是 还行 ,由于 在 eclipse 里 cocos2dx 会 打印 编译 错误的 log

(2) 浮点型 溢出问题,这样的 问题 会 比較 难解决,我也是 慢慢试出来的

首先 看看 shader 精度的 一些 最低范围

cocos2dx 编写shader 遇到 溢出问题[通俗易懂]
cocos2dx 编写shader 遇到 溢出问题[通俗易懂]

以下 是我的 部分 shader 源代码:

代码语言:javascript
复制
<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>

错误 集中在 float dis = distance(pos,u_touchPos);

distance 是 求 屏幕中的 两个点的 距离。 我预计 它 的 形式 大致 是 这种

float distance(vec2 pos1, vec2 pos2){

vec3 sub = pos1 – pos2;

return sqrt(sub.x * sub.x + sub.y * sub.y);

}

因为 cocos2dx 会 默认 设置 顶点着色器 使用 高精度 float, 片元着色器 使用 中等 精度 float, (我这段代码 是 片元着色器的 代码),

所以 float 的 范围 在-16384 ~ 16384 之间, 当 两个 百位数 相乘 非常有可能 造成 溢出。

以下 给出 最后 改动的 代码:

代码语言:javascript
复制
<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>

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/115776.html原文链接:https://javaforall.cn

本文参与?腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022年1月3,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客?前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com