How to read 2 textures in one WebGL fragment shader? | Sololearn: Learn to code for FREE!
New course! Every coder should learn Generative AI!
Try a free lesson
+ 1

How to read 2 textures in one WebGL fragment shader?

I want to have a fragment shader in WebGL read from 2 textures. I have a Sampler2D corresponding with each texture. After loading the second texture, all calls to texture2D using either sampler2D appears to return black. This problem can be reproduced at: https://code.sololearn.com/WA18A2a0a21A To reproduce: 1. Run that code. 2. Adjust any of the x, y, z, or scale controls to redraw. Every texture including the surface will go black which is not desired. My goal with this question is to fix the code enough to have the cloud texture loaded on one side/hemisphere and the surface texture loaded on the other. I don't want loading the cloud texture to affect the surfaceSampler. Key parts of the code are: - loadCloudTexture function in JS. If the implementation is commented out, surfaceSampler continues to work fine when adjusting the x, y, z, or scale controls. - loadTexture function in JS. I added the level parameter hoping it could help load multiple textures but it didn't work. level is a constant in the code this was adapted from. This function is adapted from a working example at https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL which loads only 1 texture. I removed the power of 2 checks because my code's images definitely don't use power of two dimensions. - The fragment shader is implemented in the HTML section. I added a little red light to the cloud-sampled side just so it'll be visible even when texture2D on the samplers return black. If you get the second texture to work, please point out what you changed and why that should fix it. What am I doing wrong?

17th Jan 2021, 7:02 AM
Josh Greig
Josh Greig - avatar
3 Answers
+ 1
Thanks for the links, David. I saw them posting the question before, though. I ended up discovering the problem. I needed to call gl.activeTexture(gl.TEXTURE1); before loading the second texture. It looks like the gl.bindTexture in my loadTexture function depends on the latest activated texture. Also, the level parameter to the loadTexture function was useless. The gl.texImage2D level parameter needed to be 0 for both textures to work. Passing it as a parameter to loadTexture function didn't fix anything. I'll update the referenced code to include these fixes.
17th Jan 2021, 8:24 AM
Josh Greig
Josh Greig - avatar
+ 1
Josh Greig I wish I had some free time to validate these articles against your code sample before presenting them. But... I figured I'd share them in case you haven't already come across these or something similar. https://webglfundamentals.org/webgl/lessons/webgl-2-textures.html https://dev.to/lesnitsky/webgl-month-day-10-multiple-textures-gf3 Good Luck 👌
17th Jan 2021, 8:00 AM
David Carroll
David Carroll - avatar
0
The referenced code was adjusted and polished into something to show Earth at https://code.sololearn.com/WA18A2a0a21A/# It uses 2 textures representing the Earth's surface and clouds and various other interactive settings.
18th Jan 2021, 10:34 AM
Josh Greig
Josh Greig - avatar