Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creating textures from arrays #14

Closed
tjpotts opened this issue Sep 21, 2015 · 9 comments
Closed

Creating textures from arrays #14

tjpotts opened this issue Sep 21, 2015 · 9 comments
Assignees
Milestone

Comments

@tjpotts
Copy link

tjpotts commented Sep 21, 2015

I have a shader which I'm trying to adapt to work with gl-react, but I've run into a problem. My shader uses a texture effectively as a gaussian function lookup table. In my previous implementation, the gaussian function was calculated beforehand as an array of values which was then used to create a GL texture to be used in the shader.

However, the only way I can see of creating textures using gl-react is by specifying an image source path. Is there any way of using an array of precomputed values instead? Or any sort of work around?

@gre
Copy link
Owner

gre commented Sep 21, 2015

gl-react not only supports textures as uniforms but also supports types like: int, float, vecN, matN, ...

You can also send an array via uniforms.

gl-react relies on gl-shader which have support for array / struct. This mapping is not documented in gl-react because it is not currently supported in gl-react-native (but will eventually be implemented).

Here is an example:

const React = require("react");
const GL = require("gl-react");

const shaders = GL.Shaders.create({
  arrayExample: {
    frag: `
precision highp float;
varying vec2 uv;

uniform float array[6];

void main () {
  gl_FragColor = vec4(
    array[0] + array[1],
    array[2] + array[3],
    array[4] + array[5],
    1.0);
}
    `
  }
});

class ArrayExample extends GL.Component {
  render () {
    const { width, height } = this.props;
    return <GL.View
      shader={shaders.arrayExample}
      width={width}
      height={height}
      uniforms={{ array: [0.0, 0.1, 0.2, 0.3, 0.4, 0.5] }}
    />;
  }
}

module.exports = ArrayExample;

renders a blue square (rgb(10%, 50%, 90%)):
screen shot 2015-09-21 at 10 42 02

@gre gre added the question label Sep 21, 2015
@tjpotts
Copy link
Author

tjpotts commented Sep 21, 2015

Unfortunately, WebGL does not support dynamically indexing arrays. In my case (I am implementing a bilateral filter) I need to lookup values based on differences in values in the source image, which makes using an array not possible due to this limitation of WebGL. This is why I have been using a texture to store the data instead (which also gives the benefit of allowing for interpolation on the pre-calculated function).

It sounds like the functionality I am looking for is not explicitly supported, so do you have any suggested way of hacking around it? Or a suggested way of adding this ability? It looks like both gl-shader and gl-texture2d should allow for it just fine.

@gre
Copy link
Owner

gre commented Sep 21, 2015

oh, so you want to use a texture for this. Sorry I missed your initial needs.

You want to create a texture from your array.
Yeah gl-texture2d allows ndarray object.

Now we just needs a special case for this if we want it to work in gl-react.

In the meantime, as a workaround here is what you could do:

  • Create a temporary canvas of your texture of dimension width=arraySize height=1, get a 2D Context, draw your array in it.
  • get a data64 uri of it. canvas.toDataURL()
  • pass this in the uniforms (it will works like an image url).
  • in your shader, lookup at position (percentage, 0.5). Nice side effect is you also have linear interpolation for free.

@tjpotts
Copy link
Author

tjpotts commented Sep 21, 2015

That worked great, thanks! Are there any plans to add this into gl-react so that the work-around doesn't need to be used?

@gre gre added feature and removed question labels Sep 21, 2015
@gre gre self-assigned this Sep 21, 2015
@gre
Copy link
Owner

gre commented Sep 21, 2015

that sounds like a great feature to add.
I don't think it involves too much work, I'll add it in gl-react soon and see if it is easy to add in gl-react-native.

@gre
Copy link
Owner

gre commented Sep 21, 2015

I've got it implemented.
It will be released in next version of gl-react, probably this week.
We need to check everything works as expected (especially with the 2 other features that will be included in this release).

A gl-react-native version of this feature is not planned for now (unless someone needs it) because implies some work if we want to implement it as well as gl-texture2d does.

Use-case example:

// var ndarray = require("ndarray");

var t1 = ndarray(new Float64Array([
  1, 0, 0, 1,
  0, 1, 0, 1,
  0, 0, 1, 1
]), [3, 1, 4]); // here, using Float*Array & [ w, h, 4 ] shape will result of RGBA & FLOAT mode

var t2 = {
  disableLinearInterpolation: true,
  array: ndarray(new Float64Array([
    1, 0, 0, 1,
    0, 1, 0, 1,
    0, 0, 1, 1
  ]), [3, 1, 4])
};

var t3 = require("baboon-image");

Results:
screen shot 2015-09-21 at 20 58 06

(all of these ndarray shapes are supported: https://github.com/stackgl/gl-texture2d#var-tex--createtexturegl-array , in your use-case you might just need the [w,h,1] or the [w,h] shape. I have not tested them )

@tjpotts
Copy link
Author

tjpotts commented Sep 21, 2015

Awesome! This should be perfect.

gl-react-native support would be nice, as I'd like to have the ability to port to a native app in the future, but not a huge deal for me personally.

Another feature I've realized I will be needing though is the ability to set the texture wrapping to gl.CLAMP_TO_EDGE. Since there's already code to enable/disable interpolation, I assume this would be pretty straight forward to add in a similar fashion?

@gre
Copy link
Owner

gre commented Sep 21, 2015

gl.CLAMP_TO_EDGE will be here by default.
selecting another mode might be another feature. If we implement this we will need to do it also for images.

@gre gre added this to the 1.1.0 milestone Sep 26, 2015
@gre
Copy link
Owner

gre commented Oct 1, 2015

will be in incoming 1.1.0

@gre gre closed this as completed Oct 1, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants