Jump to content
Sign in to follow this  
hoknamahn

Thoughts about inconsistency of "volumes" in Houdini and how

Recommended Posts

Hi guys,

Last couple of days I spent in thinking about volumetric data, tools for generation of volumetric data, contexts for working with volumetric data (image3d context, 3D Texture Generator ROP, Mantra volume primitives, Volume SOP, Volume VOP SOP, scalar and vector fields in DOPs, force fields and so on) in Houdini and found them inconsistent. I'll explain why...

First of all what context is?

1. Contexts are parts of Houdini which have different properties and made for different purposes.

2. Context defines a type of data you work with. Pretty similar to parameters of functions and type of result in programming languages. For example in SOPs we have vertices, points, primitives and so on as input parameters and type of result which SOP context returns is GDP (object consists of geometry).

2. Context defines global variables available for our "tools" (i.e. VEX functions, Operators, scripts). For example, P, v and so on.

3. Context is an engine which has different methods for generation of variables. We can use surface context in Mantra and image3d in 3D Texture Generator ROP as examples. And probably is a good idea to add to them Volume Mix SOP (Yes, in this post I will mix different kinds of contexts: Operation contexts like SOP, POP, ROP etc., contexts defined by operators like Volume VOP SOP or Volume Mix SOP, shading contexts like surface and image3d contexts. They are different but idea is pretty similar) So come back to our Mantra surface context, image3d context and context defined in Volume Mix world. If we take a look at P variable we can see that methods used for generation of P by those contexts are different. Mantra uses position on surface (and this is depends on sampling rate, on using algorithm - raytracing or micropolygons) while image3d context or Volume Mix SOP (I mean it's $X, $Y, $Z variables) do loop through centers of voxels inside 3d grid (and thus P depends on the resolution of that grid)

4. Context defines types of tools and methods how those tools work with context specific data.

So we have all those contexts because they have differences in types, tools and purposes. Let's take a look what do we have for work with volumetric data... Houdini < 9.0 had only image3d context and 3d textures. Since Houdini 9 we have image3d context/i3d textures, volume primitives (with tools for creation of volumes: Iso Offset SOP, Volume SOP, Volume Mix and finally the volume beast Volume VOP SOP), in DOPs we have scalar and vector fields. What I don't like:

1. Volume VOP SOP. It's not only SOP. It's context in context. It defines a "volume" context for VEX code and VOPs, it is a subnetwork for VOPs (we are already have VOP subnetworks in SOPs and they are really cool and helpful. But this one looks a bit superflous). And all this stuff is inside SOPs like a parallel universe. As for me this SOP is more crazy and inconsistent than Particle SOP. The programming truth says "If function does too much probably better to split it into several less complex functions".

2. In mathematical sence field is a function defined in continuous space (even if some functions have breaks in different areas they just "not defined" or "not exist" but the space is still continuous). I'd like to have those defined in continuous space fields. I'll tell why later.

3. Volume primitives are scalars. Yes, vector or matrix can be represented by scalars but anyway it's not so conveniently.

4. We have very different instruments/methods for similar things. For me the only difference between Volume Primitive used in SOPs / POPs / DOPs / Mantra and so on, force fields in POPs and DOPs, density fields in DOPs, i3d textures generated by 3D Texture Generator ROP is the format of data and type of data u can store. All of them have same dimension, they have resolution (i.e. they store data in voxels) and so on. Yep of course I understand that Volume primitive is a primitive while i3d texture is texture. So if you pass volume primitive to Mantra it will do everything necessary for rendering of volumetrics. But if you use volume primitives or i3d textures for sampling of some data they are completely the same (even if they have different formats, functions for sampling and different features). So I don't like to have too many similar tools.

How I see a "perfect" solution. Imagine Field Operator context (FOPs). In this context you work on fields of different types (and ideally in different dimensions. but for simplicity we can stop on 3d case). This context allows to create _fields_, modify them by FOPs (which are like SOPs, POPs and so on but very specific and oriented on work in volume), by FOP VOPs and FOP VEX operators. This context creates specific global variables and space in this context is "continuous". This context is useless by itself but we can and we will use fields (which are in reality templates) defined in FOPs for sampling of function. So if you define MySinField as f(sin(x)) in FOPs you could sample it in POPs as force field or in DOPs as grid based fluid or bake it onto the disk. In FOPs field doesn't have resolution but final result in POPs, SOPs or DOPs has. That's why I call them "templates". And here FOP context looks pretty similar to image3d. But it is "live" context. You define a "template field" and then you have ability to do sampling from it directly (without baking onto disk). Even "viewport" could sample this template field to render it. Also several subnets could sample same "template field" but using different sampling rate. Pipeline could look like FOPs (define field template using fancy tools) -> Sample function from this field in _any_ subnetwork (even in other FOP subnet) with any resolution or bake it onto disk as i3d texture (because sampling in live mode can be very expensive). In this case we can forget about Volume SOP / Volume Mix SOP and so on and could use a bit extended Object Merge SOP (and similar things in DOPs, POPs etc) or something like Merge Field SOP. Next step is how to use this on Mantra side. We can bake field into i3d texture and then use proper procedural for generation of volume primitive or generate volume primitive directly from "template field" using same idea as in HScript instancing.

I'm not sure is it clear for you guys but hope so. SideFX does fantastic job but I think there is always couple of ways to make a software better. What do you think?

P. S. I don't think this is easy to implement or this could be done in one or two years. I just like to hear what do you think about this idea.

P. P. S. I believe the choice of programming language has the same influence on development as 3d software on effects. What do you think guys (Edward, Mark and other guys from SideFX) about modern ideas in programming and about pretty old ones (like functional programming) which are very popular in academic world but not too much in "real" production? Could changing of programming language help to make software better?

Edited by hoknamahn

Share this post


Link to post
Share on other sites

Not a proper feedback probably, but here's my 2 kopejka's:

- I find FOPs potentially useful in many areas - it is a layer of math abstractions that can find usage in numerous applications.

- - Just think of our own space (not CG - reality!) as a continuous space filled with varying densities of matter/energy. It is basically same function space and functions. It could be a new (not really, but anyways) way to generate data (geometry/volumes/point clouds) - in a way similar to Terragen for example (as I perceive it working - I may be wrong about it's mechanics of course).

- Similar to CHOPs - it is just a clean way to generate some data and pipe it into other contexts. That will help keeping "houdini code" clean and logical - without further rapping contexts into sub-contexts, etc...

- it would be something that hasn't been implemented by competing 3D packages yet, so it could be a significant step of SideFX, pushing mainstream CG industry even further.

P.S. here whenever I use 'data' - I understand it as a synonym to 'data field' or just 'field'.

Cheers,

Vlad

Share this post


Link to post
Share on other sites

Since you can't "store" a purely symbolic function, I think what you're suggesting is closer to the concept of a "shader" -- i.e: the shader (or CVEX function or whatever) operates on continuous space and the discretization is done by the caller, which chooses how to carry out the sampling (point samples, integrals, whatever) based on some context-related criteria.

So this hypothetical FOP returns a state vector of arbitrary dimension (and of arbitrary meaning) as a function of time and n-dimensional P. But this is pretty much exactly what DOPs are (for dim(P)=3), where the "caller" is a solver... so, unless I misunderstand, I think we already have FOPs.

What I think you're really suggesting then is not so much a new context, but a unification of the various volume/field representations currently available, and a unified query language for this single representation from any context, including VEX... and I have to agree that this would be a GoodThing :)

Share this post


Link to post
Share on other sites

Hey,

As i was typing the reply Mario and Madjestic kinda answered already

It's funny you raise this question and propose to solve it that way because i had similar thoughts lately.

How it happened is a while ago i asked myself the question: "what is this CVEX thing, why not another vex context", and i came across the definition in the documentation : CVEX = "vex that executes outside of contexts!"

Bingo! I think we're getting a rich idea here:

I think we should rethink the contexts and VEX/VOP could be defined out of contexts and the bindings would determine where it is executed ( by binding i mean global parameters and outputs: that's how it's more or less working with the volume VOPSOP).

The compilation would tell you if you could use this code in SOPs or in rendering or in COPs, depending on some of the functions you use that only make sense in some contexts and not in others and you would have "vex callers" in different contexts

There's a lot of cool things we could do with this:

ranging from using the same code for surface shaders and displacement shaders ( skipping variables exports) to baking a shader to geometry (surface/volumes, either GLSL or on vertices) or baking to COPs !! (i'm not a hardware specialist at all but shouldn't this unification be reflected in a unified SIMD hardware- it was more or less the idea at nVidia, no, to render with graphic cards?), or even bake volume to i3d, whatever you want really, the things you mentioned would be a subset of this!

Instead of having several VEX/VOP contexts for 90% of the functions that are similar, why not have one UNIQUE VEX context with bindings. I mean, after all, Vex contexts are a redundancy, no!, and with this we're getting THE VEX UNIFICATION ! :)

So CVEX ( from what the definition says at least) corresponds to your FOP!

I think that's the underlying idea of it, and it would be cool to have this pushed further ( i haven't thought of the limitations of this approach yet, there may be some big ones. Question is: are contexts similar enough for this to work).

hope i was clear

-d

Edited by David Gary

Share this post


Link to post
Share on other sites
Since you can't "store" a purely symbolic function, I think what you're suggesting is closer to the concept of a "shader" -- i.e: the shader (or CVEX function or whatever) operates on continuous space and the discretization is done by the caller, which chooses how to carry out the sampling (point samples, integrals, whatever) based on some context-related criteria.

So this hypothetical FOP returns a state vector of arbitrary dimension (and of arbitrary meaning) as a function of time and n-dimensional P. But this is pretty much exactly what DOPs are (for dim(P)=3), where the "caller" is a solver... so, unless I misunderstand, I think we already have FOPs.

Yep Mario, 99% (???) correct! :rolleyes: 1% for DOPs... Correct me if I wrong but the resolution of field (not the resolution of processing of that volume but that 3d grid) in DOPs is a constant and doesn't dependent on solvers. So what if I want to merge a field (it has resolution [x, y, z]) from dopnet1 into /obj/geo1 with resolution [x1, y1, z1] and merge the same field but with resolution [x2, y2, z2] into... /obj/popnet6? Also... What about fields driven not by "pure" functions but by hands (some kind of Haskell "monads")? For example hypotetic 3d field brushes?

What I think you're really suggesting then is not so much a new context, but a unification of the various volume/field representations currently available, and a unified query language for this single representation from any context, including VEX... and I have to agree that this would be a GoodThing :)

Yes it's true we already have several solutions which do something in nonunified and weird way. They need to be improved. The reason to start to think about FOPs was ability to create a wide range of tools: VEX based generators / filters, brushes and so on. And I'm not sure can they fit into existing ideology.

Edited by hoknamahn

Share this post


Link to post
Share on other sites
Hey,

As i was typing the reply Mario and Madjestic kinda answered already

It's funny you raise this question and propose to solve it that way because i had similar thoughts lately.

How it happened is a while ago i asked myself the question: "what is this CVEX thing, why not another vex context", and i came across the definition in the documentation : CVEX = "vex that executes outside of contexts!"

Bingo! I think we're getting a rich idea here:

I think we should rethink the contexts and VEX/VOP could be defined out of contexts and the bindings would determine where it is executed ( by binding i mean global parameters and outputs: that's how it's more or less working with the volume VOPSOP).

The compilation would tell you if you could use this code in SOPs or in rendering or in COPs, depending on some of the functions you use that only make sense in some contexts and not in others and you would have "vex callers" in different contexts

There's a lot of cool things we could do with this:

ranging from using the same code for surface shaders and displacement shaders ( skipping variables exports) to baking a shader to geometry (surface/volumes, either GLSL or on vertices) or baking to COPs !! (i'm not a hardware specialist at all but shouldn't this unification be reflected in a unified SIMD hardware- it was more or less the idea at nVidia, no, to render with graphic cards?), or even bake volume to i3d, whatever you want really, the things you mentioned would be a subset of this!

Instead of having several VEX/VOP contexts for 90% of the functions that are similar, why not have one UNIQUE VEX context with bindings. I mean, after all, Vex contexts are a redundancy, no!, and with this we're getting THE VEX UNIFICATION ! :)

So CVEX ( from what the definition says at least) corresponds to your FOP!

I think that's the underlying idea of it, and it would be cool to have this pushed further ( i haven't thought of the limitations of this approach yet, there may be some big ones. Question is: are contexts similar enough for this to work).

hope i was clear

-d

I was thinking about unification of VEX because of chains of shaders in MentalRay. But I'm not sure I got your idea. Who has to define context specific things? Now this sort of things do SOPs, POPs, Mantra etc. Or idea is to change any VEX shader from

surface shadername() {}

to

shadername() {}

or to define the entry point of shader like

main = shadername() {}

to make possible to run shader in any context and hope that context in which you'd like to run current shader is able to give all necessary variables? It's close to unification but this unification lies on shoulders of shaderwriter (or user). What if I try to use a unified shader (which is using L) in SOPs? Sounds like semiunified solution :lol: Well we need a switch "Strict / Non-strict VEX".

So CVEX ( from what the definition says at least) corresponds to your FOP!

I thought FOPs could be work environment. Not just a function. But yes if forget about different tools, visualisatios and so on and leave pure mathematics such CVEX shader can be called "FOPs".

Edited by hoknamahn

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×