Can SoOffscreenRenderer use tiles bigger than 1024 - coin3d

The coin3d offscreen rendering class SoOffscreenRenderer is capable of rendering big images (e.g. 4000 x 2000 pixels), that don't fit on the screen or in a rendering buffer. This is done by partitioning the image into tiles that are rendered one after the other, where the default size of these tiles is 1024 x 1024.
I looked at the code of SoOffscreenRenderer and CoinOffscreenGLCanvas and found environment variables COIN_OFFSCREENRENDERER_TILEWIDTH COIN_OFFSCREENRENDERER_TILEHEIGHT. I could change the tile size using these variables, but only to sizes smaller than 1024. I could create tiles with 512 x 512 pixels, and also 768 x 768. When I used values bigger than 1024, the resulting tiles were always of size 1024 x 1024.
Is it possible to use bigger tile sizes like 2048 x 2048 or 4096 x 4096, and how would I do that?

It is possible to use larger tiles and coin does it automatically. It will find out which tile sizes work by querying the graphics card driver.
From CoinOffscreenGLCanvas.cpp:
// getMaxTileSize() returns the theoretical maximum gathered from
// various GL driver information. We're not guaranteed that we'll be
// able to allocate a buffer of this size -- e.g. due to memory
// constraints on the gfx card.
The reason why it did not work was that the environment variable COIN_OFFSCREENRENDERER_MAX_TILESIZE was set somewhere in our application using coin_setenv("COIN_OFFSCREENRENDERER_MAX_TILESIZE", "1024", 1);. Removing this call allowed bigger tile sizes to be used.
In CoinOffscreenGLCanvas::getMaxTileSize(void), the variable COIN_OFFSCREENRENDERER_MAX_TILESIZE is read and the tile size clamped accordingly.
On my older computer it generated tiles of size 1024, but on a newer machine the tiles were of size 4096.

Related

Using GPU to rasterize image with 128 color channels

I need to rasterize a multispectral image, where each pixel contains the intensity (8 bits) at 128 different wavelengths, for a total of 1024 bits/pixel.
Currently I am using OpenGL, and rasterizing in 43 passes, each producing an image with 3 of the 128 channels, but this is too slow.
Is it possible to do it in a single pass by somehow telling the GPU to rasterize a 128 color component image (not necessarily using OpenGL)?

Simulate Camera in Numpy

I have the task to simulate a camera with a full well capacity of 10.000 Photons per sensor element
in numpy. My first Idea was to do it like that:
camera = np.random.normal(0.0,1/10000,np.shape(img))
Imgwithnoise= img+camera
but it hardly shows an effect.
Has someone an idea how to do it?
From what I interpret from your question, if each physical pixel of the sensor has a 10,000 photon limit, this points to the brightest a digital pixel can be on your image. Similarly, 0 incident photons make the darkest pixels of the image.
You have to create a map from the physical sensor to the digital image. For the sake of simplicity, let's say we work with a grayscale image.
Your first task is to fix the colour bit-depth of the image. That is to say, is your image an 8-bit colour image? (Which usually is the case) If so, the brightest pixel has a brightness value = 255 (= 28 - 1, for 8 bits.) The darkest pixel is always chosen to have a value 0.
So you'd have to map from the range 0 --> 10,000 (sensor) to 0 --> 255 (image). The most natural idea would be to do a linear map (i.e. every pixel of the image is obtained by the same multiplicative factor from every pixel of the sensor), but to correctly interpret (according to the human eye) the brightness produced by n incident photons, often different transfer functions are used.
A transfer function in a simplified version is just a mathematical function doing this map - logarithmic TFs are quite common.
Also, since it seems like you're generating noise, it is unwise and conceptually wrong to add camera itself to the image img. What you should do, is fix a noise threshold first - this can correspond to the maximum number of photons that can affect a pixel reading as the maximum noise value. Then you generate random numbers (according to some distribution, if so required) in the range 0 --> noise_threshold. Finally, you use the map created earlier to add this noise to the image array.
Hope this helps and is in tune with what you wish to do. Cheers!

True Type Font Scaling

