LightWave – WinFX Lexicon
I’ll be documenting here a set of terms in LightWave lingo along with their equivalents in WPF/XAML. I’ll also be making notes of any pertinent differences in approach between the two environments particularly pertaining to each specific concept. The notes here will specifically be limited to what’s acheivable in XAML without any code behind to pull off any fancy tricks.
Some of these notes will be obvious, others less so.
This does not claim to be authoritative – it’s all based on my personal observations, so if I’m wrong, please let me know!
General Concepts
Object -> GeometryModel3D
These are the closest equivalent terms for the general geometry/surface wrappers in each environment. A GeometryModel3D brings together the actual vertex geometry (MeshGeometry3D) with a surface definition (MaterialGroup).
Parenting -> Model3DGroup.Children
The same functionality that Parenting gives in LightWave can be achieved by grouping a Child’s Model3D data in the Parent’s Model3D.Children property. This has the effect of applying all transformations the Parent receives to the Child.
Camera -> ProjectionCamera
Ok, so you’ll almost certainly find a use for the MatrixCamera class too, as soon as you depart from LightWave’s simple camera settings, but ProjectionCamera is the ancestor class of PerspectiveCamera and OrthographicCamera, which will cover 97% of the uses you’ll need. LightWave’s camera is defined to look up its own Z axis, and this is most easily modeled with a LookDirection of 0,0,-1 in the xaml. Cameras in WPF also have a Transform property, so they are animatable in exactly the same way as Model3Ds.
Targeting -> ?
As far as I can tell, there is simply no way to declaratively make Model3Ds, lights or the camera rotate in place driven by another object. There’s scope here for subclassing GeometryModel3D and adding a Target DependencyProperty, if one feels so inclined… Maybe one of these days I’ll get round to it
Surface -> MaterialGroup
Geometry -> MeshGeometry3D
There’s a slight kink to this. LightWave’s UV map coordinates are specified per image in the surface, so in principle there can be as many UV map sets for an object as there are texture layers. A MeshGeometry3D only has a single TextureCoordinates property, and it doesn’t support any projection types. This means that in order to have any hope of matching appearance between LightWave and WPF, all images on an object must share the same projection type and parameters.
Lights
Point Light -> PointLight
These are directly equivalent.
Distant Light -> DirectionalLight
A Distant Light is almost the same as a DirectionalLight. They differ in that a Distant Light can have a Target. A DirectionalLight cannot.
Ambient Color, Ambient Intensity -> AmbientLight
LightWave’s lighting has a global ambient colour and intensity setting. The closest equivalent to these in XAML is the AmbientLight type. AmbientLights only have a Color property, but you can have more than one in a given Model3D tree.
Spot Light -> SpotLight
The Spot Light and SpotLight are almost identical. The only difference is that LightWave’s outer cone angle is measured from the center to the edge, whereas WPF’s SpotLight’s OuterConeAngle property is measured from side to side (that is, the OuterConeAngle value is double LightWave’s value).
Surfaces
Colour Channel -> DiffuseMaterial
The colour channel in LightWave is primarily represented by the DiffuseMaterial in WPF. However, there are wrinkles in this…
Transparency level -> Brush.Opacity
In LightWave, transparency goes from 0% (fully opaque) to 100% (fully transparent). The sense is reversed in WPF – Opacity values go from 0.0 (fully transparent) to 1.0 (fully opaque).
Transparency map -> DiffuseMaterial or UIElement.OpacityMask
In LightWave, the transparency channel is applied as a scalar intensity level to a surface. In WPF, there concept of a “transparency channel” doesn’t really exist. There’s no such thing as an OpacityMaterial, for example. There are two options if you want the effect of image-based transparency. The first is to apply your transparency map to the alpha channel of the colour image you are using for the DiffuseMaterial. The immediate advantage of this is that it’s simple. As long as you’ve only got a single colour image map, and you don’t mind altering the source image, it’s probably easiest to do this.
The alternative is a little more convoluted. It’s easiest to show the code first, then explain what it’s doing.
<VisualBrush>
<VisualBrush.Visual>
<Image HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0,0,0,0"
Source="#filename#">
<Image.OpacityMask>
<ImageBrush ImageSource="#mask_filename#" />
</Image.OpacityMask>
</Image>
</VisualBrush.Visual>
</Visual>
What we have here completely replaces the ImageBrush that would otherwise have filled the DiffuseMaterial.Brush property of the MaterialGroup. What this does is to create a generic Image control, and, taking advantage of the fact that all UIElements can have an OpacityMask added, we apply our transparency mask image to that control. Then we place that control inside a VisualBrush, which allows it to be used as a texture.
There is, however, a catch. OpacityMasks, for some unknown reason (and I don't know of any other system that works this way) use the opacity of the opacity mask's image for its value, not the intensity. With that in mind, the only technique I've found to use the same transparency image file in both LightWave and WPF involves copying the image, inverting it, and applying it to itself as an alpha mask, then switching off the alpha channel in LightWave. Clunky, but it works.
Luminosity Channel -> EmissiveMaterial
EmissiveMaterial is the closest match for LightWave's luminosity. However, they don't quite work the same way. A higher luminosity value in LightWave makes the observed surface colour tend towards the full surface colour value. EmissiveMaterials are entirely independent of any DiffuseMaterials that happen to live in the same MaterialGroup, and are coloured rather than scalar. I'll post an update shortly about how to get matching behaviour between the two.
Specularity Channel -> SpecularMaterial
The SpecularMaterial behaves in a very similar fashion to the Specular channel in LightWave, with the intensity of the SpecularMaterial's brush providing a close analogue to the specular channel value.
Glossiness -> SpecularMaterial.SpecularPower
Glossiness is approximately SpecularPower. I haven't confirmed a mathematical relationship, but from visual tests it looks to me like the glossiness range 0% -> 100% maps to a SpecularPower range of 17 -> 255. Also, it doesn't appear to be possible to apply an image map to this property.
September 11th, 2006 at 10:59 am
[...] Just made a quick update to the Lexicon page. In a nutshell, it turns out that you can animate PerspectiveCameras in exactly the same way as Model3Ds, because they support a Transform property. I haven’t had a chance to play with it properly yet, but it means no more fiddling with Vector3DAnimations to change LookDirection any more. Woohoo! [...]