RenderKit / ospray

An Open, Scalable, Portable, Ray Tracing Based Rendering Engine for High-Fidelity Visualization
http://ospray.org
Apache License 2.0
1.02k stars 186 forks source link

Documentation questions #290

Closed paulmelis closed 5 years ago

paulmelis commented 5 years ago

Sorry for the list of (direct) questions, but I was reading the docs somewhat more closely and was wondering about the points below:

Data

OSPData ospNewData(...., const void *source, const uint32_t flags=0)

The flag OSP_DATA_SHARED_BUFFER indicates that the buffer can be shared with the application. In this case the calling program guarantees that the source pointer will remain valid for the duration that this data array is being used.

So by implication that means that not using the OSP_DATA_SHARED_BUFFER flag means that the ospNewData call makes a copy of the source data and source can therefore be freed directly after the call?

Table 5: Valid named constants for OSPDataType.

OSP_FLOAT3A ... and aligned 3-element vector

Aligned to a 4, 8, 16, ... byte boundary?

Volumes

float, samplingRate, 0.125, sampling rate of the volume (this is the minimum step size for adaptive sampling)

What exactly is the unit of this value, is it related to world-size, cell-size, volume bbox, ...?

Structured Volume

Such a volume type is created by passing the type string "shared_structured_volume" to ospNewVolume. The voxel data is laid out in memory in XYZ order ...

Does "XYZ order" mean that the X coordinate iterates the slowest when traversing the volume in memory?

I.e. idx(x,y,z) = x*(NY*NZ) + y*NZ + z instead of the slightly more common idx(x,y,z) = z*(NX*NY) + y*NX + x?

Transfer Function

One type of transfer function that is built-in in OSPRay is the linear transfer function, which interpolates between given equidistant colors and opacities.

Table 10: Parameters accepted by the linear transfer function.

vec3f[] colors data array of RGB colors float[] opacities data array of opacities vec2f valueRange domain (scalar range) this function maps from

I assume the first entry in the TF is aligned with valueRange.x and the last entry with valueRange.y?

Triangle Mesh

Table 11. Parameters defining a triangle mesh geometry.

vec4f[] / vec3fa[] vertex.color data array of vertex colors (RGBA/RGB)

Similar questions for the aligned vec3f as with the OSP_FLOAT3A type, aligned on what boundary?

Table 19: Parameters understood by all renderers.

int, spp, 1, samples per pixel

Even though it's a common parameter, is it applicable to be to the scivis renderer?

And when using ospRenderFrame with a OSP_FB_ACCUM framebuffer is the spp value used at all, or does each rendered frame then have 1 sample-per-pixel?

Perspective Camera

The perspective camera implements a simple thinlens camera for perspective rendering, supporting optionally depth of field and stereo rendering, but no motion blur.

Motion blur is mentioned a few times, but always as "not supported", so what motion blur support is there in OSPRay? :)

Note that when setting the aspect ratio a non-default image region (using imageStart & imageEnd) needs to be regarded.

Hmm, don't quite get what is meant here?

Finally a question on thread-safety of the API itself. This is only described in relation to the scenegraph, but are OSPRay API calls thread-safe in general?

jeffamstutz commented 5 years ago

Hi,

We are always happy to answer question...no worries! :)

So by implication that means that not using the OSP_DATA_SHARED_BUFFER flag means that the ospNewData call makes a copy of the source data and source can therefore be freed directly after the call?

Yes.

Aligned to a 4, 8, 16, ... byte boundary?

It really means a vec3f that occupies a vec4f amount of memory (i.e. the w component of a vec4f gets ignored). I've never really liked that name, as a vec3fa array really is just a vec3f + stride array.

What exactly is the unit of this value, is it related to world-size, cell-size, volume bbox, ...?

Cell size: it represents the average number of cells per-sample taken along the ray.

Does "XYZ order" mean that the X coordinate iterates the slowest when traversing the volume in memory? I.e. idx(x,y,z) = x(NYNZ) + yNZ + z instead of the slightly more common idx(x,y,z) = z(NXNY) + yNX + x?

No, it follows the common more common indexing scheme you mentioned: implemented here

