Can a texture store negative values?

For some background, I am trying to perform MAX blending in a pass to calculate the minimum and maximum depth and store it in the RG channels respectively of a RGBA32F texture. To use MAX blending to calculate the minimum I negate the depth value when storing it so it needs to store negative values. Therefore, the MAX blending should result in the least negative (closest to 0) value being written for the minimum depth.

However, it seems that threejs clamps the texture values from [0,1]. Is there a way to change the settings of the texture to support negative values? Would changing the internalformat help? Ideally, I would like to be able to store values from [-1,1] in the texture.

Here are the full settings of the texture I am writing to:

  • type: TEXTURE
  • textureLevel: 0
  • textureCubeMapFace: NONE
  • textureType: FLOAT
  • format: RGBA
  • internalFormat: RGBA32F
  • width: 600
  • height: 900
  • alphaSize: 32
  • blueSize: 32
  • encoding: LINEAR
  • componentType: FLOAT
  • depthSize: 0
  • greenSize: 32
  • redSize: 32
  • stencilSize: 0
  • textureLayer: 0

It appears like you are storing each component as a 32 bit floating point value. I don’t see why a 32 bit float wouldn’t be able to also hold negative values, as the 1st bit is reserved as the “sign-bit”.

Reference: Single-precision floating-point format - Wikipedia

As @vielzutun.ch mentioned, Float textures should be able to hold both + and - values.

The other formats that can hold signed values are indicated in the texture type where it shows like RGBA8_SNORM == signed + normalized
vs like RGBA32UI == 32 bit (U)nsigned (I)nteger

It’s only the texture formats that use an unsigned datatype that can’t hold negative numbers… and the N type (normalized) textures will be clamped to -1 to 1 range.

https://threejs.org/docs/#api/en/constants/Textures

However, the built in materials may clamp the texture values internally when they are read. If that’s the case, you might need to hack the materials shader itself to prevent that, or use your own custom shader.

There are also Blending modes you can use to Add or Subtract…
like THREE.AdditiveBlending, SubtractiveBlender, MultiplyBlending, etc…

1 Like

I’ve figured out the solution (or my problem in this case). The RGBA32F texture can hold negative values. I was just doing something wrong during my MAX blending.