Converting RGB planes to XYZ dimensions

aceslowman's icon

I'm working with an argb matrix, and would like to convert it into a single plane matrix, mapping rgb to xyz. I am attempting to fill a jitter matrix with 3D voronoi (similar to jit.bfg), but on the GPU.

I have gone down a few different paths in working on this:

First of all, I imagine that I could take a [jit.matrix 4 char 512 512] and remap RGB->XYZ, into a [jit.matrix 1 char 64 64 64]. Both should have an equivalent amount of data, but so far I have not found a way to remap the planes to match the new dimensions.

Next, and something I know far less about, I am finding information about 3D textures in OpenGL. I imagine something like this:

[jit.matrix 1 char 64 64 64] -> [jit.slab @file 3dVoronoi.jxs] -> [jit.matrix 1 char 64 64 64]

So far, I have not figured out how to utilize 3D texture coordinates, and even then, I can't seem to send a 3D matrix to a slab, and then read back into a 3D matrix.

Does anybody have some guidance on this, or some references that I could be pointed towards?

Thanks!

aceslowman's icon

Full patch below:

3DVoronoi.jxs

<jittershader name="default">
    <description> Default shader </description>
    <param name="offset" type="float" default="0.0" />
    <param name="scale" type="float" default="0.1" />    
    <language name="glsl" version="1.0">    
        <bind param="offset" program="fp" />
        <bind param="scale" program="fp" />    
        <program name="vp" type="vertex">
<![CDATA[
void main (void)
{
gl_Position = ftransform();
    gl_FrontColor = gl_Color;
}
]]>        
        </program>
        <program name="fp" type="fragment">
<![CDATA[

// 3D Voronoi code originally by Max Bittker, adapted for Max
// https://github.com/MaxBittker/glsl-voronoi-noise/blob/master/3d.glsl
const mat2 myt = mat2(.12121212, .13131313, -.13131313, .12121212);
const vec2 mys = vec2(1e4, 1e6);
vec2 rhash(vec2 uv) {
  uv *= myt;
  uv *= mys;
  return fract(fract(uv / mys) * uv);
}
vec3 hash(vec3 p) {
  return fract(
      sin(vec3(dot(p, vec3(1.0, 57.0, 113.0)), dot(p, vec3(57.0, 113.0, 1.0)),
               dot(p, vec3(113.0, 1.0, 57.0)))) *
      43758.5453);
}
vec3 voronoi3d(const in vec3 x) {
  vec3 p = floor(x);
  vec3 f = fract(x);
 float id = 0.0;
  vec2 res = vec2(100.0);
  for (int k = -1; k <= 1; k++) {
    for (int j = -1; j <= 1; j++) {
      for (int i = -1; i <= 1; i++) {
        vec3 b = vec3(float(i), float(j), float(k));
        vec3 r = vec3(b) - f + hash(p + b);
        float d = dot(r, r);
       float cond = max(sign(res.x - d), 0.0);
        float nCond = 1.0 - cond;
       float cond2 = nCond * max(sign(res.y - d), 0.0);
        float nCond2 = 1.0 - cond2;
       id = (dot(p + b, vec3(1.0, 57.0, 113.0)) * cond) + (id * nCond);
        res = vec2(d, res.x) * cond + res * nCond;
       res.y = cond2 * d + nCond2 * res.y;
      }
    }
  }
 return vec3(sqrt(res), abs(id));
}
uniform float scale;
uniform float offset;
void main()
{    
    vec3 coord = gl_FragCoord.xyz;
 
    vec3 color = voronoi3d((coord * scale) + offset);
 
    gl_FragColor = vec4(color, 1.0);
} 
]]>
        </program>
    </language>
</jittershader>
Max Patch
Copy patch and select New From Clipboard in Max.