User Tools

Site Tools

Hue Variation

Hue variation adds semi-random hues to individual instances or individual vertices based on parameters and a shader-based algorithm.

Hue variation is controlled via a set of per-base tree settings. In the Compiler, right-click on a base tree and select “Edit Effect LOD…”. You'll see Hue Variation as a new slider at bottom of the dialog – it defaults to enabled for the highest LOD only. The effect is not free, so only use it when you need this level of variation.

In the SDK, hue variation is set per CCore/CTree object using CCore::SetHueVariationParameters() that takes the following structure:

struct SHueVariationParams
	st_float32	m_fByPos;
	st_float32	m_fByVertex;
	Vec3		m_vColor;

When active, the amount of per-instance variation is controlled by m_fByPos. Zero means no effect and around 0.2 would be a very noticeable effect. m_fByVertex follows the same scale and addresses the amount of per-vertex variation applied. m_vColor determines which color the the variation will be tinted, but this can be misleading. A value of (1, 1, 1) can cause green leaves to have yellow-tinted variations. Experimenting is necessary for each tree.

Default Algorithm

In the shader template file Include_Utility.fx, there are two functions used to determine how much hue variation is applied both per-position and per-vertex. The key is to come up with a unique value based on the input. For position/instance variation, we use:

//  GenerateHueVariationByPos
//	Determines a unique [0, 1] float3 based on attributes unique to an instance;
//	in this case we're using a combination of the instance's 3D position
//	and orientation vector.
float3 GenerateHueVariationByPos(float fVariationScalar, float3 vInstanceRightVector)
	return fVariationScalar * fmod(vInstanceRightVector, float3(1.0, 1.0, 1.0)) * u_vHueVariationColor;

fVariationScalar corresponds to SHueVariationParams::m_fByPos and u_vHueVariationColor corresponds to SHueVariationParams::m_vColor. Just as important as the equation used in the function is which parameters the function takes. We use the instance's right vector because it tends to be a randomly-generated value in our examples. You're free to modify the function to use any input and/or equation that suits your approach.

For per-vertex variation, the following function is used:

//  GenerateHueVariationByVertex
//	Determine a unique [0, 1] float3 value based on attributes unique to a vertex
//	that *do not* change with LOD. We're using the normal in combination
//	with the instance's orientation vector.
//	This function can be modified as needed, but care should be take not to
//	use vertex attributes that might change as LOD changes, else the hue
//	variation will change along with it.
float3 GenerateHueVariationByVertex(float fVariationScalar, float3 vNormal)
	return fVariationScalar * sin(vNormal * 20.0f) * u_vHueVariationColor;

As noted in the comments, it's important that input values for this function not change as the instance transitions from one LOD to the next. A vertex's position, for example, makes a poor input for this function because the leaf geometry often scales up and down during LOD transitions. As it scales, its variation would change on the fly.