0
$\begingroup$

I wrote a Python script to generate several image textures for use in Image Texture nodes. All the calculations yield values with many decimal places (some being on the order of 1e-7).

Printing the results of the calculations themselves to the console shows the values in full (or at least sufficient) precision. Printing the RGBA values of the generated image pixels for the image texture node, however, shows only one decimal place—with minuscule values being reduced to 0.0.

For this particular image texture node, this precision is not just a matter of display on the console. It really does seem that the RGBA values are 0.0. I say this because scaling the output of the Image Texture node by 1e7 has no effect (on color strength, which the node serves to control); yet, adding a 1e-7 to the output and then scaling suffices to get a nonzero color strength.

I figure that somewhere between the calculations themselves and the storing of the results in the generated image pixels, something is happening. This seems true: printing the RGBA values of the pixel entries in the generated image itself shows 0.0s instead of the small numbers I saw when printing the calculation results.

I'll post more detail if needed, but does anyone know why this might be happening? I should note that this kind of rounding doesn't seem to be happening for a different image texture file (whose values have many decimal places, though all are sizable fractions between 0 and 1, as opposed to being on the order of 1e-7).

Thanks in advance!

$\endgroup$
  • $\begingroup$ Related : blender.stackexchange.com/q/75066/29586. Note that by default a packed image will be packed as 8-bit. This will significantly affect precision. The solution is to ensure it's packed as 32-bit float but for this it seems it needs to be first saved to disk and then re-load it before packing. $\endgroup$ – Rich Sedman Aug 18 '18 at 6:58
  • $\begingroup$ See also blender.stackexchange.com/a/75429/29586 which generates in image from float values and stores as a 32-bit float image consisting of a single row of pixels. $\endgroup$ – Rich Sedman Aug 18 '18 at 8:14
  • $\begingroup$ Thanks!!! This is exactly what I needed. Saving in 32-bit EXR format resolved the issue with the image texture. The pixel RGBA values now have the decimal places that I expected and wasn't seeing before. Sadly... the numerical issue in my model persists, so now I have to search for its cause elsewhere. For some reason, the particles in my models are getting their colors from the wrong pixels—in some cases from pixels to the right, in others from pixels to the left. It seems like a numerical error and I can't figure out why it's there... $\endgroup$ – Alex Aug 20 '18 at 3:26
  • $\begingroup$ Glad to help. I did post a comment to your quesstion blender.stackexchange.com/questions/116110 relating to offsetting each coordinate in your texture by 0.5 pixel - does that help with your other issue? You example is currently sampling the image right on the pixel boundary (add 0.5 to the Image index prior to the Division node and also use 0.5 in place of the 1.0 in the Combine XYZ node). $\endgroup$ – Rich Sedman Aug 20 '18 at 6:04
  • $\begingroup$ While I've learned a lot about using image textures to control particle properties (thanks!), my issue sadly persists. I've switched to 32-bit EXR images, which helped with precision, offset my image texture input coordinates by half a pixel to ensure that the sampling is within a pixel, and even split my image texture into a 347 x 345 matrix to avoid dividing by a very large number (as I now have to divide by 347 at the most, instead of by 119617). Still checking the results from the last step, but as of now, my particle colors are still being sampled 9-13 px away from their correct places... $\endgroup$ – Alex Aug 20 '18 at 6:11
1
$\begingroup$

Images are usually created and packed as PNGs as 8-bit sRGB format. This severely limits the precision of the RGBA values stored. To improve precision you need to force the image to be stored in a format that supports 32-bit float channels such as EXR format.

To use a simple example, storing as an 8-bit image would be limited to steps of 1/256 or approximately 0.0039 - any value below around 0.002 would be rounded down to zero and any value from 0.002 to around 0.006 would be rounded to 0.004 (or 00000001 in binary). The actual values used for each 'step' is further complicated by the sRGB color conversion (which stretches the color space in order to produce a more practical range of colors for display on a screen - see Wikipedia sRGB

Examples of storing images in 32-bit float EXR format can be found in Creating and packing a 32-bit float image and Capture object properties to use in a Cycles material

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.