Access 2 sprites/textures in a WebGL shader for a Sprite object?

0 favourites
  • 7 posts
From the Asset Store
High quality sound effect pack, in the following categories: Dark, Mystical, Peaceful
  • I have a use case where I could really benefit from accessing an additional sprite/texture in a WebGL shader. The reason is that I have visual information in one texture and in the other texture I extra information I want accessible to my shader algorithm.

    Is there any way to do this? Can I access an additional animation on the Sprite via the shader?

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • Anyone have any ideas?

    I hope there is a way to do this and we don't have to place two textures inside a single texture and access the coordinates with an offset or something like that.

  • Your question is mostly incomprehensible to be, but try taking your two objects and effects and pasting them to a drawing canvas to combine into a single object.

  • Yeah it sounds like you want to add a normal map to a texture without having to add the map.

  • Shaders in construct are limited in what you can access. So you can't access additional textures currently unless they update it in the future. Best bet would be to add the idea to the suggestion platform and hope it's picked up.

    According to the manual:

    construct.net/en/make-games/manuals/addon-sdk/guide/configuring-effects

    That page lists what you have access to from an effect. Currently the two textures you can have access to are the foreground and background. Maybe with some trickery you could have two sprites stacked and use the backgound samper to get the image below. However that has a lot of cases it probably wouldn't work well.

    An unsupported way would be to use webgl directly but that can be tricky/kinda unsolved for C3. Construct's renderer uses webgl behind the scenes currently, with a focus on batching things for speed. In construct 2 I found that you could end all the current batches and then use any webgl you wanted for maximum flexibility. The only caveat was you needed to make sure the webgl state was unchanged when you finished the webgl code otherwise it would break construct's renderer.

    Construct 3's renderer has been reengineered and updated a few times so it's less clear how to utilize custom webgl, if at all. Last I looked it's setup in suck a way to be more of a black box that you can only interact with in a supported way. Also I believe they plan on utilizing a different api later on, and I could see them reworking the renderer in the future, so that would make any unsupported solution easy to break.

    Anyways if you want to attempt it you'll need a few things. First you'll need to access the webgl context of the canvas. There may be something in the js sdk that provides that or you can attempt to grab it from the canvas itself. Next you'll need to access the compiled shader program for your effect. That's probably the biggest roadblock as that might be hidden behind some closures in construct's renderer. Also even if you can find a list of shader programs in the renderer it may still be an issue of figuring out which one it is.

    Anyways, if you're able to find a way to access your effect's shader program then something like the following might be a way to set a second texture you can access from the effect.

    You'd add this line to your effect:

    uniform sampler2d texture2;

    Then to make that reference a texture you'd need to do something like this:

    function setTexture2(gl, program, texture)
    {
     var u_tex2Location = gl.getUniformLocation(program, "texture2");
     gl.uniform1i(u_image0Location, 4); // texture unit 4.
     gl.activeTexture(gl.TEXTURE4);
     gl.bindTexture(gl.TEXTURE_2D, texture);
    }

    You need to call that function with the webgl context, the shader program of your effect, and the handle to a webgl texture. The texture is either loaded with wegl or you somehow access another texture from a sprite or something. The most fragile part here is I'm assuming that texture unit 4 isn't used by construct's renderer so we take advantage of that by using it. You'd only need to call that function when we want to change the texture.

    Other potential issues that may need to be dealt with is how that will sync with the renderer. There may be other issues I'm not thinking of.

    Overall I generally just try to work within what features construct provides, but there are other potential solutions, they just don't always pan out.

  • Your question is mostly incomprehensible to be, but try taking your two objects and effects and pasting them to a drawing canvas to combine into a single object.

    oosyrag This can't be achieved by a blending function between two layers. I need a single shader to make calculations based on two incoming textures.

    Yeah it sounds like you want to add a normal map to a texture without having to add the map.

    newt I'm not trying to add a normal map, traditionally that refers to lighting information. But you're correct that I am trying to add an extra texture to serve as a map of some kind. I'm not attempting to do this "without adding the map". I want to add the map, but when I look at Construct's shader code, I don't see a way of providing a second text.

    If you do know how to add a second texture, please tell me!

    Shaders in construct are limited in what you can access. So you can't access additional textures currently unless they update it in the future. Best bet would be to add the idea to the suggestion platform and hope it's picked up.

    R0J0hound Interesting! Thanks for the detailed response. Indeed you are understanding my request correctly. Your suggestion to access additional textures via a 'gl.getUniformLocation()' and 'gl.uniform1i()' is interesting but some of my concerns are:

    • My project will have many, many sprite objects that will include this shader (usually only 1 or 2 on-screen at a time, don't worry). And each sprite object will need an accompanying additional texture for the shader.
    • If it always needs to be loaded programmatically like this, I'd probably need to make the path to the additional texture a variable on the effect that is passed through.
    • Which sounds a bit messy/complicated and presumably this will create quite a lot of work in preparing the textures in the project.

    If the above works, it'd be a doable solution. But I don't know if that technique does work – i.e. loading extra textures via the shader through an additional file path request. I also wonder if that stalls the initial load of the shader or anything like that.

    I'd love if Ashley weighed in with any thoughts on this!

  • Using an additional texture input to a shader is not currently supported. The only workaround is to use the foreground and background as two separate inputs, which is what the built-in normal mapping shader does (instead of providing the normal map as an additional input).

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