I assume the first entry in the TF is aligned with valueRange.x and the last entry with valueRange.y?

Correct, the colors and opacities are applied based on valueRange.

Similar questions for the aligned vec3f as with the OSP_FLOAT3A type, aligned on what boundary?

Hopefully the description I gave earlier makes sense here (and why it says RGBA/RGB for vec4f/vec3fa in the documentation).

Even though it's a common parameter, is it applicable to be to the scivis renderer?

Yes, all of our renderers all respond to common parameters.

And when using ospRenderFrame with a OSP_FB_ACCUM framebuffer is the spp value used at all, or does each rendered frame then have 1 sample-per-pixel?

The spp parameter is essentially the same thing as looping over ospRenderFrame() N times. Thus the spp value is used, where each sample is accumulated as if the application repeatedly called ospRenderFrame().

Motion blur is mentioned a few times, but always as "not supported", so what motion blur support is there in OSPRay? :)

Currently none...we demoed new Embree motion blur features (via custom OSPRay extensions) at SIGGRAPH 2017, but the features never ended up in an OSPRay release. We haven't had users ask for motion blur, so we haven't prioritized it. However, you could implement your own motion blur mesh as an OSPRay geometry which just forwards multiple vertex arrays to Embree. I think our renderers would take that just fine...but if not I don't think it would be difficult to do so. IIRC, this is how we implemented the Embree demo back then.

Hmm, don't quite get what is meant here?

Not sure, @johguenther?

Finally a question on thread-safety of the API itself. This is only described in relation to the scenegraph, but are OSPRay API calls thread-safe in general?

We make no guarantees about API thread safety, though you certainly can get away with some things. The way we do this in the scene graph is through specified tree traversals (e.g. commit, render, etc.), where each traversal does a single operation, such as commit all the underlying objects. In ospExampleViewer (now deprecated in favor of OSPRay Studio), we have a background thread which renders frames, but does all the object commits as necessary between frames. It's not super difficult to implement in application space, so we want to avoid that complexity behind the API unless it's absolutely required.

However, OSPRay 2.0 will introduce some asynchronous API calls, mainly ospRenderFrame(). However, that is different than the thread safety of the API itself (i.e. multiple application threads calling the API).

What I know today would not work:

...everything else is "undefined behavior" and may or may not work.


We will take this feedback and try to improve our documentation in the future...thanks for these, and let us know if anything is still unclear!

Cheers, Jeff

paulmelis commented 5 years ago

Hi Jeff, thanks for the quick answers. Two small additions:

Aligned to a 4, 8, 16, ... byte boundary?

It really means a vec3f that occupies a vec4f amount of memory (i.e. the w component of a vec4f gets ignored). I've never really liked that name, as a vec3fa array really is just a vec3f + stride array.

Hmm, that's surprising, I was really expecting alignment on a memory boundary. Maybe the AlignedAllocator stuff in the sources threw me off. So there is no requirement of aligning to a memory boundary for any data in OSPRay?

Even though it's [spp] a common parameter, is it applicable to be to the scivis renderer?

Yes, all of our renderers all respond to common parameters.

I tried setting spp to 1024 and saw no slowdown in a scivis render. I now see what I did wrong: I used ospSet1f instead of ospSet1i.

johguenther commented 5 years ago

Re perspective camera: when you crop/enlarge the image region using imageStart and imageEnd (which default to [0..1]) then the aspect has to be set accordingly to avoid a distorted image. It could then be that the correct aspect is not simply framebuffer width by height, but rather framebuffer aspect multiplied by image region aspect.

ingowald commented 5 years ago

On 12/12/18 2:09 PM, Paul Melis wrote:

Hi Jeff, thanks for the quick answers. Two small additions:

    Aligned to a 4, 8, 16, ... byte boundary?

It really means a vec3f that occupies a vec4f amount of memory
(i.e. the w component of a vec4f gets ignored). I've never really
liked that name, as a vec3fa array really is just a vec3f + stride
array.

Hmm, that's surprising, I was really expecting alignment on a memory boundary. Maybe the |AlignedAllocator| stuff in the sources threw me off. So there is no requirement of aligning to a memory boundary for any data in OSPRay?

