Andreas999
Newcomer
Hi,
I wrote a mandelbrot and julia program which you can find here: http://www.lichtundliebe.info/projects/2DFractal/2DFractal.jnlp. Here is the code: http://www.lichtundliebe.info/projects/2DFractal.zip
If you have no deep zoom, the program works at all shader model 3.0 cards. If you have deeper zoom (5-6x click at the fractal), it uses a fixed point arithmetic for higher precision:
At an ATI x1600 card, this glsl fragment shader causes crashing. Using the gpu shaderanalyzer, I read, this shader is not supported by HW for x1x00 cards.
But at my hd2600xt card, the precision shaders are working. I don't understand why. But, I found out, it's something with the main loop. Do you know, how to fix this code?
Best,
Andreas
I wrote a mandelbrot and julia program which you can find here: http://www.lichtundliebe.info/projects/2DFractal/2DFractal.jnlp. Here is the code: http://www.lichtundliebe.info/projects/2DFractal.zip
If you have no deep zoom, the program works at all shader model 3.0 cards. If you have deeper zoom (5-6x click at the fractal), it uses a fixed point arithmetic for higher precision:
Code:
varying vec2 position;
//uniform sampler2D myColorTable;
uniform float maxIter;
uniform vec4 deltaVectorX1;
uniform vec4 deltaVectorX2;
uniform vec4 deltaVectorY1;
uniform vec4 deltaVectorY2;
uniform vec4 lowerLeftCornerX1;
uniform vec4 lowerLeftCornerX2;
uniform vec4 lowerLeftCornerY1;
uniform vec4 lowerLeftCornerY2;
//1/1024.0=0.0009765625
// the float mantissa has only 23 bits => number->number1 should be enough
void convertToBigSize(in float number,out vec4 number1, out vec4 number2){
number1=vec4(0.0);
number2=vec4(0.0);
float signum=sign(number);
number=abs(number);
float temp=floor(number);
number1.r=temp;
number-=temp;
number*=1024.0;
temp=floor(number);
number1.g=temp;
number-=temp;
number*=1024.0;
temp=floor(number);
number1.b=temp;
number-=temp;
number*=1024.0;
temp=floor(number);
number1.a=temp;
number1*=signum;
}
//41 Ops
void add(inout vec4 a1, inout vec4 a2, in vec4 b1, in vec4 b2){
a1+=b1;
a2+=b2;
//the values after the point have to be greater than 0.0
a1.r-=2.0;//-2
a2.a+=2048.0;
a1.gba+=2046.0;
a2.rgb+=2046.0;
float temp=floor(a2.a*0.0009765625);
a2.b+=temp;
a2.a-=temp*1024.0;
temp=floor(a2.b*0.0009765625);
a2.g+=temp;
a2.b-=temp*1024.0;
temp=floor(a2.g*0.0009765625);
a2.r+=temp;
a2.g-=temp*1024.0;
temp=floor(a2.r*0.0009765625);
a1.a+=temp;
a2.r-=temp*1024.0;
temp=floor(a1.a*0.0009765625);
a1.b+=temp;
a1.a-=temp*1024.0;
temp=floor(a1.b*0.0009765625);
a1.g+=temp;
a1.b-=temp*1024.0;
temp=floor(a1.g*0.0009765625);
a1.r+=temp;
a1.g-=temp*1024.0;
}
//44+30+63=137ops
void mult(inout vec4 a1, inout vec4 a2, in vec4 b1, in vec4 b2){
vec4 z11=a1*b1.r;
vec4 z12=a2*b1.r;
vec4 z21=a1*b1.g;
vec4 z22=a2*b1.g;
vec4 z31=a1*b1.b;
vec4 z32=a2*b1.b;
vec4 z41=a1*b1.a;
vec4 z42=a2*b1.a;
vec4 z51=a1*b2.r;
vec4 z52=a2*b2.r;
vec4 z61=a1*b2.g;
vec4 z62=a2*b2.g;
vec4 z71=a1*b2.b;
vec4 z72=a2*b2.b;
vec4 z81=a1*b2.a;
vec4 z82=a2*b2.a;
vec3 tempM2=z82.gba;
tempM2.rg+=z72.ba;
tempM2.r+=z62.a;
vec4 tempM1=z52;
tempM1.a+=z82.r;
tempM1.rgb+=z81.gba;
tempM1.ba+=z72.rg;
tempM1.rg+=z71.ba;
tempM1.gba+=z62.rgb;
tempM1.r+=z61.a;
tempM1.rgb+=z42.gba;
tempM1.rg+=z32.ba;
tempM1.r+=z22.a;
a2=z51;
a2.a+=z81.r;
a2.ba+=z71.rg;
a2.gba+=z61.rgb;
a2.a+=z42.r;
a2.rgb+=z41.gba;
a2.ba+=z32.rg;
a2.rg+=z31.ba;
a2.gba+=z22.rgb;
a2.r+=z21.a;
a2+=z12;
a1=z11;
a1.gba+=z21.rgb;
a1.ba+=z31.rg;
a1.a+=z41.r;
float tempSign=sign(tempM2.g);
float temp=floor(abs(tempM2.g)*0.0009765625);
tempM2.r+=temp*tempSign;
tempSign=sign(tempM2.r);
temp=floor(abs(tempM2.r)*0.0009765625);
tempM1.a+=temp*tempSign;
tempSign=sign(tempM1.a);
temp=floor(abs(tempM1.a)*0.0009765625);
tempM1.b+=temp*tempSign;
tempSign=sign(tempM1.b);
temp=floor(abs(tempM1.b)*0.0009765625);
tempM1.g+=temp*tempSign;
tempSign=sign(tempM1.g);
temp=floor(abs(tempM1.g)*0.0009765625);
tempM1.r+=temp*tempSign;
tempSign=sign(tempM1.r);
temp=floor(abs(tempM1.r)*0.0009765625);
a2.a+=temp*tempSign;
tempSign=sign(a2.a);
temp=floor(abs(a2.a)*0.0009765625);
a2.b+=temp*tempSign;
a2.a-=temp*1024.0*tempSign;
tempSign=sign(a2.b);
temp=floor(abs(a2.b)*0.0009765625);
a2.g+=temp*tempSign;
a2.b-=temp*1024.0*tempSign;
tempSign=sign(a2.g);
temp=floor(abs(a2.g)*0.0009765625);
a2.r+=temp*tempSign;
a2.g-=temp*1024.0*tempSign;
tempSign=sign(a2.r);
temp=floor(abs(a2.r)*0.0009765625);
a1.a+=temp*tempSign;
a2.r-=temp*1024.0*tempSign;
tempSign=sign(a1.a);
temp=floor(abs(a1.a)*0.0009765625);
a1.b+=temp*tempSign;
a1.a-=temp*1024.0*tempSign;
tempSign=sign(a1.b);
temp=floor(abs(a1.b)*0.0009765625);
a1.g+=temp*tempSign;
a1.b-=temp*1024.0*tempSign;
tempSign=sign(a1.g);
temp=floor(abs(a1.g)*0.0009765625);
a1.r+=temp*tempSign;
a1.g-=temp*1024.0*tempSign;
}
/*//only for test purposes
float convertToFloat(in vec4 X1, in vec4 X2){
float number=X1.r;
float divi=1024.0;
number+=X1.g/divi;
divi*=1024.0;
number+=X1.b/divi;
divi*=1024.0;
number+=X1.a/divi;
divi*=1024.0;
number+=X2.r/divi;
divi*=1024.0;
number+=X2.g/divi;
divi*=1024.0;
number+=X2.b/divi;
divi*=1024.0;
number+=X2.a/divi;
return number;
}*/
//a=a+b-4, 41 Ops
void add2(inout vec4 a1, inout vec4 a2, in vec4 b1, in vec4 b2){
a1+=b1;
a2+=b2;
//the values after the point have to be smaller than 0.0
a1.r-=2.0;//-4+2
a2.a-=2048.0;
a1.gba-=2046.0;
a2.rgb-=2046.0;
float temp=ceil(a2.a*0.0009765625);
a2.b+=temp;
a2.a-=temp*1024.0;
temp=ceil(a2.b*0.0009765625);
a2.g+=temp;
a2.b-=temp*1024.0;
temp=ceil(a2.g*0.0009765625);
a2.r+=temp;
a2.g-=temp*1024.0;
temp=ceil(a2.r*0.0009765625);
a1.a+=temp;
a2.r-=temp*1024.0;
temp=ceil(a1.a*0.0009765625);
a1.b+=temp;
a1.a-=temp*1024.0;
temp=ceil(a1.b*0.0009765625);
a1.g+=temp;
a1.b-=temp*1024.0;
temp=ceil(a1.g*0.0009765625);
a1.r+=temp;
a1.g-=temp*1024.0;
//a1.r=floor(a1.r);
//a1.g=floor(a1.g);
}
void main ()
{
//position=lowerLeftCorner+(gl_Position.xy+vec2(1.0,1.0))*deltaVector;
vec4 tempPositionX1=vec4(0.0);
vec4 tempPositionX2=vec4(0.0);
vec4 tempPositionY1=vec4(0.0);
vec4 tempPositionY2=vec4(0.0);
vec2 tmpPosition=position+1.0;
convertToBigSize(tmpPosition.r,tempPositionX1, tempPositionX2);
convertToBigSize(tmpPosition.g,tempPositionY1, tempPositionY2);
mult(tempPositionX1,tempPositionX2, deltaVectorX1, deltaVectorX2);
mult(tempPositionY1,tempPositionY2, deltaVectorY1, deltaVectorY2);
vec4 positionX1=lowerLeftCornerX1;
vec4 positionX2=lowerLeftCornerX2;
vec4 positionY1=lowerLeftCornerY1;
vec4 positionY2=lowerLeftCornerY2;
add(positionX1, positionX2, tempPositionX1, tempPositionX2);
add(positionY1, positionY2, tempPositionY1, tempPositionY2);
//z=position
vec4 zX1=positionX1;
vec4 zX2=positionX2;
vec4 zY1=positionY1;
vec4 zY2=positionY2;
gl_FragColor = vec4(1.0,1.0,1.0,1.0);
//vec2 tempZ=z*z;
vec4 tempZX1=zX1;
vec4 tempZX2=zX2;
vec4 tempZY1=zY1;
vec4 tempZY2=zY2;
mult(tempZX1, tempZX2, zX1, zX2);
mult(tempZY1, tempZY2, zY1, zY2);
vec4 temp1=tempZX1;
vec4 temp2=tempZX2;
//tempZ.x+tempZ.y
add2(temp1,temp2,tempZY1, tempZY2);
float i=float(0.0);
float temp=0.0;
float tempSign=0.0;
vec3 tempM2=vec3(0.0);
vec4 tempM1=vec4(0.0);
vec4 z11=vec4(0.0);
vec4 z12=vec4(0.0);
vec4 z21=vec4(0.0);
vec4 z22=vec4(0.0);
vec4 z31=vec4(0.0);
vec4 z32=vec4(0.0);
vec4 z41=vec4(0.0);
vec4 z42=vec4(0.0);
vec4 z51=vec4(0.0);
vec4 z52=vec4(0.0);
vec4 z61=vec4(0.0);
vec4 z62=vec4(0.0);
vec4 z71=vec4(0.0);
vec4 z72=vec4(0.0);
vec4 z81=vec4(0.0);
vec4 z82=vec4(0.0);
//(tempZ.x+tempZ.y)<=4 equivalent to tempZ.x+tempZ.y-4<=0.0
while (i<=maxIter && all(lessThanEqual(temp1,vec4(0.0))) && all(lessThanEqual(temp2,vec4(0.0))))
{
//z = vec2(tempZ.x - tempZ.y, 2.0*z.x*z.y) + position;
//add(tempZX1, tempZX2, -tempZY1, -tempZY2);
tempZX1-=tempZY1;
tempZX2-=tempZY2;
//the values after the point have to be greater than 0.0
tempZX1.r-=2.0;//-2
tempZX2.a+=2048.0;
tempZX1.gba+=2046.0;
tempZX2.rgb+=2046.0;
temp=floor(tempZX2.a*0.0009765625);
tempZX2.b+=temp;
tempZX2.a-=temp*1024.0;
temp=floor(tempZX2.b*0.0009765625);
tempZX2.g+=temp;
tempZX2.b-=temp*1024.0;
temp=floor(tempZX2.g*0.0009765625);
tempZX2.r+=temp;
tempZX2.g-=temp*1024.0;
temp=floor(tempZX2.r*0.0009765625);
tempZX1.a+=temp;
tempZX2.r-=temp*1024.0;
temp=floor(tempZX1.a*0.0009765625);
tempZX1.b+=temp;
tempZX1.a-=temp*1024.0;
temp=floor(tempZX1.b*0.0009765625);
tempZX1.g+=temp;
tempZX1.b-=temp*1024.0;
temp=floor(tempZX1.g*0.0009765625);
tempZX1.r+=temp;
tempZX1.g-=temp*1024.0;
//mult(zY1, zY2, zX1, zX2);
z11=zY1*zX1.r;
z12=zY2*zX1.r;
z21=zY1*zX1.g;
z22=zY2*zX1.g;
z31=zY1*zX1.b;
z32=zY2*zX1.b;
z41=zY1*zX1.a;
z42=zY2*zX1.a;
z51=zY1*zX2.r;
z52=zY2*zX2.r;
z61=zY1*zX2.g;
z62=zY2*zX2.g;
z71=zY1*zX2.b;
z72=zY2*zX2.b;
z81=zY1*zX2.a;
z82=zY2*zX2.a;
tempM2=z82.gba;
tempM2.rg+=z72.ba;
tempM2.r+=z62.a;
tempM1=z52;
tempM1.a+=z82.r;
tempM1.rgb+=z81.gba;
tempM1.ba+=z72.rg;
tempM1.rg+=z71.ba;
tempM1.gba+=z62.rgb;
tempM1.r+=z61.a;
tempM1.rgb+=z42.gba;
tempM1.rg+=z32.ba;
tempM1.r+=z22.a;
zY2=z51;
zY2.a+=z81.r;
zY2.ba+=z71.rg;
zY2.gba+=z61.rgb;
zY2.a+=z42.r;
zY2.rgb+=z41.gba;
zY2.ba+=z32.rg;
zY2.rg+=z31.ba;
zY2.gba+=z22.rgb;
zY2.r+=z21.a;
zY2+=z12;
zY1=z11;
zY1.gba+=z21.rgb;
zY1.ba+=z31.rg;
zY1.a+=z41.r;
tempSign=sign(tempM2.g);
temp=floor(abs(tempM2.g)*0.0009765625);
tempM2.r+=temp*tempSign;
tempSign=sign(tempM2.r);
temp=floor(abs(tempM2.r)*0.0009765625);
tempM1.a+=temp*tempSign;
tempSign=sign(tempM1.a);
temp=floor(abs(tempM1.a)*0.0009765625);
tempM1.b+=temp*tempSign;
tempSign=sign(tempM1.b);
temp=floor(abs(tempM1.b)*0.0009765625);
tempM1.g+=temp*tempSign;
tempSign=sign(tempM1.g);
temp=floor(abs(tempM1.g)*0.0009765625);
tempM1.r+=temp*tempSign;
tempSign=sign(tempM1.r);
temp=floor(abs(tempM1.r)*0.0009765625);
zY2.a+=temp*tempSign;
tempSign=sign(zY2.a);
temp=floor(abs(zY2.a)*0.0009765625);
zY2.b+=temp*tempSign;
zY2.a-=temp*1024.0*tempSign;
tempSign=sign(zY2.b);
temp=floor(abs(zY2.b)*0.0009765625);
zY2.g+=temp*tempSign;
zY2.b-=temp*1024.0*tempSign;
tempSign=sign(zY2.g);
temp=floor(abs(zY2.g)*0.0009765625);
zY2.r+=temp*tempSign;
zY2.g-=temp*1024.0*tempSign;
tempSign=sign(zY2.r);
temp=floor(abs(zY2.r)*0.0009765625);
zY1.a+=temp*tempSign;
zY2.r-=temp*1024.0*tempSign;
tempSign=sign(zY1.a);
temp=floor(abs(zY1.a)*0.0009765625);
zY1.b+=temp*tempSign;
zY1.a-=temp*1024.0*tempSign;
tempSign=sign(zY1.b);
temp=floor(abs(zY1.b)*0.0009765625);
zY1.g+=temp*tempSign;
zY1.b-=temp*1024.0*tempSign;
tempSign=sign(zY1.g);
temp=floor(abs(zY1.g)*0.0009765625);
zY1.r+=temp*tempSign;
zY1.g-=temp*1024.0*tempSign;
//add(zY1, zY2, zY1, zY2);
zY1+=zY1;
zY2+=zY2;
//the values after the point have to be greater than 0.0
zY1.r-=2.0;//-2
zY2.a+=2048.0;
zY1.gba+=2046.0;
zY2.rgb+=2046.0;
temp=floor(zY2.a*0.0009765625);
zY2.b+=temp;
zY2.a-=temp*1024.0;
temp=floor(zY2.b*0.0009765625);
zY2.g+=temp;
zY2.b-=temp*1024.0;
temp=floor(zY2.g*0.0009765625);
zY2.r+=temp;
zY2.g-=temp*1024.0;
temp=floor(zY2.r*0.0009765625);
zY1.a+=temp;
zY2.r-=temp*1024.0;
temp=floor(zY1.a*0.0009765625);
zY1.b+=temp;
zY1.a-=temp*1024.0;
temp=floor(zY1.b*0.0009765625);
zY1.g+=temp;
zY1.b-=temp*1024.0;
temp=floor(zY1.g*0.0009765625);
zY1.r+=temp;
zY1.g-=temp*1024.0;
zX1=tempZX1;
zX2=tempZX2;
//add(zX1, zX2, positionX1, positionX2);
zX1+=positionX1;
zX2+=positionX2;
//the values after the point have to be greater than 0.0
zX1.r-=2.0;//-2
zX2.a+=2048.0;
zX1.gba+=2046.0;
zX2.rgb+=2046.0;
temp=floor(zX2.a*0.0009765625);
zX2.b+=temp;
zX2.a-=temp*1024.0;
temp=floor(zX2.b*0.0009765625);
zX2.g+=temp;
zX2.b-=temp*1024.0;
temp=floor(zX2.g*0.0009765625);
zX2.r+=temp;
zX2.g-=temp*1024.0;
temp=floor(zX2.r*0.0009765625);
zX1.a+=temp;
zX2.r-=temp*1024.0;
temp=floor(zX1.a*0.0009765625);
zX1.b+=temp;
zX1.a-=temp*1024.0;
temp=floor(zX1.b*0.0009765625);
zX1.g+=temp;
zX1.b-=temp*1024.0;
temp=floor(zX1.g*0.0009765625);
zX1.r+=temp;
zX1.g-=temp*1024.0;
//add(zY1, zY2, positionY1, positionY2);
zY1+=positionY1;
zY2+=positionY2;
//the values after the point have to be greater than 0.0
zY1.r-=2.0;//-2
zY2.a+=2048.0;
zY1.gba+=2046.0;
zY2.rgb+=2046.0;
temp=floor(zY2.a*0.0009765625);
zY2.b+=temp;
zY2.a-=temp*1024.0;
temp=floor(zY2.b*0.0009765625);
zY2.g+=temp;
zY2.b-=temp*1024.0;
temp=floor(zY2.g*0.0009765625);
zY2.r+=temp;
zY2.g-=temp*1024.0;
temp=floor(zY2.r*0.0009765625);
zY1.a+=temp;
zY2.r-=temp*1024.0;
temp=floor(zY1.a*0.0009765625);
zY1.b+=temp;
zY1.a-=temp*1024.0;
temp=floor(zY1.b*0.0009765625);
zY1.g+=temp;
zY1.b-=temp*1024.0;
temp=floor(zY1.g*0.0009765625);
zY1.r+=temp;
zY1.g-=temp*1024.0;
//tempZ=z*z;
tempZX1=zX1;
tempZX2=zX2;
tempZY1=zY1;
tempZY2=zY2;
// mult(tempZX1, tempZX2, zX1, zX2);
//mult(tempZY1, tempZY2, zY1, zY2);
//tempZ.x+tempZ.y
temp1=tempZX1;
temp2=tempZX2;
//add2(temp1,temp2, tempZY1, tempZY2);
temp1+=tempZY1;
temp2+=tempZY2;
//the values after the point have to be smaller than 0.0
temp1.r-=2.0;//-4+2
temp2.a-=2048.0;
temp1.gba-=2046.0;
temp2.rgb-=2046.0;
temp=ceil(temp2.a*0.0009765625);
temp2.b+=temp;
temp2.a-=temp*1024.0;
temp=ceil(temp2.b*0.0009765625);
temp2.g+=temp;
temp2.b-=temp*1024.0;
temp=ceil(temp2.g*0.0009765625);
temp2.r+=temp;
temp2.g-=temp*1024.0;
temp=ceil(temp2.r*0.0009765625);
temp1.a+=temp;
temp2.r-=temp*1024.0;
temp=ceil(temp1.a*0.0009765625);
temp1.b+=temp;
temp1.a-=temp*1024.0;
temp=ceil(temp1.b*0.0009765625);
temp1.g+=temp;
temp1.b-=temp*1024.0;
temp=ceil(temp1.g*0.0009765625);
temp1.r+=temp;
temp1.g-=temp*1024.0;
i+=1.0;
}
if (i <= maxIter)
{
float color=i/maxIter;
gl_FragColor=vec4(color,color,1.0,1.0);
}
}
At an ATI x1600 card, this glsl fragment shader causes crashing. Using the gpu shaderanalyzer, I read, this shader is not supported by HW for x1x00 cards.
But at my hd2600xt card, the precision shaders are working. I don't understand why. But, I found out, it's something with the main loop. Do you know, how to fix this code?
Best,
Andreas