regl icon indicating copy to clipboard operation
regl copied to clipboard

[Feature Suggestion] Texture data format: 'C' or 'F'

Open deluksic opened this issue 4 years ago • 4 comments

In numerical libraries like numpy, there is a distinction between C-style and Fortran-style (row-major, column-major) memory order.

Currently, as far as I can tell, default and only way to upload texture data through regl.texture is Fortran-style (column-major) since in texture.js at line 771 transposeData function is applied.

Proposal: Add a flag to texture constructor to choose C-style and skip this transposition step. Possible flags could be:

{
  memoryOrder: 'row' | 'column' | 'C' | 'F',
  transpose: boolean
}

deluksic avatar May 22 '20 11:05 deluksic

I can also give this a go if you agree with the suggestion.

deluksic avatar May 22 '20 12:05 deluksic

Thanks for the suggestion, @deluksic!

For the sake of argument, I made an example of how this may be accomplished with the current API: Reorganizing Input Data for regl Using the ndarray Format

To make a long story short, you may use data, shape, stride, and offset to pass any ndarray-like object as the data property of a texture. The shape/stride/offset combination allows you to perform any reordering/flipping/transposing/striding/etc, and regl performs the copy internally, as needed to correctly pass data along to WebGL.

As for what those strides are, you can perform the stride computation yourself, which is not exactly user-friendly, nor is it the worst, or you can use the ndarray library (it's small!) and pass an actual ndarray object for the texture data.

In short, the shape/stride computation is:

value(i, j, k) = data[offset + stride[0] * i + stride[1] * j + stride[2] * k...]

which gives you quite a few possibilities.

Unless I'm mistaken, I do find the combination of memoryOrder, transpose, and the existing flipY flag a bit confusing since it seems like those operations depend on the order in which they're applied to the input, as opposed to passing an ndarray which clearly indicates that massaging the input is your concern, and the only thing regl can do is flipY.

rreusser avatar May 23 '20 00:05 rreusser

I am already pre-transposing the ndarray like this, to get the correct format:

array.transpose(1, 0, 2);

However, I felt its a little weird that a transpose needs to be done at all. Hence my suggestion to introduce transpose OR memoryOrder (not both, sorry!). I would lean towards memoryOrder.

I see your point about flipY and operation order. But memory order in my mind has nothing to do with what is a Y direction. In any case, memoryOrder would be done first as it is just a format specification, and then you can have a potential flipY act on it later. Does it make sense? :relaxed:

deluksic avatar May 23 '20 18:05 deluksic

On the other hand, what would be very confusing is: this flag makes no sense if you don't pass in an ArrayLike object for data, since that code path does not seem to transpose anything?

deluksic avatar May 23 '20 18:05 deluksic