Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 4 of 4

Thread: large fixed point values in glsl

  1. #1
    Intern Newbie
    Join Date
    Aug 2012
    Posts
    48

    large fixed point values in glsl

    I wrote a simple program to draw a mandelbrot set in the fragment shader, it's currently using a uniform float as it's scale factor which allows a certain degree of zoom ability but then the image quality deteriorates really badly and I can't get to some of the more interesting places in the set.

    I was wondering is it possible to use large fixed point values and send them into the fragment shader?

    I would need a really large factional part and only 1 or 2 bits for decimal since it'll be around 1 to -1.[0000000000...]

    I might be approaching the problem wrong I am unsure that's why I am asking here. How can I send such large numbers to the fragment shader? I noticed that I am able to do logical shifts in the fragment shader so 1<<30 or 1>>30 both work.

    I am just unsure how to put it together. Here's the fragment shader btw.

    Code :
    #version 330 core
     
    in vec4 fcolor;
    in vec2 fTexCoord;
    in vec2 fCoord;
     
    uniform int maxIterations;
    uniform sampler1D mandiTexture;
    uniform vec2 center;
    uniform float scale;
     
    out vec4 color;
     
    void main()
    {
       float ONE_OVER_LOG_TWO = 1.0f/0.69314718055f;
       vec2 c, z;
       vec4 colora, colorb;
     
        c.x = (fCoord.x * scale) + center.x;
        c.y = (fCoord.y * scale) + center.y;
     
        	int i;
        	z = vec2(0.0f, 0.0f);
            float size, smoothed, colorI;
     
        	for(i=0; i< maxIterations; i++) {
        		float x = (z.x * z.x - z.y * z.y) + c.x;
        		float y = (z.y * z.x + z.x * z.y) + c.y;
     
        		if((x * x + y * y) > (1 << 30))
        		{
        		    break;
        		}
        		z.x = x;
        		z.y = y;
        	}
     
        vec4 tcolor;
     
        if (i == maxIterations)
        {
           tcolor = vec4(0.0f, 0.0f, 0.0f, 1.0f);
        }
           else
        {
           float tr, tg, tb;
           float t = float(i)/float(maxIterations);
           tr = (9*(1-t)*t*t*t);
           tg = (15*(1-t)*(1-t)*t*t);
           tb = (8.5*(1-t)*(1-t)*(1-t)*t);
           tcolor = vec4(tr, tg, tb, 1.0f);
        }
     
        color =  tcolor;
    }

  2. #2
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,404
    Quote Originally Posted by blubee View Post
    I might be approaching the problem wrong I am unsure that's why I am asking here. How can I send such large numbers to the fragment shader? I noticed that I am able to do logical shifts in the fragment shader so 1<<30 or 1>>30 both work.
    If you can rely upon support for OpenGL 4.0 or later, you can just use double precision (i.e. GLSL variables of type "double" and glUniform2d() etc).

    Otherwise, you're limited to 32-bit signed or unsigned integers (and vectors thereof), both for the uniforms and for local variables within the shader. Bear in mind that any multiplies will also be limited to a 32-bit result, so for fixed-point arithmetic you'd need to perform up to four 16x16->32 multiplies for each fixed-point multiply.

  3. #3
    Intern Newbie
    Join Date
    Aug 2012
    Posts
    48
    thanks for the reply, with this project I cannot use double precision as it's on mobile mainly.

    On the irc channel someone recommended checking out perturbation, that seems like quite a lot of math. Is that something feasible to get better resolution on android?

    currently I get about this much detail with 32 bit float values in the fragment shader.
    Click image for larger version. 

Name:	Screen Shot 2015-08-12 at 12.35.58 AM.jpg 
Views:	212 
Size:	20.0 KB 
ID:	2042Click image for larger version. 

Name:	Screen Shot 2015-08-12 at 2.38.53 AM.jpg 
Views:	189 
Size:	19.7 KB 
ID:	2043

  4. #4
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,404
    Quote Originally Posted by blubee View Post
    thanks for the reply, with this project I cannot use double precision as it's on mobile mainly.
    Even highp floats aren't guaranteed to have more than a 16-bit mantissa. And the fragment shader isn't required to support highp, only mediump. mediump floats may only have a 10-bit mantissa, and integers may only have 11 bits (including the sign). highp integers (where supported) need only have 17 bits (including the sign).

    You can use glGetShaderPrecisionFormat to determine the number of bits of precision for each type and precision for each shader type.

    If you want reasonable precision even on devices which only meet the minimum requirements of the specification, you'll need to use two or three integers to store each component and implement your own add/subtract/multiply operations.

    Quote Originally Posted by blubee View Post
    currently I get about this much detail with 32 bit float values in the fragment shader.
    That looks more like a consequence of the iteration limit than precision.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •