VEXGoryDetails
From Odwiki
Here is some more technical information on VEX which advanced users might find useful.
Contents |
SIMD
Mantra and Houdini execute VEX in a SIMD fashion. SIMD means "Single Instruction, Multiple Data". This means that each instruction is run for a bunch of points before the next instruction is run. VEX code like:
surface foo() {
printf("S = %g\n", s);
printf("T = %g\n", t);
}
may not produce results that you'd expect since the first printf() statement is run for all the points being processed, then the second printf() statement is run. SIMD is an optimized virtual machine which operates very quickly on large banks of input data due to processor pipelining and other optimizations.
Pre-optimizer
Before the VEX code is executed, Houdini/mantra will pre-optimize the compiled VEX code and cull out any instructions which don't contribute to the final data. It'll also resolve any variable for calculations which don't vary across the surface and replace those variables with constants. In this way, complex shaders of hundreds or thousands of instructions get reduced to the bare minimum depending on the parameters and input geometry attributes. A shader can easily end up in the tens of instructions from the thousands. This is obviously a HUGE speed consideration.
Caveats and gotchas
- It may well happen that the pre-optimizer may optimize out a value that only you may find useful. In these cases, you can trick the compiler into thinking that the value contributes to the final data. Try adding and then immediately subtracting the value you're interested in to the output data. e.g. In a shader, put: Cf = Cf + mydata - mydata;
- There are no arrays in VEX. Keep this in mind when considering your code design. The best you can really do is to retask the matrix4 datatype as an array of 16 floats.
- At the operator level, VEX SOPs, COPs, CHOPs, etc. do not have any local variables. The user-interface values are cooked once and then the VEX Op is run on your entire data.
- Colours in VEX are defined as a vector data type, not as a float[3]. You must be careful to not let this affect your thinking when it comes to adding extra geometry attributes using the AttribCreateSOP. You may be tempted to add an attribute to represent colour using the vector data type in the SOP which can cause major havoc later because you may do some transforms on that geometry (using a TransformSOP, for instance). Any transformations will transform vector atttributes too and so corrupt your colour information which is obviously NOT meant to be modified during a transform. Transforms will rotate vector types to ensure true vector information like velocity vectors and normals remain correct. So take care to create float[3] data types for colour information in the AttribCreateSOP and spare yourself some unnecessary psychedelia.
Casting
Unlike C++ (but like RenderMan SL), VEX uses the return type as part of the signature. This can create unresolvable type problems
Cf = random(noise(P));
This code should generate a warning from vcc since it's impossible to figure out whether the noise() function should return a float, vector or vector4.
The C++ style of casting is used to specify the return type explicitly.
Cf = random( vector(noise(P)) );
The C style of casting is implemented as a type conversion operation.
If you inspect the VEX assembler of the two types of
Cf = random( (vector) noise(P));
You'll still get the warning, and you should see that the noise() function generates a floating point value which is then converted to a vector. This is very different than the noise() function generating a vector result by itself.
However, since the C++ type-casting style is used for explicit return code specification, it can't really be used for casting one type to another. You have to use the C style.
A very subtle difference, but a potentially important one.



