Color table

Hi,

I have here the code for a mandelbrot fractal:

vertex1.vert:


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


fragment1.vert:


varying vec4 position;
uniform sampler1D myColorTable;
const float iter=64.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=i/iter;
         gl_FragColor = texture1D(myColorTable,color);//vec4(color,color,1.0,1.0);
      }
   
}


Please look at gl_FragColor = texture1D(myColorTable,color);//vec4(color,color,1.0,1.0); At first, the color was calculated. But, this is commented out. Now, I would like to look up the color in a color table.
Here is, what I tried with java:


public void simpleSetup() {
         Quad oQuad=new Quad("myQuad",width,height);
         oQuad.setLocalTranslation(new Vector3f(width/2,height/2,0));
         oQuad.setRenderQueueMode(Renderer.QUEUE_ORTHO);
      
         Texture oColorTexture=new Texture();
         TextureState oState=renderer.createTextureState();
         oState.setEnabled(true);
         
         ByteBuffer oBuffer=BufferUtils.createByteBuffer(64*4);
         for(byte i=0;i<64;i++){
            oBuffer.put((byte)(i*4));
            oBuffer.put((byte)(i*4));
            oBuffer.put((byte)255);
            oBuffer.put((byte)255);
         }
         Image oImage=new Image(Image.RGBA8888,64,1,oBuffer);
         oColorTexture.setImage(oImage);
         oState.setTexture(oColorTexture, 0);
         
         oQuad.setRenderState(oState);
         
         
         so=renderer.createGLSLShaderObjectsState();
         so.load(getClass().getClassLoader().getResource(
            "vertex1.vert"),
            getClass().getClassLoader().getResource(
                    "fragment1.frag"));
         so.setEnabled(true);
         
         so.setUniform("myColorTable", 0);
         oQuad.setRenderState(so);
         rootNode.attachChild(oQuad);
         rootNode.updateRenderState();
         
      }



But, it does not work. The shader does not find the color table. Do you know, how to fix it? At the tutorials, I did not find any examples for this.

Best,
Andreas

Does it work if you make the table a sample2d?

Hi,

thx 4 asking.

Yes, it would work:

fragment1.frag:


varying vec4 position;
uniform sampler2D myColorTable;
const float iter=64.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=i/iter;
         gl_FragColor=texture2D(myColorTable,vec2(color,0));
      }
   
}


and java:


public void simpleSetup() {
         Quad oQuad=new Quad("myQuad",width,height);
         oQuad.setLocalTranslation(new Vector3f(width/2,height/2,0));
         oQuad.setRenderQueueMode(Renderer.QUEUE_ORTHO);
         Texture oColorTexture=new Texture();
         TextureState oState=renderer.createTextureState();
         oState.setEnabled(true);
         ByteBuffer oBuffer=BufferUtils.createByteBuffer(64*4);
         for(byte i=0;i<64;i++){
            oBuffer.put((byte)(i*4));
            oBuffer.put((byte)(i*4));
            oBuffer.put((byte)255);
            oBuffer.put((byte)255);
         }
         Image oImage=new Image(Image.RGBA8888,64,1,oBuffer);
         oColorTexture.setImage(oImage);
         oState.setTexture(oColorTexture, 0);
         oQuad.setRenderState(oState);
      so=renderer.createGLSLShaderObjectsState();
      so.load(getClass().getClassLoader().getResource(
            "vertex1.vert"),
            getClass().getClassLoader().getResource(
                   "fragment1.frag"));
      so.setEnabled(true);
      so.setUniform("myColorTable", 0);
      oQuad.setRenderState(so);
      rootNode.attachChild(oQuad);
      rootNode.updateRenderState();
   }


But I think, it is not a very elegant way.

Best,
Andreas

1d textures should be supported in 2.0 (although they have not been tested really.)  Perhaps sampler1d would work better there.

Hi,

the texture1d test was successful. I used the fragment shader of my first post and this jme 2.0 code:



public void simpleSetup() {
         Quad oQuad=new Quad("myQuad",width,height);
         oQuad.setLocalTranslation(new Vector3f(((float)width)/2,((float)height)/2,0));
         oQuad.setRenderQueueMode(Renderer.QUEUE_ORTHO);
         Texture1D oColorTexture=new Texture1D();
         TextureState oState=renderer.createTextureState();
         oState.setEnabled(true);
         ByteBuffer oBuffer=BufferUtils.createByteBuffer(64*4);
         for(byte i=0;i<64;i++){
            oBuffer.put((byte)(i*4));
            oBuffer.put((byte)(i*4));
            oBuffer.put((byte)255);
            oBuffer.put((byte)255);
         }
         Image oImage=new Image(Image.Format.RGBA8,64,1,oBuffer);
         oColorTexture.setImage(oImage);
         oState.setTexture(oColorTexture, 0);
         oQuad.setRenderState(oState);
         so=renderer.createGLSLShaderObjectsState();
         so.load(getClass().getClassLoader().getResource(
            "vertex1.vert"),
            getClass().getClassLoader().getResource(
                    "fragment1.frag"));
         so.setEnabled(true);
         so.setUniform("myColorTable", 0);
         oQuad.setRenderState(so);
         rootNode.attachChild(oQuad);
         rootNode.updateRenderState();
      }



Best,
Andreas

Nice to see ppl trying out the newer jme 2.0 features.  :slight_smile: