Notch Notch
2026.2 2026.1 0.9.23
AI MCP
 Light | Dark
Custom Shader Effector

Custom Shader Effector

Updated: 29 Jun 2026

Add a custom .fx shader script as a Cloner Effector.

image

Example .dfx

Method #

See Working With Custom Shaders for an overview on managing .fx resources and HLSL scripts in Notch.

This node let’s you create your own custom effectors using shader code. This is great way of expanding the capabilities of cloner systems in Notch, and with careful design and implementation can lead to endless possibilities of innovative, efficient cloner based looks. Notch shaders are written in HLSL and use the D3DX Effect framework which allows for multiple techniques and passes and access to all of the pipeline stages.

Cloner Effectors allow for the manipulation of position, rotation, scale and colours of clones, as well as the killing of clones. For an overview of cloner systems and how to use clone effectors within them, see This Article.

This node receives information on a cloner system once per frame. By writing HLSL code, you can perform operations on that data and use it to update (effect) attributes of clones. You can also define your own variables that can be controlled from the Property Editor or via Modifiers, just like other parameters in Notch.

As with all cloner effectors, the order of node’s in the node graph will impact the order of operation and therefore the behaviour of cloner effectors. This also impacts the behaviour of the Custom Shader Effector. In short, when several cloner effectors are used in combination, the effectors that are placed at the top left of the node graph will be processed first, then those that are lower down in the node graph. For more information in this, see this section on Node Hierarchy and Data Flow
Custom Shader Effectors require the implementation of your own code to determine the behaviour of the Effector, and requires some knowledge of these systems to implement. Use of custom shaders is at your own risk. 10Bit does not provide support for custom shader code. If you experience an issue with a project/block you will need to demonstrate your issue without your custom shader in the nodegraph, to be able to receive support from the 10bit team. Support is only available for issues specifically related to the functionality of the Custom Shader Node, not for any custom code. External tools are available that can provide good assistance in writing these nodes when provided with the example script.

Understanding the Key Functionality of the Example Script #

Once you have gotten set up with the example script as shown in Set Up you are ready to start reading and customising it’s HLSL code.

This script uses mathematical functions to animate the scale, rotation and colour of the clones it acts on as determined by it’s falloff properties (the falloff applies a weighting to each clone that can be used to set how much the effector acts on any given clone).

There will be more detail in later sections, but in brief, to achieve this within this file:

  • Buffers are created to receive and hold information about the cloner system at the time the effector is applied to the cloner system. These incoming values are read once per frame.
  • Variables are created that will control the effect. These variables can be named as you chose, and can be controlled via the Property Editor or by using modifiers just like other properties in Notch.
  • The falloff properties of the node are used to control the effect on a clone by clone basis.
  • The functionality of this effector is determined inside of the function CS_ApplyEffector. This function is run once per frame, per clone. This code will run on multiple threads simultaneously.

The example code has very useful information on how to edit this shader or write these shaders, but before we get into that, let’s look at the most essential functions here.

Creating Shader Parameters #

The Custom Shader Effector lets you input floats and colours with sliders, colour controls, check boxes or menu options.

These parameters are declared in the example script like so:


float Freq_X < string propertyName = "Freq X"; > = 1.0f;
float Freq_Y < string propertyName = "Freq Y"; > = 0.0f;
float Freq_Z < string propertyName = "Freq Z"; > = 1.0f;
float Rotate_All = 0.0f;
float Scale_All = 0.0f;
Download FX Shader Copy FX Shader
This is just a code snippet. You can download the full example script here.

All global parameters without semantic ( : PARAM) binding are user params.

The property name can be set with < … > annotations to describe it’s attributes. Supported annotations for properties are as follows:

Annotation Description
string propertyName Name shown in the Notch property editor
float propertyMin Controls the default min range of the slider property
float propertyMax Controls the default max range of the slider property
string propertyType = "colour" / "checkbox" When not given, float slider is used as default
string propertyEnums[] = { "Small", "Big" } A list of property enums, gives values 0, 1, .. to the shader code

For example:

// Would create a slider named Freq Y, which has the default range of -10.0 to 10,0, and a default value of 0.
float Freq_Y <
string propertyName = "Freq Y";
float propertyMin = -10.0f;
float propertyMax = 10.0f;
> = 0.0f;

// Would create a menu with options displayed as small and big, and would return 0 and 1 respectively.
float Size_Object <
string propertyName = "Size";
string propertyEnums[] = { "Small", "Big" };
> = 0.0f;
Download FX Shader Copy FX Shader
This is just a code snippet. You can download the full example script here.

If no annotations are applied, the property will be displayed with the variable name as the property name, with underscores converted to spaces. It will be assigned a value slider with a default ranger of 0 to 1.

Buffers #

A key part of using this node is the use of buffers. These buffers are read once per frame. They are accessed to get information on each clone. This data can then be manipulated, and saved back into the same buffers. The buffers will then be used to update the properties of each clone index once per frame.

The buffers that determine the clones states that we have available to work with are shown within the example code:

Buffer Name Type Description
CloneCountBuffer StructuredBuffer<uint> Stores the total number of clones in the cloner system at index 0. N.B. this buffer is read only.
RWCloneIndexBuffer RWStructuredBuffer<uint> Stores the incoming clone index, will generally just be the number of each clone. But can be set to CLONE_KILLED_INDEX to “kill” the clone. See Here for information on “killing” clones.
RWCloneObjectIndexBuffer RWStructuredBuffer<uint> Stores which child object (mesh/node) each clone instance is referencing. Read by the renderer to know what geometry to draw for each clone. This holds an integer value that determines which child of the cloner will be instanced. This integer corresponds to the order of the cloner’s children. The first child of the node will be selected when the value is 0. The second will be selected when the value is 1 etc. See here for more info.
RWClonePositionBuffer RWStructuredBuffer<float3> X,Y and Z positions of each clone, as a float3.
RWCloneRotationBuffer RWStructuredBuffer<float3> Euler rotation of each clone stored as a float3.
RWCloneScaleBuffer RWStructuredBuffer<float3> X,Y and Z scales of each clone, as a float3.
RWCloneColourBuffer RWStructuredBuffer<float4> Per-clone RGBA colour stored as a float 4. Value range for RGBA is 0.0 to 1.0.
RWCloneUVScaleBuffer RWStructuredBuffer<float2> Per clone UV scale. Stored as float2 [scaleX,scaleY].
RWCloneUVOffsetBuffer RWStructuredBuffer<float2> Per-clone UV offset. Stored as float2 [offsetX,offsetY].
As these buffers are read and written once per frame, any changes you write to these buffers are overwritten each frame by the cloner system, so you cannot use them to carry values between frames.

Custom Buffers #

You can create your own custom buffers, that allow you to hold information across frames.

By default, each clone will have a dedicated entry in the buffer.

The buffers will be cleared once to 0 on load, and can be reset using the node’s reset pin.

The size of a buffer item must be defined with the byteSize annotation as shown in the example script.

Understanding the Example Effector #

This is really where the fun starts. What you write within the function CS_ApplyEffector is what is going to let you start messing with your clones. This node is completely customisable, and within reason you can do what you want to it. Below is just a description of how the example code is working just for completeness.

