Upcoming features in v1.3

47 views
Skip to first unread message

Magnus Wrenninge

unread,
Jun 24, 2011, 2:49:08 PM6/24/11
to field...@googlegroups.com
Hello everyone,

We're doing some work to bring back the latest production code to the
main repository, as well as add some new features in what will become
v1.3.

We would love to get your input to make sure that that interface we
create is complete enough to serve everyone's purposes. Please respond
with your questions and comments. I will most likely add a v1.3 branch
to the GitHub repository in the coming weeks, so the code will be
available then, but we won't move the master branch for a while.


* Extending MatrixFieldMapping.
FieldMapping has always had both time- and nontime-dependent
transform calls. But so far the matrix mapping did not use
time in its calculations.
> virtual void worldToVoxel(const V3d &wsP, V3d &vsP) const = 0;
> virtual void worldToVoxel(const V3d &wsP, V3d &vsP, float time) const = 0;
We are adding a second setLocalToWorld call that lets you specify
a time sample as well.
> void setLocalToWorld(const M44d &lsToWs);
> void setLocalToWorld(float t, const M44d &lsToWs);
Field3D will make no assumptions about what the time represents,
the valid range will be [-inf,inf], but here we are letting time represent
offset from current frame start. So forward motion blur would sample
[0,0.5], centered blur would sample [-.25,.25], etc (assuming 180
degree shutter).
v1.3 will be able to read .f3d files from earlier versions of the library
but fields written out with MatrixFieldMapping in v1.3 will not be
readable in earlier versions.

* Adding a frustum mapping class.
Up until now we've had a custom plugin for frustum buffers
specific to our volume renderer, but we wanted to include a
generic one with Field3D, partly to share between different
in-house apps, but also to make Field3D more feature-complete.
The interface for specifying the frustum buffer will be similar to
the matrix mapping, and it will support temporally varying transforms,
which are required to handle moving cameras.
> void setTransforms(const M44d &ssToWs, const M44d &csToWs);
> void setTransforms(float t, const M44d &ssToWs, const M44d &csToWs);
There will be support for two types of Z slice distributions:
* Uniform - equal distance in world space depth.
* Perspective - equal distance in screen space depth.

* Removing the iterator-based transforms in FieldMapping
> virtual void voxelToWorld(std::vector<V3d>::const_iterator vsP,
std::vector<V3d>::const_iterator end,
std::vector<V3d>::iterator wsP) const = 0;
These were originally added with the assumption that they would
optimize away virtual function calls. It has turned out not to be needed
and we felt that they were cluttering the interface.

* Removing the use of typeid()
Field3D already had an RTTI replacement to facilitate safe downcasting
of field types across DSO boundaries. We recently had to use Field3D
in an LLVM-based app, which requires RTTI to be turned off,
so we changed the internal implementation of field_dynamic_cast to
not use typeid(). This should not break existing code, but it may
make life easier for anyone integrating Field3D into a non-RTTI environment.

Alexis Angelidis

unread,
Jun 25, 2011, 6:28:08 AM6/25/11
to field...@googlegroups.com
Hi Magnus,
question about changes to MatrixFieldMapping:
is this to differentiate between motion of local space due to voxels appearing/disappearing on the boundary vs. the voxels actually moving? I.e. the former is ignored for motion blur, as opposed to the latter; it would be useful to have functions to track the motion of local spaces,

cheers,


--
You received this message because you are subscribed to the Google Groups "Field3D dev" group.
To post to this group, send email to field...@googlegroups.com.
To unsubscribe from this group, send email to field3d-dev...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/field3d-dev?hl=en.


Magnus Wrenninge

unread,
Jun 25, 2011, 8:34:34 PM6/25/11
to field...@googlegroups.com
The time-dependent transform calls on the Mapping objects are only there to account for buffers that move as a whole. An example would be if you had a fluid sim parented to a moving car, plane, etc. In that case, if the camera is moving along with the buffer, you want motion blur to cancel out; if the camera is stationary the voxel buffer will move in relation to the camera and cause motion blur. This is all independent of the motion of the actual fluid (i.e. the velocity field of the sim). Does that address what you mean by the motion of the local space?

Magnus

Alexis Angelidis

unread,
Jun 27, 2011, 7:12:44 AM6/27/11
to field...@googlegroups.com
is it true the assumption is the velocity must be defined in F3d-world space? (as opposed to definition in F3d-local space which require some meta info to support simultaneously varying resolution with moving space)

Magnus Wrenninge

unread,
Jun 27, 2011, 12:54:11 PM6/27/11
to field...@googlegroups.com
I don't think you need to assume anything about the velocity values.
If you want to define them to be in local space, that's fine. I don't
think there's anything in the library that requires them to be in
world space. For example, all MAC fields are implicitly oriented to
the local space, although we usually express the magnitudes as
world-space.

