regl icon indicating copy to clipboard operation
regl copied to clipboard

Clearer documentation/examples of similar `regl.cube` and `regl.texture` APIs

Open keeffEoghan opened this issue 6 years ago • 0 comments

There are similarities between the two APIs, but it can be quite unclear where some of the parameters should be passed.

In my example, I needed to generate custom mipmaps for a regl.cube, which would be read shader-side by textureCubeLodEXT(samplerCube sampler, vec3 coord, float lod), where changing lod would sample a different image. I was able to get my pre-made mip images into the cube, but whatever parameters I passed, the prepared mips would be overridden by mips auto-generated from the first image. I tested this by passing array data, setting the colour of each mip level to be different, with the syntax demonstrated in #471 and the accompanying demo (which was the only place more in-depth cube mip syntax was detailed) - mip image array 0 was blue, mip image array 1 was red, etc; but no matter the LOD used I'd always see blue. Where faces was of the form:

const faces = Array(6).fill().map(() => ({
    mipmap: [
        // Mip LOD 0 - blue
        [
            0, 0, 255, 255,
            0, 0, 255, 255,
            0, 0, 255, 255,
            0, 0, 255, 255,
        ],
        // Mip LOD 1 - red
        [
            255, 0, 0, 255,
        ]
    ]
}));

I tried passing various mip options in a number of ways, some of which included:

  • Into each entry in faces in various ways (it was some time before I found the correct syntax in #471), and passing that to the regl.cube constructor: regl.cube({ faces, /* etc... */ });, and regl.cube({ faces, mipmap: false, /* etc... */ });, and so on.
  • Into the mipmap field of the regl.cube constructor: regl.cube({ mipmap: faces, /* etc... */ });
  • Finally the correct/working version, which was to set the mips in faces as above, and passing that to both the faces and mipmap fields of the regl.cube constructor: regl.cube({ faces, mipmap: faces, /* etc... */ });

Seems like a weird syntax, but that's what worked. It took longer than I'd like to admit to figure this out - also with trying to narrow down to this mip-generation issue rather than something else, like the use of textureCubeLodEXT, the dimensions (radius, shape, width, height; or all; and at which level?). The docs and/or unit tests on the regl.cube could probably use a little expansion to help with that, as so far it's kind of saying "cube is like texture mostly, but not always", and it's not clear which level of the API will be targeted by which level of parameter. Thoughts in this case:

  • The (correct? working) syntax duplicates the mipmap parameter to both the faces and mipmap options, which is odd - seems it should probably go into one and be propagated in a standardised way.
  • The mipmap options also seem to accept Array<Image>, not just Array<Array>, which led me down a little rabbit-hole of converting the images to arrays first with get-image-pixels; this isn't listed in the docs, but is good to know that it works, and works for both textures and cubes.
  • #151 demonstrates there's duplicated code between the 2 modules, so it's not clear that an option which would work passed to texture would also work passed to one of the faces of a cube; it seems having that parity/consistency would be ideal along with efforts towards that issue.

Anyway, there are issues covering this more generally (e.g: #151), posting this so it might help others find the syntax until those issues are released.

Really loving this framework - though getting quite stuck every now and then on an unclear issue like this.

keeffEoghan avatar Nov 01 '18 15:11 keeffEoghan