The following section contains tips and best practices for using XGen.
Sometimes when you use attribute compensation the faces in the model do not align properly. For example, you can set offV=1 and all of your primitives will not point in the same direction. This misalignment is due XGen using intrinsic parameterization of the model, which is derived from the CV winding order.
You can prepare the model so its intrinsic uvs will seem randomly ordered from face to face. You can also compensate for this in most case with a few expressions:.
To compensate for misaligned faces:
float upOrDown: (abs(dot(norm($dPdv),[0,1,0]))>0.6 || abs(dot(norm($dPdu),[0,1,0]))>0.6)? 1 : 0 float flipY: (abs(dot(norm($dPdu),[0,1,0]))>0.6)? 90 : 0 float flipZ: (abs(dot(norm($dPdu),[0,0,1]))>0.6)? 90 : 0
twist: upOrDown() ? flipY() :flipZ()
To make primitives only around the normal rotate to face the camera, do the following:
To make primitives rotate to face the camera:
length: 0.3 width: 1.0 offV: 1.0 aboutN: $eye=norm($cam-$P);$ang=acosd(dot( $eye,[0,0,1])); $axis=cross([0,0,1],$eye); dot($axis,$N)>0 ? $ang : -$ang
length: 0.3 width: 1.0 bendV[0]: 1.0 aboutN: $eye=norm($cam-$P);$ang=acosd(dot( $eye,[0,0,1])); $axis=cross([0,0,1],$eye); dot($axis,$N)>0 ? $ang : -$ang
When grooming large grassy areas, it is best to use Attribute interpolation to control noise at each segment of the primitive. Create an attribute-driven description without the need to create guides, which also sets the default expressions so that they will not need guides.
If you are grooming a field of grass without guides, and your ground plane is uneven or undulates, the grass will point in the direction of the surface normal by default. To get your grass blades to point vertically by default, you must change the orientation so that each blade points upward (or at least an approximation,) try the following to expressions in the XGen Expression Editor :
offU: (90 - acosd(dot(norm($dPdu),[0,1,0]))) / 90 offV: (90 - acosd(dot(norm($dPdv),[0,1,0]))) / 90
A combination of these expressions adjusts the offU and offV attributes, and accounts for any change between the iso-tangents and the up-vector. If you need more precision with your grass direction, see Grow in Exact Direction, below.
If you have a scene where you want to simulate leaves drooping, you can use the following procedure without guides.
float bendMagU -acosd(dot(abs(norm($N)),[0,1,0]))/180*(dot(norm($dPdu),[0,1,0])) float bendMagV -acosd(dot(abs(norm($N)),[0,1,0]))/180*(dot(norm($dPdv),[0,1,0]))
bendMagU()
bendMagV()
The Always Grow Vertical tip works well for grass, but it is not exact as it is constrained by offU and offV limitations, which mean you cannot use the expressions to push past the tangent plane. If you need more precision, for example, in a pine tree with needles pointing in a specific direction, including into the surface from which the needles are generated, try the following workflow:
To specify a precise direction:
vector dir norm([1.0, 1.0, 0.0]) float dotU dot( norm($dPdu), dir() ) float dotV dot( norm($dPdv), dir() ) float len 100.0 * (abs(dotU()) + abs(dotV()))
offU dotU() / len() offV dotV() / len() offN acosd( dot($N, dir()) )
This provides the direction, normalized, in the dir palette expression. This can be a constant, as in this example, or it could be a painted normal map that you convert back into a proper normalized vector.
This procedure works because the palette expression determines which direction the primitive should be rotated. If you change that to a small value and fill it with offU and offV expressions, you can use offN for the real rotation. This overcomes the tangent plane and creates the magnitude required for aligning the primitive with the direction vector. Without the palette expressions, the direction is not guaranteed, only the magnitude of the rotation.
Except where otherwise noted, this work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License