Regarding having resolution vary with time: Are you trying to account
for this in in-frame motion blur?

The idea with the temporally varying mappings is just to support
motion of the field as a whole. I.e., you would add a localToWorld
matrix time sample at t=0 and t=0.5 (or t=0.5*dt, depending on
renderer conventions) for forward motion blur and 180 degree shutter.
It does assume that the resolution of the field is constant over the
current frame. But it doesn't assume that the resolution is constant
frame-to-frame.

Magnus

Alexis Angelidis

unread,
Jul 4, 2011, 7:26:41 PM7/4/11
to field...@googlegroups.com
I'm trying to understand if there is a conventional way to tell if local space was changed due to resolution variation or local space transformation by just looking at the files.
Below is two examples producing the same files.

Let's take two files f0 f1 with 2x2x2 voxels and local to world transformations M0 M1
with M0 = 
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1

Now consider cases A and B, both with zero velocities defined in F3d-local space:
A. If the voxels are attached to a coordinate system moving by 0.5 in x, then

M1 = 
1 0 0 0.5
0 1 0 0
0 0 1 0
0 0 0 1

B. If a slab of voxels is added in +x and removed in -x, then

M1 = 
1 0 0 0.5
0 1 0 0
0 0 1 0
0 0 0 1

I think that in both cases the f3d file is identical (unless this is where I'm missing something) but in the first case the transformation T = M1 . M0^-1 must taken into account for motion blur, as opposed to the second case.

Thanks for any info!

Magnus Wrenninge

unread,
Jul 4, 2011, 8:10:07 PM7/4/11
to field...@googlegroups.com
Hi Alexis,

The files would be different in one respect: B would have extents and data window: (1,0,0)-(2,1,1) whereas A's would be (0,0,0)-(1,1,1). Or at least, I would expect them to change if you did remove and add slabs of voxels.

You can't decide for sure by looking at two localToWorld transforms if the field is moving (for the exact reason your example illustrates). This is the reason for using multiple time samples in a single Mapping (i.e. time-varying), so that motion is clearly expressed, instead of looking at the transform in two separate files and attempting to interpolate. In your case, it would be possible to distinguish that A and B are different since the extents are different, but it's not quite how we intended for motion blur to be expressed.

Think of it as having motion vectors on geometry instead of loading the next geometry file and differentiating/interpolating. You also gain the ability to do multi-sample motion blur.

So essentially, to solve your problem: When motion blurring a moving buffer, all of the time samples for the motion should be available in one single .f3d file. That is, the intent of time-varying Mappings is to allow for the full motion to be described, instead of having to look at the transform of the following frame's .f3d file. If there is only one time sample in the file, the buffer does not move.

Which is what I mentioned in the previous email about varying resolution. Within a single frame, resolution does not vary (but the transform can). Between two frames, resolution can change (as well as the transform), but the intent is not to compute motion blur based on the transform on the following frame, but rather on the multiple time samples stored in a single file.

So in example A, you would do:
  MatrixFieldMapping mappingFrame1;
  mappingFrame1.setLocalToWorld(0.0, M0); // First sample
  mappingFrame1.setLocalToWorld(1.0, M1); // Second sample, now there's motion
  /* Write to disk, etc*/
  MatrixFieldMapping mappingFrame1;
  mappingFrame1.setLocalToWorld(0.0, M1);
  mappingFrame1.setLocalToWorld(0.0, M2);
  ...

And in example B:
  MatrixFieldMapping mappingFrame1;
  mappingFrame1.setLocalToWorld(0.0, M0); // Single sample, no motion
  /* Write to disk, etc*/
  MatrixFieldMapping mappingFrame2;
  mappingFrame2.setLocalToWorld(0.0, M1); // Single sample, no motion

Your example B does touch on the concept of boundless voxel buffers, where no explicit bounds exist and the domain grows as required when voxels get written to. However, the basic Mapping in Field3D is not intended to handle those. But I think you can work around it fairly cleanly by using the approach above, where you indicate with multiple time samples in a single Mapping that there is motion.


Hope that helps! 

Magnus

Alexis Angelidis

unread,
Jul 8, 2011, 3:43:34 AM7/8/11
to field...@googlegroups.com
Thanks for the examples of setLocalToWorld. If I understand correctly, I can handle resolution variation and space transform simultaneously either by (1) setting adequatly extents and datawindow or by (2) keeping track externally of a matrix part for resolution variation Ri and a matrix part for local space transformation Ti, such that M1 = R1 . T1 . M0 and :
  mappingFrame1.setLocalToWorld(0.0, M0);
  mappingFrame1.setLocalToWorld(1.0, T1 . M0);

I agree about your point on not loading multiple geometry to compute motion blur. Have you considered a third alternative of using a matrix that provides velocities instead of a spline of matrices (3) ?

  mappingFrame1.setWorldVelocity(V1) 

with V1 = log(T1 . T0^-1) / dt , this alternative removes the need for a matrix spline,
cheers,

Magnus Wrenninge

unread,
Jul 16, 2011, 12:13:31 PM7/16/11
to field...@googlegroups.com
Hi Alexis,

Sorry for the slow reply, I've been out for a few days.
We did consider a world velocity vector, but that wouldn't allow
multi-segment motion blur, or rotational motion blur, unless I
misunderstand what you mean.

Magnus

On Fri, Jul 8, 2011 at 12:43 AM, Alexis Angelidis

Alexis Angelidis

unread,
Jul 16, 2011, 8:39:39 PM7/16/11
to field...@googlegroups.com
Yes, translational rotational and scale motion blurs can be specified with a matrix log.
The rotational velocity can be evaluated at any point by log(R) . p

Is it beneficial to separate multiseg for either fields and world transform? If velocity is specified in multiseg in the scalar fields, then each field should have its own transform, right?

Magnus Wrenninge

unread,
Jul 18, 2011, 2:47:36 PM7/18/11
to field...@googlegroups.com
I see, I had to read up a bit on matrix logarithms. If we were to use
it, what are its main merits? Is it more efficient than interpolating
the 16 floats of a matrix?
Do you have any examples of software where it's being used in this way?

Rob Pieke

unread,
Jul 18, 2011, 3:00:52 PM7/18/11
to field...@googlegroups.com
Sorry if this is covered earlier in the thread ... I'm trying to catch up :)

Depending on how the matrix is constructed (Trans * Rot vs Rot * Trans), just blending the 16 floats for two matrices could give _very_ strange results. You might want to decompose the matrix into Rot/Trans/Scale, interpolate those, and recompose the resulting matrix.

Or use quaternions :)


