# Can't pass a 3D integer array into a GLSL shader

**URL:** https://discourse.processing.org/t/cant-pass-a-3d-integer-array-into-a-glsl-shader/39392
**Category:** Coding Questions
**Created:** [October 22, 2022, 10:26pm UTC](https://discourse.processing.org/t/cant-pass-a-3d-integer-array-into-a-glsl-shader/39392 "2022-10-22T22:26:51Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![Java.SourceForger](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/java.sourceforger/32/9831_2.png) [@Java.SourceForger](https://discourse.processing.org/u/Java.SourceForger)
#### Post date: [October 22, 2022, 10:26pm UTC](https://discourse.processing.org/t/cant-pass-a-3d-integer-array-into-a-glsl-shader/39392/1 "2022-10-22T22:26:51Z")

</div>

I have been working on a shader project using the [Processing Java Library.](https://processing.org/) I need to be able to use **PShader.set()** to pass a 3D array of integers into my GLSL shader.

I tried all of the present set() methods that they have, and none work. It seems processing only supports sending 1D arrays. I cannot find any way of sending a 3D array as a uniform into my GLSL shader.

My only other idea is maybe I can acess the lower level JOGL class and update my uniform variable there.

Also, is there a way that i can update just a few of the items in the array instead of having to pass the entire array to the shader over and over again? The data that i am passing as a uniform is thousands of elements in size. Having to keep and resend the entire thing takes up a lot of RAM and CPU.

Any help?

---

<div class="post-metadata">

### Author: ![scudly](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/scudly/32/5597_2.png) [@scudly](https://discourse.processing.org/u/scudly)
#### Post date: [October 24, 2022, 4:00pm UTC](https://discourse.processing.org/t/cant-pass-a-3d-integer-array-into-a-glsl-shader/39392/2 "2022-10-24T16:00:34Z")

</div>

If you want to stick with Processing’s calls, you could put your data in an image, pass it to the shader as a texture, do the 3D coordinate index math yourself, and read out the values with texelFetch().

---

<div class="post-metadata">

### Author: ![Java.SourceForger](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/java.sourceforger/32/9831_2.png) [@Java.SourceForger](https://discourse.processing.org/u/Java.SourceForger)
#### Post date: [October 25, 2022, 3:52am UTC](https://discourse.processing.org/t/cant-pass-a-3d-integer-array-into-a-glsl-shader/39392/3 "2022-10-25T03:52:10Z")

</div>

I am fine sending data via jogl, i just need to know how to do it.

Also, is it possible to update a piece of a variable? I only need to change little parts of my uniform, and the fact that it is thousands of values makes it computationally intensive when i just want to update a few of those values

---

<div class="post-metadata">

### Author: ![scudly](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/scudly/32/5597_2.png) [@scudly](https://discourse.processing.org/u/scudly)
#### Post date: [October 25, 2022, 7:42pm UTC](https://discourse.processing.org/t/cant-pass-a-3d-integer-array-into-a-glsl-shader/39392/4 "2022-10-25T19:42:03Z")

</div>

If you’re willing to use direct OpenGL calls, then there are (too) many different buffering mechanisms you can try and at least some of them support sub-buffer updating. I haven’t used any of them other than textures and vertex buffers, though.

If you search, you can find threads like [https://www.reddit.com/r/opengl/comments/j8fsp0/are\_there\_any\_faster\_alternatives\_to/](https://www.reddit.com/r/opengl/comments/j8fsp0/are_there_any_faster_alternatives_to/) where people offer suggestions and links to talks or papers about different buffering mechanisms.

My main point is to not worry about the 3D format of your data. Just use a 1D buffer of data and do the 3D mapping math in your shader.

---

<div class="post-metadata">

### Author: ![Java.SourceForger](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/java.sourceforger/32/9831_2.png) [@Java.SourceForger](https://discourse.processing.org/u/Java.SourceForger)
#### Post date: [October 26, 2022, 3:15am UTC](https://discourse.processing.org/t/cant-pass-a-3d-integer-array-into-a-glsl-shader/39392/5 "2022-10-26T03:15:44Z")

</div>

Ok. That method sounds best. However, I am very new to the world of OpenGL. Could you please provide an applicable code example?

---

<div class="post-metadata">

### Author: ![scudly](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/scudly/32/5597_2.png) [@scudly](https://discourse.processing.org/u/scudly)
#### Post date: [October 26, 2022, 6:05am UTC](https://discourse.processing.org/t/cant-pass-a-3d-integer-array-into-a-glsl-shader/39392/6 "2022-10-26T06:05:50Z")

</div>

You haven’t said what you’re doing with your 3D volume of data, so I just contrived this example for my own amusement and edification.

This code creates a 144x144x144 volume of integer data with `noise()` scaled up to 1,000,000 and stores it in a texture. The fragment shader shows xy-plane slices of the volume looping from bottom to top. The `fetchData()` function converts the 3D ijk coordinates into 2D texture coordinates, fetches the data as ARGB, and converts it into an integer.

```auto
PShader shdr;
PImage dataImg;

void setup() {
  size( 900, 900, P2D );
  frameRate( 30 );
  shdr = new PShader( g.parent, vertSrc, fragSrc );
  
  int nDatai = 144, nDataj = 144, nDatak = 144;
  shdr.set( "nData", nDatai, nDataj, nDatak );

  dataImg = createImage( 2048, 2048, ARGB );
  dataImg.loadPixels();
  float ns = 0.05;
  for( int k=0; k<nDatak; k++ )
    for( int j=0; j<nDataj; j++ )
      for( int i=0; i<nDatai; i++ ) {
        int idx = (k*nDataj+j)*nDatai+i;
        dataImg.pixels[idx] = int((noise( i*ns, j*ns, k*ns )) * 1000000);
      }
  dataImg.updatePixels();
  shdr.set( "dataImg", dataImg );
}

void draw() {
  shdr.set( "time", (frameCount/144.) % 1. );
  shader( shdr );
  rect( 0, 0, width, height );
  resetShader();
}

String[] vertSrc = { """
#version 330
precision highp float;
precision highp int;

uniform mat4 transformMatrix;
attribute vec4 position;
void main() {
  gl_Position = transformMatrix * position;
}
""" };

String[] fragSrc = { """
#version 330
precision highp float;
uniform vec2 resolution;
uniform float time;
uniform sampler2D dataImg;
uniform ivec3 nData;

out vec4 fragColor;

int fetchData( ivec3 ijk ) {
  ivec2 imgSize = textureSize( dataImg, 0 );
  int idx = (ijk.z*nData.y+ijk.y)*nData.x+ijk.x;
  int j = idx / imgSize.x;
  int i = idx - j * imgSize.x;
  ivec4 v = ivec4(texelFetch( dataImg, ivec2( i, j ), 0 ) * 255.0);
  return ((v.a*256+v.r)*256+v.g)*256+v.b;
}

vec3 draw( vec2 p ) {
  vec3 col = vec3( 0. );
  ivec3 ijk = ivec3( vec3((p+vec2(1.))*0.5, time) * nData );
  int d = fetchData( ijk );
  if( d > 400000 )
    col = vec3( float(d)/1000000. );
  return col;
}

void main() {
  float ss = 2.;
  vec3 tot = vec3(0.);
  for( int ssi=0; ssi<ss; ssi++ )
    for( int ssj=0; ssj<ss; ssj++ ) {
      vec2 of = vec2( ssi, ssj ) / ss - 0.5;
      vec2 uv = (2.*(gl_FragCoord.xy+of)-resolution)*vec2(1,-1)/resolution.y;
      tot += draw( uv );
    }
  tot /= (ss*ss);

  fragColor = vec4( clamp( tot, 0., 1. ), 1.0 );
}
"""};

```

---

<div class="post-metadata">

### Author: ![Java.SourceForger](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/java.sourceforger/32/9831_2.png) [@Java.SourceForger](https://discourse.processing.org/u/Java.SourceForger)
#### Post date: [October 26, 2022, 10:10pm UTC](https://discourse.processing.org/t/cant-pass-a-3d-integer-array-into-a-glsl-shader/39392/7 "2022-10-26T22:10:24Z")

</div>

> You haven’t said what you’re doing with your 3D volume of data

I am making a Minecraft style Voxel game. Each element of the 3D array represents a light value (0-15) for that voxel (-1 if the voxel is opaque), since the shader is applied to individual chunks, I need to send the all the light values of the loaded chunks to the shader as if they were connected.

The reason why I wanted to know how to use direct OpenGL Calls and “sub-buffer updating” is so that I dont have to send the entire lightmap array to the shader every time I set a block. 😂

In order to do this, I’m guessing I would need to access processing’s JOGL object (wherever that is) and then update the shader’s uniforms there. Would you be so kind as to show me a code example of how I could do this?

---

<div class="post-metadata">

### Author: ![scudly](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/scudly/32/5597_2.png) [@scudly](https://discourse.processing.org/u/scudly)
#### Post date: [October 26, 2022, 11:22pm UTC](https://discourse.processing.org/t/cant-pass-a-3d-integer-array-into-a-glsl-shader/39392/8 "2022-10-26T23:22:10Z")

</div>

PGL is Processing’s wrapper around JOGL, which, in turn, is a Java wrapper around OpenGL. If you are doing GL calls up to around version 3.3, you can probably use PGL. Otherwise, you’ll want to use gl directly. Nearly all of the tutorials out there are written for C/C++ or for webgl. JOGL mostly works the same except when it comes to passing data as you have to convert Java’s data types into native formats.

I haven’t done anything with creating my own textures which is probably what you would prefer to do, so I don’t have any wisdom to offer there.

In the Processing IDE, bring up the File: examples menu - Demos - Graphics - LowLevelGLVboInterleaved and start from their code. The meat of it is here:

```auto
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;

import com.jogamp.opengl.*;

PJOGL pgl;
GL4 gl;

void draw() {
  pgl = (PJOGL) beginPGL();
  gl = pgl.gl.getGL4();

  // Get GL ids for all the buffers
  IntBuffer intBuffer = IntBuffer.allocate(1);  
  gl.glGenBuffers(1, intBuffer);
  posVboId = intBuffer.get(0);

  endPGL();
}

FloatBuffer allocateDirectFloatBuffer(int n) {
  return ByteBuffer.allocateDirect(n * Float.BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
}

IntBuffer allocateDirectIntBuffer(int n) {
  return ByteBuffer.allocateDirect(n * Integer.BYTES).order(ByteOrder.nativeOrder()).asIntBuffer();
}

```

Or look at fuller examples like [https://github.com/ElementMo/ComputeShader](https://github.com/ElementMo/ComputeShader).

You might also need to add

```auto
  hint( DISABLE_OPTIMIZED_STROKE );

```

to `setup()` to keep Processing from batch rendering its buffers after (and on top of) your OpenGL calls.

---

<div class="post-metadata">

### Author: ![Java.SourceForger](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/java.sourceforger/32/9831_2.png) [@Java.SourceForger](https://discourse.processing.org/u/Java.SourceForger)
#### Post date: [October 26, 2022, 11:24pm UTC](https://discourse.processing.org/t/cant-pass-a-3d-integer-array-into-a-glsl-shader/39392/9 "2022-10-26T23:24:43Z")

</div>

Ok. Thanks! Will PGL work for me if I am using processing 4.0?

---

<div class="post-metadata">

### Author: ![scudly](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/scudly/32/5597_2.png) [@scudly](https://discourse.processing.org/u/scudly)
#### Post date: [October 26, 2022, 11:27pm UTC](https://discourse.processing.org/t/cant-pass-a-3d-integer-array-into-a-glsl-shader/39392/10 "2022-10-26T23:27:27Z")

</div>

It makes little difference whether you use pgl or gl. pgl is just a wrapper. It simply doesn’t have much of the more modern opengl calls. So you might as well just use gl instead and don’t bother with pgl.
