在WebGL着色器中获取精确的整数模

在WebGL着色器中获取精确的整数模,webgl,shader,fragment-shader,Webgl,Shader,Fragment Shader,我想在WebGL片段着色器中获得x和y的精确模x和y是整数 通过绘制mod(x,y),我们得到以下结果: 用于生成红色和黑色矩形的实际代码为: gl_FragColor = vec4(mod( float(int(v_texCoord[0]*15.))/15., float(int(v_texCoord[1]*15.))/15. ), 0, 0, 1); 其中v_texCoord是一个vec2,范围从左上角的0,0到右下角的1,1。float和int的精度都设置为mediump 阅读

我想在WebGL片段着色器中获得
x
y
的精确模
x
y
是整数

通过绘制mod(x,y),我们得到以下结果:

用于生成红色和黑色矩形的实际代码为:

gl_FragColor = vec4(mod(
  float(int(v_texCoord[0]*15.))/15.,
  float(int(v_texCoord[1]*15.))/15.
), 0, 0, 1);
其中v_texCoord是一个vec2,范围从左上角的
0,0
到右下角的
1,1
。float和int的精度都设置为mediump

阅读图表,我们发现虽然
mod(6,6)
是正确的
0
mod(7,7)
实际上是
7
如何解决此问题?

我尝试实现自己的mod()函数。但是,它具有相同的错误,并生成相同的图形

int func_mod(int x, int y) {
    return int(float(x)-float(y)*floor(float(x)/float(y)));
}
在Javascript中,我可以调试它,该函数工作得非常好。然后我尝试了一种迭代方法,因为我担心自己会发疯,而且我不相信浮点除法

int iter_mod(int x, int y) {
    x = int(abs(float(x))); y = int(abs(float(y)));
    for(int i=0; i>-1; i++) {
        if(x < y) break;
        x = x - y;
    }
    return x;
}
int iter\u mod(int x,int y){
x=int(abs(float(x));y=int(abs(float(y)));
对于(int i=0;i>-1;i++){
如果(x
这是可行的,但我无法绘制它,因为当我尝试时,它在环0中出现错误,导致linux崩溃。对于我需要的spritesheet计算,它工作得很好,但我真的觉得这是一个不正确的解决方案


(更新:它在我的手机上运行得很好。现在不是我的代码出错,只是我的问题…

你不是7乘7而是7/15乘7/15

试一试

您可以在这里看到运行的两个版本

函数渲染(num){
var gl=document.getElementById(“c”+num).getContext(“webgl”);
var programInfo=twgl.createProgramInfo(gl,[“vs”,“fs]”);
变量数组={
位置:[1,-1,0,1,-1,0,-1,1,0,-1,1,0,1,-1,0,1,1,0],
};
var bufferInfo=twgl.createBufferInfoFromArrays(gl,arrays);
变量={
分辨率:[gl.canvas.width,gl.canvas.height],
intMod:num==1,
};
总账使用程序(programInfo.program);
twgl.setBuffersAndAttributes(总帐、程序信息、缓冲信息);
twgl.设置制服(程序信息、制服);
twgl.drawBufferInfo(总账,bufferInfo);
}
渲染(0)
渲染(1)
canvas{边距:1m;高度:100px;宽度:150px;}
div{display:inline块;}
前{文本对齐:居中;}

属性向量4位置;
void main(){
gl_位置=位置;
}
精密中泵浮子;
均匀vec2分辨率;
统一bool-intMod;
void main(){
vec2 v_texCoord=gl_FragCoord.xy/resolution.xy;
如果(!intMod){
gl_FragColor=vec4(mod(
浮动(int(v_texCoord[0]*15.))/15。,
浮动(int(v_texCoord[1]*15.))/15。
), 0, 0, 1);
}否则{
gl_FragColor=vec4(mod(
地板(v_texCoord[0]*15.),
楼层(v_texCoord[1]*15.)
)/15., 0, 0, 1);
}
}
分数模

mod with ints
这里有一个GLSL函数,它使用应为整数的(浮点)参数精确计算mod:


请注意,如果a0,那么返回值将>=0,这与其他语言“%operator”不同。

请注意,由于webGL2,我们现在有int运算,所以这个问题现在可以通过x%y轻松解决。

我认为这是不正确的。如果我尝试执行
x%y
操作,我会得到
'%':仅GLSL ES 3.00及以上版本支持的整数模运算符
。据我所知,只有在脚本开始时指定
#version 130
时,模运算符才有效,但恐怕还没有浏览器支持此版本的GLSL ES。我的错,看起来你可以做
#version 300 ES
,它可以工作。当你看到你写错了什么,逻辑是删除帖子;-)。我留着它以防其他人碰到同样的问题。如果你在网上搜索错误消息,人们会说使用
#version 130
,这在任何浏览器中都不起作用。我希望我的评论能帮助其他人。
gl_FragColor = vec4(mod(
  floor(v_texCoord[0] * 15.),
  floor(v_texCoord[1] * 15.)
) / 15., 0, 0, 1);
/**
 * Returns accurate MOD when arguments are approximate integers.
 */
float modI(float a,float b) {
    float m=a-floor((a+0.5)/b)*b;
    return floor(m+0.5);
}