Using DataTextures in shader materials

I’m using a DataTexture to pass the map of biomes (desert, tundra, forest, etc) to my terrain shader. While this works, I get this warning:

[.WebGL-0x7f97b1d20e00]GL ERROR :GL_INVALID_OPERATION : 
glDrawElements: Texture bound to texture unit 0 with internal format GL_R8UI is not compatible with sampler type GL_SAMPLER_2D

The texture is being created like this:

this.biomeTexture = new DataTexture(biomeData, size, size, RedIntegerFormat, UnsignedByteType);
this.biomeTexture.internalFormat = 'R8UI';
this.biomeTexture.wrapS = this.biomeTexture.wrapT = ClampToEdgeWrapping;
this.biomeTexture.minFilter = this.biomeTexture.magFilter = NearestFilter;
this.biomeTexture.needsUpdate = true;

And the sampler is being declared in my shader like this:

uniform lowp usampler2D surfaceTypeMap;

Like I say, it works, in the sense that what I am seeing on the screen is correct; but it has a bunch of warnings in the console that I would like to get rid of.

On a related question: currently I am making the data texture a power of two (rounding up). Is there any benefit to doing this for data textures?

When using NearestFilter then no.

With WebGL 1 it was required to have POT textures so mipmaps could be generated. But with WebGL 2 (the default of latest three.js version) even this is not required anymore.

Do you mind demonstrating the issue with a live example. You can use this fiddle as a basis:

I think I have figured out what is going on: it appears to be a leakage of state between two different shaders. Essentially, the terrain shader is using an integer sampler, and the water shader is using a shadowmap - somehow the integer texture that is being bound for the terrain sample is also being bound to the shadowmap sampler for the water shader, and since the shadowmap shader is a floating-point sampler GL complains.

I noticed several things:

  • The warnings would only appear when the camera was near water.
  • When the warnings started appearing, the water would stop rendering.

I was confused at first because the water shader doesn’t use any texture samplers and has lights: false. However, USE_SHADOWMAP was still defined for some reason, so it was declaring a sampler uniform even though it wasn’t actually using it for anything.

When I added #undef USE_SHADOWMAP in the water shader, the problem went away.