// Only process this clone if it's within the valid range and hasn't been killed
if (cloneIndex < numClones && RWCloneIndexBuffer[cloneIndex] != CLONE_KILLED_INDEX)
{
// Transform clone's local position into world space using the parent cloner's transform
float3 clonePos = mul(float4(RWClonePositionBuffer[cloneIndex], 1.0f), CloneParentTransformBuffer[cloneIndex]);

// Transform world position into the falloff node's local space for sampling
float3 falloffPos = mul(float4(clonePos, 1.0f), FalloffTransform).xyz;

// Sample the falloff value (0 yp1) at this clone's world position — defines the effector's region of influence
float falloff = GetFalloff(clonePos);

// Build a wave pattern across XYZ using sine/cosine of position * frequency + time, creating animated ripple movement
float effectArea = sin(falloffPos.x * Freq_X + AnimationTime) + cos(falloffPos.z * Freq_Z + AnimationTime) + sin(cos(falloffPos.y * Freq_Y + AnimationTime));

// Clamp effectArea to 0-1 so it can be safely used as a blend weight
effectArea = saturate(effectArea);

// Final influence amount — combines the spatial wave pattern with the falloff mask
float amt = effectArea * falloff;

// Target rotation: full spin on X (2π), quarter turn on Y (0.5π), no Z rotation
float3 rot = float3(2.0f * kPI, 0.5f * kPI, 0.0f);

// Blend clone's current rotation toward the target rotation based on effect influence
RWCloneRotationBuffer[cloneIndex] = lerp(RWCloneRotationBuffer[cloneIndex], rot, amt);

// Apply a global rotation offset on top of the blended result
RWCloneRotationBuffer[cloneIndex] +=
Rotate_All;

// Blend clone's scale toward Scale_All — note inverted weight (1-amt), so unaffected clones get scaled
RWCloneScaleBuffer[cloneIndex] = lerp(RWCloneScaleBuffer[cloneIndex], float3(1.0f, 1.0f, 1.0f) * Scale_All, 1.0f - amt);

// Blend clone colour toward a blue tint based on how strongly the effect is influencing this clone
RWCloneColourBuffer[cloneIndex] = lerp(RWCloneColourBuffer[cloneIndex], float4(0.50f, 0.50f, 1.0f, 1.0f), amt);

// If influence has effectively dropped to zero, kill this clone to remove it from the simulation
if (amt < 1e-4)
{
    RWCloneIndexBuffer[cloneIndex] =
CLONE_KILLED_INDEX;
}
Download FX Shader Copy FX Shader
This is just a code snippet. You can download the full example script here.

Tips, Tricks and Considerations #

Resetting the Node #

The node can be reset by sending a momentary value of 1 into it’s “Reset” input pin. In practice this clears all it’s buffers and resets its effect.

Logging #

When you are working with this node, you may make errors in your code that causes the node not to function. For this reason, useful information is shown inside of Notch’s log window to point out where you have gone wrong. It is recommended to work with your log window open when editing your code. This can be done from View -> Log Window.

Multithreading #

This compute shader runs 64 threads simultaneously per group, each processing one clone in parallel. This is part of what makes cloner systems efficient, but it introduces some rules you need to follow to avoid unpredictable results.

  • Each thread owns exactly one cloneIndex. As long as you only read and write to your own index, you are safe. However, if you start using the current thread to overwrite information about other clones, that information could well be overwritten by another thread that runs just after it.
  • A race condition happens when two threads try to read or write the same memory location at the same time. The result is unpredictable — whichever thread wins will overwrite the other.
  • Don’t assume thread execution order. Threads in different groups can run in any order.
  • Avoid branching based on other clones’ state. The state you read may be mid-write by another thread

Hierarchy, Node Order and Effector Combinations #

Again, remember that the presence of other effectors above this node in the hierarchy will impact the data that arrives in the RWClone buffers. This is important to remember as you are going to be working with the data as it arrives at your effector, after it’s been changed by any other effectors.

The Full Example Script #

#if 1
#include "FalloffShaderDef.h"
// Falloff API
// float GetFalloff(float3 pos);
// float4x4 FalloffTransform;
#endif

#define kPI	3.1415926535897932f

StructuredBuffer <uint> CloneCountBuffer : CLONECOUNTBUFFER;

// transform of the cloner node (could be from a cloned cloners chain)
StructuredBuffer<float4x4> CloneParentTransformBuffer : CLONEPARENTTRANSFORMBUFFER;

#define CLONE_KILLED_INDEX 0xFFFFFFFF
// cloned item index number, CLONE_KILLED_INDEX for removed clones
RWStructuredBuffer<uint> RWCloneIndexBuffer : RWCLONEINDEXBUFFER;

// cloner child node object index number
RWStructuredBuffer<uint> RWCloneObjectIndexBuffer : RWCLONEOBJECTINDEXBUFFER;

RWStructuredBuffer<float3> RWClonePositionBuffer : RWCLONEPOSITIONBUFFER;
RWStructuredBuffer<float3> RWCloneRotationBuffer : RWCLONEROTATIONBUFFER;
RWStructuredBuffer<float3> RWCloneScaleBuffer : RWCLONESCALEBUFFER;

RWStructuredBuffer<float4> RWCloneColourBuffer : RWCLONECOLOURBUFFER;
RWStructuredBuffer<float2> RWCloneUVScaleBuffer : RWCLONEUVSCALEBUFFER;
RWStructuredBuffer<float2> RWCloneUVOffsetBuffer : RWCLONEUVOFFSETBUFFER;


float4x4 EffectorWorldTransform : EFFECTORWORLDTRANSFORM;

float AnimationTime : ANIMATIONTIME;
float TimeDelta : TIMEDELTA;

sampler LinearClampSampler
{
	Filter = Min_Mag_Mip_Linear;
	AddressU = Clamp;
	AddressV = Clamp;
};
sampler LinearWrapSampler
{
	Filter = Min_Mag_Mip_Linear;
	AddressU = Wrap;
	AddressV = Wrap;
};


// -- Custom Shader Parameters --
// Set your custom shader parameters here. All global parameters without semantic ( : PARAM) binding are user params.
// The property name can be set with < ... > annotations or underscores like below (the underscores are converted as spaces in the name).
// The default values given here (= 1.0f; etc) propagate into the Notch property editor for new parameters.
// Supported annotations for properties:
// * string propertyName							- name shown in the Notch property editor
// * float propertyMin								- controls the default min range of the slider property
// * float propertyMax								- controls the default max range of the slider property
// * string propertyType = "colour" / "checkbox"	- when not given, float slider is used as default
// * string propertyEnums[] = { "Small", "Big" }	- a list of property enums, gives values 0,1,.. to the shader code

float Freq_X < string propertyName = "Freq X"; > = 1.0f;
float Freq_Y < string propertyName = "Freq Y"; > = 0.0f;
float Freq_Z < string propertyName = "Freq Z"; > = 1.0f;

float Rotate_All = 0.0f;
float Scale_All = 0.0f;

// Custom buffers can be used for state updates across frames.
// By default, each clone has one dedicated entry in the buffer (index with cloneIndex).
// The buffer content is cleared once to 0, and on node Reset input signal.
// The size of a buffer item has to be defined with the byteSize annotation like below.
RWStructuredBuffer<float> RWCustomCloneBuffer <int byteSize=4;>;



[numthreads(64,1,1)] void CS_ApplyEffector(uint3 GroupId : SV_GroupID, 
						uint3 DispatchThreadId : SV_DispatchThreadID,
						uint3 GroupThreadId : SV_GroupThreadID,
						uint GroupIndex : SV_GroupIndex)
{
	int cloneIndex = DispatchThreadId.x;
	uint numClones = CloneCountBuffer[0];

	if (cloneIndex < numClones && RWCloneIndexBuffer[cloneIndex] != CLONE_KILLED_INDEX)
	{
		float3 clonePos = mul(float4(RWClonePositionBuffer[cloneIndex], 1.0f), CloneParentTransformBuffer[cloneIndex]);
	
		float3 falloffPos = mul(float4(clonePos, 1.0f), FalloffTransform).xyz;
		float falloff = GetFalloff(clonePos);
		float effectArea = sin(falloffPos.x * Freq_X + AnimationTime) + cos(falloffPos.z * Freq_Z + AnimationTime) + sin(cos(falloffPos.y * Freq_Y + AnimationTime));
		effectArea = saturate(effectArea);

		float amt = effectArea * falloff;
	
		float3 rot = float3(2.0f * kPI, 0.5f * kPI, 0.0f);
	
		RWCloneRotationBuffer[cloneIndex] = lerp(RWCloneRotationBuffer[cloneIndex], rot, amt);
		RWCloneRotationBuffer[cloneIndex] += Rotate_All;
	
		RWCloneScaleBuffer[cloneIndex] = lerp(RWCloneScaleBuffer[cloneIndex], float3(1.0f, 1.0f, 1.0f) * Scale_All, 1.0f - amt);
		RWCloneColourBuffer[cloneIndex] = lerp(RWCloneColourBuffer[cloneIndex], float4(0.50f, 0.50f, 1.0f, 1.0f), amt);
	
		if (amt < 1e-4)
		{
			RWCloneIndexBuffer[cloneIndex] = CLONE_KILLED_INDEX;
		}
	}
}

technique11 ApplyEffector
{
	pass p0
	{
		SetComputeShader(CompileShader(cs_5_0, CS_ApplyEffector()));
	}
};
Download FX Shader Copy FX Shader

Another Example Script - Object Weights #

This is just another quick example of a script that lets you adjust the amount of each of your clones that gets created by the cloner. Set the number of different objects you have attached to your cloner, and then control the amount of each type of clone with the the weight parameters.

#if 1
#include "FalloffShaderDef.h"
#endif

#define kPI 3.1415926535897932f

StructuredBuffer<uint> CloneCountBuffer : CLONECOUNTBUFFER;
StructuredBuffer<float4x4> CloneParentTransformBuffer : CLONEPARENTTRANSFORMBUFFER;

#define CLONE_KILLED_INDEX 0xFFFFFFFF
RWStructuredBuffer<uint> RWCloneIndexBuffer : RWCLONEINDEXBUFFER;
RWStructuredBuffer<uint> RWCloneObjectIndexBuffer : RWCLONEOBJECTINDEXBUFFER;
RWStructuredBuffer<float3> RWClonePositionBuffer : RWCLONEPOSITIONBUFFER;
RWStructuredBuffer<float3> RWCloneRotationBuffer : RWCLONEROTATIONBUFFER;
RWStructuredBuffer<float3> RWCloneScaleBuffer : RWCLONESCALEBUFFER;
RWStructuredBuffer<float4> RWCloneColourBuffer : RWCLONECOLOURBUFFER;
RWStructuredBuffer<float2> RWCloneUVScaleBuffer : RWCLONEUVSCALEBUFFER;
RWStructuredBuffer<float2> RWCloneUVOffsetBuffer : RWCLONEUVOFFSETBUFFER;

float4x4 EffectorWorldTransform : EFFECTORWORLDTRANSFORM;
float AnimationTime : ANIMATIONTIME;
float TimeDelta : TIMEDELTA;

sampler LinearClampSampler
{
    Filter = Min_Mag_Mip_Linear;
    AddressU = Clamp;
    AddressV = Clamp;
};
sampler LinearWrapSampler
{
    Filter = Min_Mag_Mip_Linear;
    AddressU = Wrap;
    AddressV = Wrap;
};

// -- Custom Shader Parameters --

float Num_Clone_Types < 
    string propertyName = "Num Clone Types"; 
    float propertyMin = 1.0f; 
    float propertyMax = 10.0f; 
> = 2.0f;

float Weight_Clone_0 < string propertyName = "Weight Clone 0"; float propertyMin = 0.0f; float propertyMax = 1.0f; > = 0.1f;
float Weight_Clone_1 < string propertyName = "Weight Clone 1"; float propertyMin = 0.0f; float propertyMax = 1.0f; > = 0.1f;
float Weight_Clone_2 < string propertyName = "Weight Clone 2"; float propertyMin = 0.0f; float propertyMax = 1.0f; > = 0.1f;
float Weight_Clone_3 < string propertyName = "Weight Clone 3"; float propertyMin = 0.0f; float propertyMax = 1.0f; > = 0.1f;
float Weight_Clone_4 < string propertyName = "Weight Clone 4"; float propertyMin = 0.0f; float propertyMax = 1.0f; > = 0.1f;
float Weight_Clone_5 < string propertyName = "Weight Clone 5"; float propertyMin = 0.0f; float propertyMax = 1.0f; > = 0.1f;
float Weight_Clone_6 < string propertyName = "Weight Clone 6"; float propertyMin = 0.0f; float propertyMax = 1.0f; > = 0.1f;
float Weight_Clone_7 < string propertyName = "Weight Clone 7"; float propertyMin = 0.0f; float propertyMax = 1.0f; > = 0.1f;
float Weight_Clone_8 < string propertyName = "Weight Clone 8"; float propertyMin = 0.0f; float propertyMax = 1.0f; > = 0.1f;
float Weight_Clone_9 < string propertyName = "Weight Clone 9"; float propertyMin = 0.0f; float propertyMax = 1.0f; > = 0.1f;

// Per-clone assigned object index, persisted across frames so assignment is stable
RWStructuredBuffer<float> RWAssignedCloneType <int byteSize=4;>;


// -- Helper: Hash a uint to a float in 0-1 range --
// Used to generate a stable per-clone random value without a texture lookup
float HashToFloat(uint seed)
{
    seed = (seed ^ 61u) ^ (seed >> 16u);
    seed *= 9u;
    seed ^= seed >> 4u;
    seed *= 0x27d4eb2du;
    seed ^= seed >> 15u;
    return (float) (seed & 0x00FFFFFFu) / (float) 0x01000000u;
}


[numthreads(64, 1, 1)]void CS_ApplyEffector(uint3 GroupId : SV_GroupID,
                        uint3 DispatchThreadId : SV_DispatchThreadID,
                        uint3 GroupThreadId : SV_GroupThreadID,
                        uint GroupIndex : SV_GroupIndex)
{
    int cloneIndex = DispatchThreadId.x;
    uint numClones = CloneCountBuffer[0];

    if (cloneIndex < numClones && RWCloneIndexBuffer[cloneIndex] != CLONE_KILLED_INDEX)
    {
        // -- Build the weights array from individual parameters --
        float weights[10];
        weights[0] = Weight_Clone_0;
        weights[1] = Weight_Clone_1;
        weights[2] = Weight_Clone_2;
        weights[3] = Weight_Clone_3;
        weights[4] = Weight_Clone_4;
        weights[5] = Weight_Clone_5;
        weights[6] = Weight_Clone_6;
        weights[7] = Weight_Clone_7;
        weights[8] = Weight_Clone_8;
        weights[9] = Weight_Clone_9;

        int numTypes = (int) clamp(Num_Clone_Types, 1.0f, 10.0f);

        // -- Sum only the active weights so we can normalise against them --
        float totalWeight = 0.0f;
        for (int i = 0; i < numTypes; i++)
        {
            totalWeight += weights[i];
        }

        // -- Generate a stable random value for this clone based on its index --
        float randVal = HashToFloat((uint) cloneIndex) * totalWeight;

        // -- Walk the cumulative weight bands to pick a clone type --
        // e.g. weights [0.9, 0.1]: band 0 = 0.0-0.9, band 1 = 0.9-1.0
        // A randVal of 0.95 falls in band 1, so clone type 1 is selected
        uint selectedType = (uint) (numTypes - 1); // fallback to last type
        float cumulative = 0.0f;
        for (int j = 0; j < numTypes; j++)
        {
            cumulative += weights[j];
            if (randVal < cumulative)
            {
                selectedType = (uint) j;
                break;
            }
        }

        // -- Write the selected object index --
        RWCloneObjectIndexBuffer[cloneIndex] = selectedType;

        // -- Persist the assignment so it remains stable across frames --
        RWAssignedCloneType[cloneIndex] = (float) selectedType;
    }
}

technique11 ApplyEffector
{
    pass p0
    {
        SetComputeShader(CompileShader(cs_5_0, CS_ApplyEffector()));
    }
};
Download FX Shader Copy FX Shader

Parameters

These properties control the 3D transforms of the node. Transforms will generally be inherited by child nodes, although they can be ignored through the Inherit Transform Channels attributes.

ParameterDetails
Position X The objects position along the local x-axis.
Position Y The objects position along the local y-axis.
Position Z The objects position along the local z-axis.
Rotation Heading The objects rotation around the local y-axis.
Rotation Pitch The objects rotation around the local x-axis.
Rotation Bank The objects rotation around the local z-axis.
Scale X The objects scale along the local x-axis.
Scale Y The objects scale along the local y-axis.
Scale Z The objects scale along the local z-axis.

Control the inheritance of the transforms from the parent.

ParameterDetails
Position Toggle inheritance of the Position from the parent.
Rotation Toggle inheritance of the Rotation from the parent.
Scale Toggle inheritance of the Scale from the parent.
World Position Only Inherit the world position from the parent only, rotation and scale will be ignored. Overrides above properties.
Inherit Time Toggle inheritance of time from the parent.

These properties control the core behaviours of the node.

ParameterDetails
Create Shader File.. Create a template shader file to edit.
Shader Choose which .fx shader file to use.

The properties control the time at which the node is active. See Timeline for editing time segments.

ParameterDetails
Duration Control the duration of the node’s time segment.
  • Composition Duration : Use the length of the composition for the node’s time segment duration.
  • Custom : Set a custom duration for the node’s time segment.
Node Time The custom start and end time for the node.
Duration (Timecode) The length of the node’s time segment (in time).
Duration (Frames) The length of the node’s time segment (in frames).
Time Segment Enabled Set whether the node’s time segment is enabled or not in the Timeline.

Inputs

NameDescriptionTypical Input
Falloff NodeUse an input node to control the transformation values of the falloff.Falloff
Procedural FalloffUse a procedural system to generate falloff from. Useful for creating complex and unconventional falloffs from an Effector.Procedural Root
ResetResets the effector when it receives a value change from 0 to 1.Value
Target NodeModifiy the rotations of the node to always direct the z axis towards the input.Null
Local Transform OverrideApply the transforms of another node to this node, relative to its parent.Null