MSDN's truetype font article (https://learn.microsoft.com/en-us/typography/opentype/otspec160/ttch01) gives the following for converting FUnits to pixels:
Values in the em square are converted to values in the pixel coordinate system by multiplying them by a scale. This scale is:
pointSize * resolution / ( 72 points per inch * units_per_em )
where pointSize is the size at which the glyph is to be displayed, and resolution is the resolution of the output device. The 72 in the denominator reflects the number of points per inch.
For example, assume that a glyph feature is 550 FUnits in length on a 72 dpi screen at 18 point. There are 2048 units per em. The following calculation reveals that the feature is 4.83 pixels long.
550 * 18 * 72 / ( 72 * 2048 ) = 4.83
Questions:
It says "pointSize is the size at which the glyph is to be displayed." How does one compute this, and what units is it in?
It says "resolution is the resolution of the output device". Is this in DPI? Where would I get this information?
It says "72 in the denominator reflects the number of points per inch." Is this related to DPI or no?
In the example, it says '18 point'. Is this 18 used in computing the resolution or the pointSize?
Unfortunately, Apple's documentation is more or less the same, and other than that there are barely any resources other than just reading the source code of stb_truetype.
It says "pointSize is the size at which the glyph is to be displayed." How does one compute this, and what units is it in?
You don’t compute the point size, you set it. It’s the nominal size you want the font to be displayed in (think the font menu in a text editor). The ‘point size’ is a traditional typographical measurement system, with ‘point’ being roughly 1/72 of an inch. This brings the other question:
It says "72 in the denominator reflects the number of points per inch." Is this related to DPI or no?
No. Again, these are typographical points — the same unit you set the point size with. That’s why it’s part of the denominator in the first place: the point size is expressed in a measurement system of 72 points to an inch, and that has to be somehow taken into account in the equation.
Now, the typographical points are different from the output device’s dots or pixels. While in the early days of desktop publishing it was common to have a screen resolution of 72 pixels per inch that indeed corresponded to typographical system of 72 points per inch (no coincidence in that), these days the output resolution can, of course, vary quite dramatically, so it’s important to keep the point vs pixel distinction in mind.
In the example, it says '18 point'. Is this 18 used in computing the resolution or the pointSize?
Neither. It is the point size; see above. The entire example could be translated as follows. With a font based on 2048 units per em, if a particular glyph feature is 550 em units long and the glyph gets displayed at the size of 18 points (that is, 18/72 of an inch) on a device with screen resolution of 72 pixels per inch, the pixel size of that feature will be 4.84.
It says "resolution is the resolution of the output device". Is this in DPI? Where would I get this information?
It’s DPI/PPI, yes. You have to query some system API for that information or just hardcode the value if you’re targeting a specific device.

Size in MemoryRequirements not what I'm expecting

I'm creating a texture, querying the memory requirements, and it's not what I was expecting. Here's the ImageCreateInfo structure:
ImageCreateInfo()
.X2D(1024, 1024)
.Format(Format::R8G8B8_UNORM)
.InitialLayout(ImageLayout::PREINITIALIZED)
.Tiling(ImageTiling::LINEAR)
.Usage(ImageUsageFlagBits::TRANSFER_SRC);
Now, I was expecting one byte for each of R,G,B, at width and height of 1024 to give memory requirements of 3 * 1024 * 1024 = 3,145,728. But instead, it returns 1,048,576, which is perfectly 1024 * 1024. It seems to not care about the one byte for each channel of RGB. What am I missing here?
You're right in that this should return 3,145,728 bytes, but is the R8G8B8_UNORM format actually available on your implementation? If not, you won't get a correct allocation size because you actually are not going to be able to use that image anyway.
If you enable validation layers this should throw an error from the image validation layers btw.
At least on the GPU I'm right now it's not supported for any of the tiling modes or as a buffer format. But e.g. R8G8B8A8 or R8G8 are available and return the correct allocation size.
If R8G8B8 is actually available on your GPU could you post your complete VkImageCreateInfo structure, including number of mips and layers?
So a good idea would be to check if the image format you request (and want to allocate for) is actually supported for your use case (linear, optimal, buffer).

How should I tile images for CATiledLayer?

I know how to tile images, I just don't get how the images should turn out, with sizes and stuff..
The names should be Image_size_row_colum, and one of the Apple tiles images is:
Lake_125_0_0.png
I use TileCutter to tile the images, but I don't know if I should tile my original image to 512x512px, and then make a worse resolution image of the original from ≈7000x6000 to ≈5000x4000 and then tile that image to 512x512px or whatever.. I just don't get the whole setup..
The class reads images like this:
NSString *tileName = [NSString stringWithFormat:#"%#_%d_%d_%d",
imageName, (int)(scale * 1000), row, col];
And with the first of apples tiles are named Lake_125_0_0.png, that gives me nothing.. I just don't get it.. Anyone?
Thanks.
the tiles are by default always 256 to 256 pixels (although in the apple example some tiles at the border of the image got cropped).
Lake_1000_1_2: full resolution tile at scale 1, row 1, col 2.
Lake_500_1_2: half resolution: the tile is also 256 to 256 pixel but you show an area of the image which is actually 512 to 512 pixels (so you loose quality)
Lake_250_1_2: quarter resolution
Lake_125_1_2: show 8*256 to 8*256 pixels of the original image inside a 256 to 256 pixels tile
I hope this helps.