具有两个浮动的Webgl双精度仿真无效

时间:2017-03-20 17:18:39

标签: javascript opengl double webgl mandelbrot

Mandelbrot set WebGlOpenGl代播放时,我不可避免地偶然发现float的32位double的精确度很低。然而,当我找到this great article时,新的希望就诞生了 小心翼翼地,我从上述来源中获取了函数,并在JS方面添加了doubles解构。

据我所知,JS对于浮点数有64位function doubleToFloat(d) { return new Float32Array([d])[0]; }; function splitDouble(dbl) { //splits JS number to array of 2 32bit floats var arr = []; arr[0] = doubleToFloat(dbl); arr[1] = doubleToFloat(dbl - arr[0]); //console.log(dbl, arr); arr = new Float32Array(arr); dlog(dbl,arr); return arr; }; ///Somewhere inside rendering function - binding data to webGl var planeH = 4/settings.magnification; var planeMult = planeH/canvasH; //screen to complex plane dimensions multiplier var planeW = canvasW*planeMult; var planeWOffset = planeW/2; //offset to align plane's 0:0 at screen's center var planeHOffset = planeH/2; bindUniforms(program, { WIDTH: canvasW, HEIGHT: canvasH, CENTER_X: {value:splitDouble(settings.centerX),type:"2fv"}, CENTER_Y: {value:splitDouble(settings.centerY),type:"2fv"}, MAGNIFICATION: settings.magnification, PLANE_W_OFFSET: {value:splitDouble(planeWOffset),type:"2fv"}, PLANE_H_OFFSET: {value:splitDouble(planeHOffset),type:"2fv"}, PLANE_MULT: {value:splitDouble(planeMult),type:"2fv"}, uSampler: {value:texIndex,type:"1i"} }); --> sent to webGL ,所以我的想法是计算JS方面的一些准备数据,将它作为浮动对发送到GPU并继续进行mandelbrot循环。

可悲的是,最后我看到结果图像的差异几乎没有,我真的不知道我的失败点在哪里。

JS:

#ifdef GL_FRAGMENT_PRECISION_HIGH
   precision highp float;
#else
   precision mediump float;
#endif
   precision mediump int;

const int ITER_LIMIT = <%=iterLimit%>;
uniform float MAGNIFICATION;
uniform vec2 CENTER_X;
uniform vec2 CENTER_Y;
uniform float WIDTH;
uniform float HEIGHT;
uniform vec2 PLANE_W_OFFSET;
uniform vec2 PLANE_H_OFFSET;
uniform vec2 PLANE_MULT;
uniform sampler2D uSampler;
const float threshold = 10.0;

///Double emulation functions///////////////
vec2 ds(float a) {
    vec2 z;
    z.x = a;
    z.y = 0.0;
    return z;
}

vec2 ds_add(vec2 dsa, vec2 dsb) {
    vec2 dsc;
    float t1, t2, e;

    t1 = dsa.x + dsb.x;
    e = t1 - dsa.x;
    t2 = ((dsb.x - e) + (dsa.x - (t1 - e))) + dsa.y + dsb.y;

    dsc.x = t1 + t2;
    dsc.y = t2 - (dsc.x - t1);
    return dsc;
}



vec2 ds_mult(vec2 dsa, vec2 dsb) {
    vec2 dsc;
    float c11, c21, c2, e, t1, t2;
    float a1, a2, b1, b2, cona, conb, split = 8193.;

    cona = dsa.x * split;
    conb = dsb.x * split;
    a1 = cona - (cona - dsa.x);
    b1 = conb - (conb - dsb.x);
    a2 = dsa.x - a1;
    b2 = dsb.x - b1;

    c11 = dsa.x * dsb.x;
    c21 = a2 * b2 + (a2 * b1 + (a1 * b2 + (a1 * b1 - c11)));

    c2 = dsa.x * dsb.y + dsa.y * dsb.x;

    t1 = c11 + c2;
    e = t1 - c11;
    t2 = dsa.y * dsb.y + ((c2 - e) + (c11 - (t1 - e))) + c21;

    dsc.x = t1 + t2;
    dsc.y = t2 - (dsc.x - t1);

    return dsc;
}

vec2 ds_sub(vec2 dsa, vec2 dsb) {
    return ds_add(dsa, ds_mult(ds(-1.0),dsb));
}
///End of Double emulation functions/////////

///Inside main()////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////

float sqThreshold = threshold*threshold;

vec2 X = ds_mult(ds(gl_FragCoord.x),PLANE_MULT);
vec2 Y = ds_mult(ds(gl_FragCoord.y),PLANE_MULT); 

vec2 planeX = ds_add(ds_sub(X,PLANE_W_OFFSET),CENTER_X);
vec2 planeY = ds_sub(ds_sub(Y,PLANE_H_OFFSET),CENTER_Y);

vec4 outcome = vec4(ds(0.0),ds(0.0));   
vec4 C = vec4(planeX,planeY);
int iters = 0;

for (int i = 0; i < ITER_LIMIT; i++) {
    iters = i;
    vec2 sqRe = ds_mult(outcome.xy,outcome.xy);
    vec2 sqIm = ds_mult(outcome.zw,outcome.zw);     
    vec4 Zsq = vec4(
        ds_sub(sqRe,sqIm),  
        ds_mult(ds(2.0),ds_mult(outcome.xy,outcome.zw))
    );                         
    outcome.xy = ds_add(Zsq.xy,C.xy);
    outcome.zw = ds_add(Zsq.zw,C.zw);       

    vec2 sqSumm = ds_add(ds_mult(outcome.xy,outcome.xy),ds_mult(outcome.zw,outcome.zw));
    if (sqSumm.x > sqThreshold) break;      

};  

--> Proceed to coloring

WebGL(片段着色器):

 DateDif( interval, date1, date2, [firstdayofweek], [firstweekofyear] )

 borrowed from https://www.techonthenet.com/excel/formulas/datediff.php

结果(右侧的位置/ maginfication数据):enter image description here 没有双重仿真的相同图像的零差异。

感谢您阅读此文本和代码,任何提示和/或想法?

0 个答案:

没有答案