"Historically" the "A" in vec3fa referred to "SSE alignment"; i.e., 16 byte alignment. Reason for this is that on some architectures there were such alignment constraints for SSE loads, so if your array element wasn't a multiple of 16 you'd run into issues. Other architectures later on had similar constraints for 64-byte alignment, and though you obviously didn't want to blow each vec3f into 64 bytes of storage the 'vec3fa' type at least allowed to always process four vec3fa's together in 64-byte alignment, so this was once again very useful. So in a sense, the 'A' only means "whatever you provide as a base address, we'll guarantee the increments are 16 bytes".

And of course, for the internal vec3fa class that also came with automatic "attribute(align(16))"s that did force the alignment you suspected - exposing that to an API array data type was just a way of also carrying that over into array types, and allowing the user to tell us that "hey, I will guarantee that you can treat all of these array elements as (aligned) 'vec3fa's. (Quite funnily the vec4f never had similar explicit alignment guarantees - go figure).

As to the "it's only there for vec3fa": yes, the only thing where this really made sense is vec3f->vec3fa, hence no other data type has that. Today this alignment requirement is way less of an issue (though some older CPUs that require alignment are still running), but 16-byte alignment also implies 64-byte cache line alighment (and cheaper addressing math), so in some (admittedly rare) cases can still be useful.

Cheers,

Ingo

PS: Note that at the time when we heavily relied on this alignment we even guaranteed that the fourth component would always get copied but would never get overwritten, so you could even "abuse" it to store other values (eg, a 32-bit vertex color value, or a radius or color for a sphere particle), but I don't think we still guarantee that, so better not use that.

surfsara-visualization commented 5 years ago

Thanks for all the feedback and explanations!

One more I just noticed:

Ambient Light

Note that the SciVis renderer uses ambient lights to control the color and intensity of the computed ambient occlusion (AO).

Usually, one only has 1 ambient light, but it seems with OSPRay it's possible to have more (although I don't directly see a good use case). I assume the sentence means that the scivis renderer adds up light contributions from all ambient lights for computing an AO color of a sample, and not that the scivis renderer internally places ambient lights to influence AO in any way. The words "uses" and "control" used together are a bit vague.

johguenther commented 5 years ago

Right, all ambient lights get added up for AO, instead of having an "AO color/intensity" parameter for the SciVis renderer. (Essentially the same happens in the pathtracer: the illumination by ambient lights added, although not explicitly, thus there is a performance degradation when multiple ambient lights are placed in the scene).

paulmelis commented 5 years ago

Quad Light

The emission side is determined by the cross product of edge1×edge2.

Hmmm, as OSPRay uses a right-handed coordinate system, I would expect the emission to be in the opposite direction of the vector ending at position shown in the figure of the quad light. Or isn't that what the arrow shows? Reason I ask is that my local tests seem to suggest emission is happening in the other direction (or maybe I screwed up my math ;-))

johguenther commented 5 years ago

That vector is the position vector of the Quad light, not the emission direction; it is emitting towards the reader.

paulmelis commented 5 years ago

Okay, thanks for the verification, so I must be doing something wrong

paulmelis commented 5 years ago

I must be stupid, but can you check the attached example based on ospTutorial.c? Planar geometry (2 tris) in the XY plane at Z=0, camera at Z=2 looking down the -Z axis, quad light at Z=10 with edge1=(0,5,0) and edge2=(5,0,0). That should give edge1 x edge2 = (0,0,-25), i.e. light shining down the -Z axis. But I'm not seeing any colored geometry in the render unless I swap edge1 and edge2.

quadlight.zip

johguenther commented 5 years ago

Thanks for thoroughly checking: this is indeed a bug in the Quad light (edge1 and edge2 get swapped when passed as parameters). This will get fixed in a next release.

paulmelis commented 5 years ago

Argh, and I even checked that code pretty carefully, but missed the argument swapping in QuadLight_set's parameters :smile:

johguenther commented 5 years ago

All mentioned issues should be addressed in the latest v1.8 release.