0 Favourites

How to implement a look up table in a shader?

  • I need a way to store 16 arbitrary values in a shader and output one of them depending on a 0-1 input range. I tried to use a 4x4 matrix and also an array, but none of them work. It seems GLSL doesn't allow to use variable indexes to access them.

    Searching the internet I found that the common approach is to use a texture as a look up, but C2 doesn't have any mechanism to pass additional textures to shaders besides the front and back samplers.

    So, what is the proper way to implement a look up table in a shader?

  • You mean other than a mask?

  • Construct 3

    Buy Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Buy Now Construct 3 users don't see these ads
  • Yes. I need to store 16 weights and access them by a variable index. It's possible to use the front texture to pass the weights as a small sprite in the corner and sample the proper pixels, but then I don't have access to the front texture where the weight texture is. It basically will add a weight texture to the corner of the game, which is not acceptable.

    I need either a way to store and access the weights in shader code, or a way to pass additional textures to shaders.

    It would be great if we could add a kernel texture along with the shader files and specify a dependency in the xml. This would add so many possibilities:

    Or if it was possible to expose a texture param where the user could enter a project file to use as a texture:

    But while that's not implemented I think the only way is to discover how to store and access the weights by a variable index in the shader code.

  • As it is C2's renderer doesn't let you pass anything but numbers to shaders.

    There are a lot of other values that you can pass to webgl in shaders, including lists of numbers, textures and even lists of textures.

    [quote:24fpga9v]gl.uniform1f (floatUniformLoc, v); // for float

    gl.uniform1fv(floatUniformLoc, [v]); // for float or float array

    gl.uniform2f (vec2UniformLoc, v0, v1); // for vec2

    gl.uniform2fv(vec2UniformLoc, [v0, v1]); // for vec2 or vec2 array

    gl.uniform3f (vec3UniformLoc, v0, v1, v2); // for vec3

    gl.uniform3fv(vec3UniformLoc, [v0, v1, v2]); // for vec3 or vec3 array

    gl.uniform4f (vec4UniformLoc, v0, v1, v2, v4); // for vec4

    gl.uniform4fv(vec4UniformLoc, [v0, v1, v2, v4]); // for vec4 or vec4 array

    gl.uniformMatrix2fv(mat2UniformLoc, false, [ 4x element array ]) // for mat2 or mat2 array

    gl.uniformMatrix3fv(mat3UniformLoc, false, [ 9x element array ]) // for mat3 or mat3 array

    gl.uniformMatrix4fv(mat4UniformLoc, false, [ 17x element array ]) // for mat4 or mat4 array

    gl.uniform1i (intUniformLoc, v); // for int

    gl.uniform1iv(intUniformLoc, [v]); // for int or int array

    gl.uniform2i (ivec2UniformLoc, v0, v1); // for ivec2

    gl.uniform2iv(ivec2UniformLoc, [v0, v1]); // for ivec2 or ivec2 array

    gl.uniform3i (ivec3UniformLoc, v0, v1, v2); // for ivec3

    gl.uniform3iv(ivec3UniformLoc, [v0, v1, v2]); // for ivec3 or ivec3 array

    gl.uniform4i (ivec4UniformLoc, v0, v1, v2, v4); // for ivec4

    gl.uniform4iv(ivec4UniformLoc, [v0, v1, v2, v4]); // for ivec4 or ivec4 array

    gl.uniform1i (sampler2DUniformLoc, v); // for sampler2D (textures)

    gl.uniform1iv(sampler2DUniformLoc, [v]); // for sampler2D or sampler2D array

    gl.uniform1i (samplerCubeUniformLoc, v); // for samplerCube (textures)

    gl.uniform1iv(samplerCubeUniformLoc, [v]); // for samplerCube or samplerCube array

    Some of those could be useful additions to request.

    To do it without official support could be very tricky.

    In webgl/js if you compile a shader you first need to get the variable location in the shader with something like:

    var offsetLoc = gl.getUniformLocation(someProgram, "u_offset");

    Then you'd set the uniform before drawing using one of the functions listed above.

    So basically it's rather simple in just javascript, but you can't do that for C2 since you need it to work with the runtime's batch renderer to get the effect to be applied to anything else the runtime draws. Modifying the batch renderer isn't trivial and is best left to be done by Scirra since a lot of other things in the runtime and editor would need to be done to accommodate it.

    You could just do your own webgl renderer in a plugin to render to a texture that c2's renderer could then draw, but I haven't had much luck in the past grabbing what's already been rendered to modify.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)