0

Solution

I have decided to use a texture as I will not need to modify the data and here is how you would pass a texture to the shader:

The data is being passed to a variable (Sampler2D) named "worldData"

Javascript Code:

var tex = gl.createTexture();
  gl.bindTexture(gl.TEXTURE_2D, tex);
  var level = 0;
  var width = 2;
  var height = 1;
  var data = new Uint8Array([
   255, 0, 0, 255,   // a red pixel
   0, 255, 0, 255,   // a green pixel
  ]);
  gl.texImage2D(gl.TEXTURE_2D, level, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);

  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);

  var unit = 5;  // Pick some texture unit
  gl.activeTexture(gl.TEXTURE0 + unit);
  gl.bindTexture(gl.TEXTURE_2D, tex);
  
  gl.uniform1i(gl.getUniformLocation(program,"worldData"), 5);

Top of Fragment Shader:

uniform sampler2D worldData;

Output:

gl_FragColor = texture2D(worldData,vec2(0.5,0.5));

This code can be extended to pass-through lists, Need and help? comment and I hope to respond, however, I am still new to WebGL


Original Post

I am quite new to shaders but I am attempting to create a Voxel Raycaster in GLSL, my method is to pass the World Data through int uniforms however there seems to be an Array Size limit once I reach the thousands, are there any ways to get around this or any better ways to pass the Data through?

EDIT: I have now decided to switch to textures although I still seem to be having issues, I would expect this code to fill the screen red however it seems to be filling it black (0.,0.,0.,1.)

This code runs in the Javascript:

var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
var level = 0;
var width = 2;
var height = 1;
var data = new Uint8Array([
 255, 0, 0, 255,   // a red pixel
 0, 255, 0, 255,   // a green pixel
]);
gl.texImage2D(gl.TEXTURE_2D, level, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);

var unit = 5;  // Pick some texture unit
gl.activeTexture(gl.TEXTURE0 + unit);
gl.bindTexture(gl.TEXTURE_2D, tex);
  
gl.uniform1i(gl.getUniformLocation(program,"worldData"), 5);

This code is at the top of the shader

uniform sampler2D worldData;

And this code is at the bottom:

gl_FragColor = texture2D(worldData,vec2(0.5,0.5));

  • the limit can be queried using `gl.getParameter(MAX_FRAGMENT_UNIFORM_VECTORS)`, for what you're trying to do textures are the way to go. – LJᛃ Sep 26 '20 at 14:46
  • Interesting, I can't seem to find any good sources on how to create a texture in WebGL and how to pass it to the uniform. – ThetaHacker Sep 26 '20 at 15:46
  • 1
    There's a gazillion sources on how to create and use textures in webgl... like [this one](https://webglfundamentals.org/webgl/lessons/webgl-3d-textures.html) or [that one](https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL) – LJᛃ Sep 27 '20 at 01:06
  • I have updated the post to include my code. Help would be greatly appreciated but you don't have to. I would expect the code to make the screen red however it is black – ThetaHacker Sep 27 '20 at 02:55
  • Thank you for your help, apparently gl.texParameteri(...) is necessary – ThetaHacker Sep 27 '20 at 16:04

0 Answers0