________________________________________
From: Magnus Wrenninge [magnus.w...@gmail.com]
Sent: 18 July 2011 19:47
To: field...@googlegroups.com
Subject: Re: Upcoming features in v1.3

Alexis Angelidis

unread,
Jul 18, 2011, 5:40:10 PM7/18/11
to field...@googlegroups.com
The matrix log would be quite efficient for gridless advection, or any other process using velocity in-between files, and also efficient for baking local space velocity in the voxels (v = M . p ). I don't know how much it's used, and suspect not much.

I can see your point, and how the interpolation of matrices is an advantage for multisegging the motion for example with a PRman motion block. With a motion block, the interpolation happens outside of Field3d, and setLocalToWorld becomes essentially a way to store and order matrices. I suppose Field3d also provides a matrix interpolant with particular properties, e.g. simple and linear? (or something else as mentioned by Rob P.)

Thanks for all this info,

Magnus Wrenninge

unread,
Jul 18, 2011, 6:49:30 PM7/18/11
to field...@googlegroups.com
The idea is that whoever writes the data is responsible for adding a
sufficient number of samples to express the motion. Since only two
will be used for interpolation, it doesn't actually make it more
costly to interpolate between 16 samples than say 2. We want to avoid
the explosion of every possible breakdown of matrices and other
storage options and instead provide a simple, common way of specifying
transforms, and then leave it up to the client to figure out what to
do with those samples.

MatrixFieldMapping provides linear interpolation. It would be possible
to add others, but once again we get into trying to support everything
everyone wants. I think if a particular application requires something
special, with curved rotational interpolation etc, the cleanest way to
do so would be to, upon load, read the samples from
MatrixFieldMapping, create CustomMapping, and the assign that to the
field. And vice versa on write. I don't think the use of linear
interpolation in MatrixFieldMapping is too much of a stretch, as that
covers what both PRMan and Arnold do internally.

Basically, Field3D on disk makes no assumptions about neither time nor
interpolation of the matrices. The MatrixFieldMapping gives a library
user the very simplest interpolation possible (linear).


Magnus


On Mon, Jul 18, 2011 at 2:40 PM, Alexis Angelidis

Magnus Wrenninge

unread,
Nov 20, 2011, 2:37:08 AM11/20/11
to field...@googlegroups.com
Hello everyone,

We've finally started the process of committing the latest production code from Imageworks back to the GitHub repository. Only a little later than planned... *cough*.

If you are interested in trying out the latest code before it is released and becomes the 'master' branch you can check out the 'v1.3' branch on GitHub.
It will be updated as individual features are completed.

A milestone has been created if you are curious about what features will be in v1.3.0.

There have been changes to how Field3D files are structured (mostly due to changes in MatrixFieldMapping), but v1.3 will be backwards compatible with files created using v1.2, although not vice versa.


Magnus
Reply all
Reply to author
Forward
0 new messages