我一直在为 WebGL 中的分形研究一些距离函数,并注意到每当我将迭代计数设置为 3 或更大时,它都会在我的计算机上失败。我的意思是我得到一个灰屏而不是灰度分形(我认为这表明计算没有完成,因为我已经在非 WebGL 设置中测试了它的正确性)
但是,在工作的机器上,它在计数为 3 或更大时工作得很好。我像这样定义迭代次数:
#define MANDELBOX_ITER 20
为了找出问题所在,我转换了基于迭代的代码:
float mandelboxDist(Object inMandelbox, vec3 inPos) {
inPos -= inMandelbox.pos;
vec3 offset = vec3(inPos);
float d = 1.0;
for (int i = 0; i < MANDELBOX_ITER; i++) {
// Boxfold
inPos = clamp(inPos, -MANDELBOX_BFOLD, MANDELBOX_BFOLD)*2.0-inPos;
// Spherefold
float posDot = dot(inPos, inPos);
if (posDot < MANDELBOX_MIN_RAD) {
inPos *= MANDELBOX_LINEAR_SCALE;
d *= MANDELBOX_LINEAR_SCALE;
}
else if (posDot < MANDELBOX_FIXED_RAD) {
float inversion = MANDELBOX_FIXED_RAD/posDot;
inPos *= inversion;
d *= inversion;
}
inPos = MANDELBOX_SCALE*inPos+offset;
d = MANDELBOX_SCALE*d+1.0;
}
return length(inPos)/abs(d);
}
。进入这个:
void iterateMandelbox(inout vec3 pos, vec3 inOffset, inout float d) {
// Boxfold
pos = clamp(pos, -MANDELBOX_BFOLD, MANDELBOX_BFOLD)*2.0-pos;
// Spherefold
float posDot = dot(pos, pos);
if (posDot < MANDELBOX_MIN_RAD) {
pos *= MANDELBOX_LINEAR_SCALE;
d *= MANDELBOX_LINEAR_SCALE;
}
else if (posDot < MANDELBOX_FIXED_RAD) {
float inversion = MANDELBOX_FIXED_RAD/posDot;
pos *= inversion;
d *= inversion;
}
pos = MANDELBOX_SCALE*pos+inOffset;
d = MANDELBOX_SCALE*d+1.0;
}
float mandelboxDist(Object inMandelbox, vec3 inPos) {
inPos -= inMandelbox.pos;
vec3 offset = vec3(inPos);
float d = 1.0;
iterateMandelbox(inPos, offset, d);
iterateMandelbox(inPos, offset, d);
iterateMandelbox(inPos, offset, d);
iterateMandelbox(inPos, offset, d);
iterateMandelbox(inPos, offset, d);
iterateMandelbox(inPos, offset, d);
iterateMandelbox(inPos, offset, d);
iterateMandelbox(inPos, offset, d);
iterateMandelbox(inPos, offset, d);
iterateMandelbox(inPos, offset, d);
iterateMandelbox(inPos, offset, d);
iterateMandelbox(inPos, offset, d);
iterateMandelbox(inPos, offset, d);
iterateMandelbox(inPos, offset, d);
iterateMandelbox(inPos, offset, d);
iterateMandelbox(inPos, offset, d);
iterateMandelbox(inPos, offset, d);
iterateMandelbox(inPos, offset, d);
iterateMandelbox(inPos, offset, d);
iterateMandelbox(inPos, offset, d);
return length(inPos)/abs(d);
}
。并发现它适用于我的电脑。显然这是非常不方便的,我不知道为什么它在"手动"循环时有效。这是怎么回事?
编辑:为了回应LJ_1102的回答,我有一台2011年的Macbook,"关于这台Mac"告诉我我有一张"Intel HD Graphics 3000 384 MB"显卡
假设您使用的是Windows PC,听起来您正在ANGLE中遇到循环展开错误。
要验证这一点,请使用 --use-gl=desktop
启动浏览器。此标志强制您的浏览器不使用 ANGLE DirectX 转换层。当您的问题确实是基于角度的查看使用 getTranslatedShaderSource 编译的 HLSL 代码,并从那里进行调试。
不幸的是,如果它是一个基于角度的问题,您让它运行的唯一机会是摆弄直到正确转换或在角度项目页面上提交错误。