0
$\begingroup$

I'm working on a scientific visualization project and need to create a transfer function widget. The volume data is either in range 0-255 or it can be 16 bit i.e. 0-65535. Now the main problem is in order to color certain sections, the user needs to be able to define certain control points with varying colors and the colors need to be smoothly transitioned between those control points. Then during rendering, we find the color for every isovalue through a texture lookup in a ramp texture and color the volume data.

I've decided to do cubic spline interpolation between these control points. My question is, how do I actually render and store this gradient in an Nx1 ramp texture. Firstly, regarding the rendering part. I'm using OpenGL but also Dear-ImGui for GUI. So I don't have low level access to rendering like vertex/fragment shader for rendering this gradient. Just low level functions like rendering lines/rectangles etc.

For 8 bit volumes, I could render 256 lines of thickness gradient_width_in_pixels/256. I think this would give me the look of a rectangular gradient? However suppose I have a 16 bit volume. The max value now is 65k. I could go on and convert it to 0-255 but let's say I don't because there would be a loss of precision as in the 0-255 scale 1 value represents approximately 256 values of 0-65535 scale. What if the user wanted to color within that range? What's the proper way to handle this scenario now?

Secondly, regarding storing the gradient information. For 8bit datasets, again it'd seem pretty simple to just create an 256x1 texture. However the problem again rises for 16 bit datasets. 65k pixels don't sound good or are they okay? I know 65k x 1 texture is just a 256x256 texture but dunno if increasing only 1 dimension will cause problems.

EDIT: I thought I should clarify regarding rendering the gradient part and ask the question differently. What I wanna know is given a color control point at pixel coord (x1,y) and another point at (x2, y), how many lines of any thickness should I render to get a color gradient with smooth transition between those two colors?

$\endgroup$
1
  • $\begingroup$ The maximum texture dimension in most GPUs is 16K or 32K, so a 64K texture isn't going to fly I don't think. Regarding the gradient, if you're asking about how to render a gradient on screen so it will look visually smooth, ideally you would use dithering. If dithering is not possible, and you are not on an HDR / wide color gamut monitor, then the best you can do is one line for each 1 unit change in the 8-bit RGB values, which would mean at most 256 lines for each color segment of the gradient. $\endgroup$ Commented Sep 28, 2022 at 0:07

1 Answer 1

1
$\begingroup$

It may be easier to compute the gradient on the CPU, even with 16bit precision the CPU can grind out a texture quickly. Then just upload that to the GPU as an image. Also, it doesn't sound like users will be able to pick a new color set every frame so its sounds a lot more natural to have a work flow of: Pick colors -> Generate Image -> upload to the GPU -> use new palette to render.

Are the picked colors RGB choices? If yes then it does make sense to spread the color palette out as wide as possible (maybe even more then 16bits) 65536 pixels is just a drop in the bucket. And a nice wide color range could lead to less banding in the final image.

At some level the code will have to narrow the range down to whatever the current precision is. If that is the table, and the table has 65536 positions, then the table might contain a lot of repeating colors, but it is easy to compute the table with a new range.

$\endgroup$
1
  • $\begingroup$ By spreading out the palette you mean physically the size of the palette or internally the bits? I don't need to go more than 16bits as volume data is either 8 or 16 bit $\endgroup$ Commented Apr 29, 2021 at 13:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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