Fractals with glsl and questions

Hi,

I wrote my first shader:

vertex1.vert


void main()
{
   gl_Position = ftransform();
}


and fragment1.frag:


void main ()
{
   gl_FragColor=vec4(0.0,0.0,1.0,0.0);
}


With that code, I used the shaders:


cam.setLocation(new Vector3f(0, 0, 2));
cam.update();
Quad oQuad=new Quad("myQuad",1f,1f);
GLSLShaderObjectsState so=renderer.createGLSLShaderObjectsState();
o.load(getClass().getClassLoader().getResource(
           "vertex1.vert"),
getClass().getClassLoader().getResource(
                    "fragment1.frag"));
o.setEnabled(true);
oQuad.setRenderState(so);
rootNode.attachChild(oQuad);
rootNode.updateRenderState();


With that, I got a blue quad. I looked at this page http://www.ozone3d.net/tutorials/mandelbrot_set_p4.php and simplified the first shader:
new fragment1.frag:


void main ()
{
   vec2 c = gl_TexCoord[0].xy;
   vec2 z = c;
   gl_FragColor = vec4(0.0,0.0,0.0,0.0);
   for (float i = 0; i < 255; i += 1.0)
   {
      z = vec2(z.x*z.x - z.y*z.y, 2.0*z.x*z.y) + c;
      if (dot(z, z) > 4.0)
      {
         gl_FragColor = vec4(i/255.0,0.0,0.0,1.0);
         break;
      }
   }
}


This shader worked in TyphoonLabs Shader Designer. But, with jme, using the same java code, I got a black screen. Why doesn't it work? What should be added? How can I implement the ping-pong between the buffers described in the link above?
With gl_FragColor, I write a color to the fragment. What do I do with gl_FragData and how is the link to jme?

Best,
Andreas

Hi,

the first problem was solved using this vertex shader:


varying vec4 position;
void main()
{
   position = ftransform();
   gl_Position = position;
}

, this fragment shader


vvarying vec4 position;
void main ()
{
   vec2 c = vec2(position.x*3.0/2.0-0.8,position.y*1.25);
   vec2 z = c;
   gl_FragColor = vec4(1.0,1.0,1.0,1.0);
   for (float i = 0; i <= 255; i += 1.0)
   {
      vec2 tempZ=z*z;
      if (tempZ.x+tempZ.y > 4.0)
      {
         float color=1.0-i/255.0;
         gl_FragColor = vec4(color,color,1.0,1.0);
         break;
      }
      z = vec2(tempZ.x - tempZ.y, 2.0*z.x*z.y) + c;
   }
}


and this java code:


Quad oQuad=new Quad("myQuad",width,height);
oQuad.setLocalTranslation(new Vector3f(width/2,height/2,0));
oQuad.setRenderQueueMode(Renderer.QUEUE_ORTHO);
so=renderer.createGLSLShaderObjectsState();
so.load(getClass().getClassLoader().getResource(
            "vertex1.vert"),
            getClass().getClassLoader().getResource(
                    "fragment1.frag"));
so.setEnabled(true);
oQuad.setRenderState(so);
rootNode.attachChild(oQuad);
rootNode.updateRenderState();



Best,
Andreas

hi,



the problem with the original code is, that the texcoord buffer in this line



vec2 c = gl_TexCoord[0].xy;



is not filled by the vertex shader and all values are 0. If you want to change the position of the fractal on the object you can calculate the texture coordinates in the vertex shader and write it to the texcoord buffer gl_TexCoord[0].



the second code use the original vertex position as input for the fractal calculation.



hope this helps a little bit to understand the difference :slight_smile:

Yes, thank you.



Andreas

I just found out, while loops are faster than for loops in glsl. Do you know why?



varying vec4 position;
const float iter=255.0;
void main ()
{
   vec2 c = vec2(position.x*3.0/2.0-0.7,position.y*1.25);
   vec2 z = c;
   gl_FragColor = vec4(1.0,1.0,1.0,1.0);
   
   vec2 tempZ=z*z;
   float i=0.0;
   while (i<=iter && (tempZ.x+tempZ.y)<=4)
   {
      
      z = vec2(tempZ.x - tempZ.y, 2.0*z.x*z.y) + c;
      tempZ=z*z;
      i+=1.0;   
      
   }
   if (i <= iter)
      {
         float color=mod(i,64)/63;
         gl_FragColor = vec4(color,color,1.0,1.0);
      }
   
}



Andreas


this is driver dependent. the glsl code is compiled by the driver an optimized to.  :? :D

Ok. Let's write in assembler. :smiley:

:wink: