Material Behaviour
Material Behaviours are a way to encapsulate shader functionality into building blocks. These building blocks can then be reused across multiple TGorillaDefaultMaterialSource components. This makes it easy to keep your shaders organized and maintainable.
NOTICE: Material behaviours are not compatible with embedded Firemonkey material sources, like TLightMaterialSource or TColorMaterialSourcce!
Apply a single material behaviour to multiple material sources, but the place to edit parameters of your behaviour stay centralized. This makes it very easy to manage complex shading behaviour.
Think of material behaviours as a collection of shader snippets which can be inserted into other shaders. For each behaviour you can write code for vertex and fragment shader.
This way, to build complex material surroundings, was developed to give users an easy way to setup a GPU based wind system or to render water caustics across different 3D objects.
In many sceneries you might have large number of different types of materials and you don't want to write the same shader function for each of them. Instead you want a central component to control parameters of your behaviour and apply it to the materials you like.
This way of building shader blocks became very handy, so we've started to implemented more components. The most flexible one is of course the TGorillaMaterialDesignTimeBehaviour which allows to setup a materials behaviour at design, also with it's parameters.
At the beginning we offer a few prepared components for you:
Class | Unit |
---|---|
TGorillaMaterialBehaviour (basis for all material behaviours) | Gorilla.Material.Behaviour |
TGorillaMaterialDesignTimeBehaviour | Gorilla.Material.Behaviour.DesignTime |
TGorillaMaterialWindBehaviour | Gorilla.Material.Behaviour.Wind |
TGorillaMaterialWobbleBehaviour | Gorilla.Material.Behaviour.Wobble |
TGorillaMaterialRimLightBehaviour | Gorilla.Material.Behaviour.RimLight |
TGorillaMaterialCausticsBehaviour | Gorilla.Material.Behaviour.Caustics |
TGorillaMaterialColorAdjustBehaviour | Gorilla.Material.Behaviour.ColorAdjust |
Attach / Detach
A material behaviour is attachable to TGorillaDefaultMaterialSource components. You can either attach those by the designtime property “Behaviours” of the default material source component or use the embedded methods for managing your material behaviours.
Method | Description |
---|---|
function MaterialBehaviourAttached(ABehaviour : TGorillaMaterialBehaviour) : Boolean; | Check if a specific material behaviour is attached to the default material source. |
function IndexOfMaterialBehaviour(ABehaviour : TGorillaMaterialBehaviour) : Integer; | Get the collection item index of a specific material behaviour. If it does not exist, the function returns -1. |
procedure AttachMaterialBehaviour(ABehaviour : TGorillaMaterialBehaviour); | Attaches a specific material behaviour to the default material source. |
procedure DetachMaterialBehaviour(ABehaviour : TGorillaMaterialBehaviour); | Detaches a specific material behaviour from the default material source. |
procedure ClearMaterialsBehaviours(); | Detaches all attached material behaviours from the specific default material source. |
TGorillaMaterialBehaviour
The TGorillaMaterialBehaviour class is the basis for all kinds of material behaviours. It offers a number of abstract methods to control the integration of a behaviour.
Method | Description |
---|---|
function DoOnRegisterUniformBuffer(out AName : String; out AUBO : Pointer; out AUBOSize : Integer) : Boolean; | The method is getting called when a uniform buffer should be registered in GPU. |
procedure DoOnInitializeUniformBuffer(AMaterial : TMaterial; var AInitialized : Boolean); | The method is getting called when the Delphi record structure for the uniform buffer should be initialized. Here you can clear the record or set up some initial values. |
procedure DoOnCreateShader(ABuilder : TGorillaNodeBuilder; AKind : TContextShaderKind); | The method is getting called when creating a vertex or fragment shader from nodes. Here you can add new nodes or modify existing nodes. |
procedure DoOnUpdateShader(ABuilder : TGorillaNodeBuilder; AKind : TContextShaderKind); | The method is getting called when updating a vertex or fragment shader from nodes. |
procedure DoOnRemoveShader(ABuilder : TGorillaNodeBuilder; AKind : TContextShaderKind); | The method is getting called when removing a vertex or fragment shader from nodes. Here you should remove nodes previously added. |
procedure Apply(AMaterial : TMaterial; AContext : TContext3D; AItem : TGorillaMaterialBehaviourItem); | The method is getting called by the TGorillaDefaultMaterial during the DoApply() call. |
Besides the overwritable methods to control the behaviour integration the component provides a few callback event properties:
Event | Type | Description |
---|---|---|
OnAttached | TNotifyEvent | Getting called each time the behaviour getting attached to a specific default material |
OnDetached | TNotifyEvent | Getting called each time the behaviour getting dettached from a specific default material |
TGorillaMaterialDesignTimeBehaviour
The design time material behaviour component allows you to create material behaviours right in your IDE without writing a new component class.
Property | Type | Description |
---|---|---|
DesignTimeParams | TDesignTimeUBO | A collection to setup a user specific uniform buffer (UBO) at design time. Uniform buffers are necessary to push values to your shaders and it's the connection between your program and the GPU shader-program. The design time UBO automatically creates a byte representation for you which is compatible with OpenGL's std140 memory layout. |
VertexShader | TStrings | Write a vertex shader function to be run in the vertex shader of the material behaviour. CAUTION: Only the function code! “TLocals DATA” is available. |
FragmentShader | TStrings | Write a fragment shader function to be run in the vertex shader of the material behaviour. CAUTION: Only the function code! “TLocals DATA” is available. |
AdditionalVertexShader | TStrings | Write additional vertex shader code which will be declared right before the material behaviour vertex shader function. Use this section to write helper functions in your shader. |
AdditionalFragmentShader | TStrings | Write additional fragment shader code which will be declared right before the material behaviour fragment shader function. Use this section to write helper functions in your shader. |
Setting up Parameters
Many shaders might need parameters to control their rendering. To supply values for those, we will need a unique uniform buffer.
The design time material behaviour provides an easy to use structure called “TDesignTimeUBO” to manage your parameters. It's a simple collection DesignTimeParams inside of your TGorillaMaterialDesignTimeBehaviour component.
Each item is of the type TDesignTimeUniform with the following configurable properties:
Property | Type | Description |
---|---|---|
DisplayName | String | Declare a unique name for your parameter in the shader. CAUTION: In shader you can access the parameter with the prefix “_”. Allowed characters are: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_ |
DataType | TDesignTimeUniformDataType | Select one of the supported data types for your uniform property: udtFloat, udtInt, udtVec2, udtVec3, udtVec4, udtColor |
Layout | TDesignTimeUniformDataTypeLayout | Choose between singleton or array value layout: udtlSingleton, udtlArray |
ArrayLength | Integer | If array value layout was set TDesignTimeUniformDataTypeLayout.udtlArray, the array length will define the size of the array in your uniform buffer. |
InputValue | String | The internal TValue storage will be returned as a formatted string depending on the DataType and Layout of this uniform. |
The design time behaviour component will try to set up an OpenGL std140 memory layout compatible structure automatically for you and push it to the shader program.
NOTICE: You don't have to take care of any adjusted allocations.
Using the InputValue property in IDE expects a compatible string input corresponding to the selected DataType and Layout of your uniform parameter:
DataType | Layout | Type | Example |
---|---|---|---|
udtFloat | udtlSingleton | float | “0.25” |
udtInt | udtlSingleton | int | “123” |
udtVec2 | udtlSingleton | vec2 | “0.1 0.2” |
udtVec3 | udtlSingleton | vec3 | “0.1 0.2 0.3” |
udtVec4 | udtlSingleton | vec4 | “0.1 0.2 0.3 0.4” |
udtColor | udtlSingleton | vec4 | “0.1 0.2 0.3 0.4” |
udtFloat | udtlArray | float[x] | “0.25 0.25 0.25 …“ |
udtInt | udtlArray | int[x] | “123 456 789 …“ |
udtVec2 | udtlArray | vec2[x] | “0.1 0.2 0.1 0.2 0.1 0.2 …“ |
udtVec3 | udtlArray | vec3[x] | “0.1 0.2 0.3 0.1 0.2 0.3 0.1 0.2 0.3 …“ |
udtVec4 | udtlArray | vec4[x] | “0.1 0.2 0.3 0.4 0.1 0.2 0.3 0.4 0.1 0.2 0.3 0.4 0.1 0.2 0.3 0.4 …“ |
udtColor | udtlArray | vec4[x] | “0.1 0.2 0.3 0.4 0.1 0.2 0.3 0.4 0.1 0.2 0.3 0.4 0.1 0.2 0.3 0.4 …“ |
TGorillaMaterialWindBehaviour
The wind material behaviour is a global component to be applied to default material sources, which should be affected by waving wind functionality.
Our wind behaviour is based on a wind channel, which is defined by a source point and a direction from there. The width, height and distance properties define the size of the channel. The wind is strongest at the source point and along the channel axis. It will lower its intensity to the outside.
Property | Type | Description |
---|---|---|
WindSource | TPosition3D | Define a source point of the wind. |
WindDir | TPosition3D | Define the direction of the wind from wind source. |
WindColor | TAlphaColor | Optional wind coloring. If wind color is set to (0.0, 0.0, 0.0, 0.0) coloring will be ignored in fragement shader. |
WindWidth | Single | Define the width of the wind channel. Wind is gettings stronger in the middle and lower to the outside. |
WindHeight | Single | Define the height of the wind channel. Wind is gettings stronger in the middle and lower to the outside. |
WindDistance | Single | Define a maximum distance of the wind. Wind is strongest at the source point and lowers to the max. distance in wind direction. |
WindPower | Single | Define the general wind power from which intensity is getting calculated depending on the wind channel width, height and max. distance. |
WindWaving | Single | Get or set a waving intensity value which defines the intensity of waving by the wind channel. This value is influenced by the width, height, max. distance and power of the wind channel. |
WindSpeed | Single | Define the speed of waving by the wind. |
WindDecay | Single | Control the influence the intensity of wind channel influence. Zero means no influence. Values between 0.0 and 1.0 are allowed. |
TGorillaMaterialWobbleBehaviour
The wobble material behaviour enables additional code in the vertex shader of each attached default material source.
It modifies the vertex position randomly by a noise function to simulate wobbling. This effect might be useful for waving or droplet simulation.
By the following properties you can control the behaviour yourself:
Property | Description |
---|---|
WobbleAxis | Enable and control the intensity of the wobble effect on each XYZ axis. |
WobbleSpeed | Control the speed of wobbling. |
WobbleIntensity | Control the general intensity of the wobble effect. You can modify this intensity on each XYZ axis by the WobbleAxis property. |
TGorillaMaterialRimLightBehaviour
For the rim lighting behaviour we've extracted the shader functionality from the TGorillaRimLightMaterialSource component to make it accessable to all default materials.
A rim light is placed behind a subject that exposes the outline or rim of the subject with light. This lighting highlights the contours of a subject and creates a dramatic and mysterious effect.
Rim lights can be used in a variety of ways. They can be used alone as a rim lighting setup to create a high contrast, stylized image. They can also be used in conjunction with other lighting setups such as the traditional 3 point lighting setup. When used in other lighting setups, these lights are often referred to as “hair lights” or “halo lighting.”
https://www.studiobinder.com/blog/what-is-a-rim-light-photography-definition/
Property | Descr |
---|---|
RimIntensity | Defines the intensity of the rim light rendering (value between 0.0 - 1.0) |
RimColor | Define the color of the rim light rendered. |
TGorillaMaterialCausticsBehaviour
Caustics are a well known optical effect produced by water surface. It's a light reflection effect, which we simplified and implemented as material behaviour.
Property | Description |
---|---|
CausticsColor | Color of caustics. |
Caustics | Number of caustics iterations. Values between 1 and 10 are allowed. |
CausticsSpeed | Speed of caustics waves. Values between 1 and 100 are allowed. |
CausticsSeed | Modify the seed for caustics computation: 1.0 - 10000.0 |
CausticsMix | Mixture between base color and caustics. Values between 0.0 - 1.0 are allowed. |
CausticsTiling | Tiling of rendered caustics. |
TGorillaMaterialColorAdjustBehaviour
Is a very simple material behaviour to adjust output colors of attached material sources by controlling brightness, contrast, gamma, hue, saturation and luminosity.
Property | Description |
---|---|
AdjustedColor | Get or set a color used to adjust the current fragment color. This color is getting multiplied with the current fragment color. Default value is (1, 1, 1, 1) |
Brightness | Get or set color brightness. |
Contrast | Get or set color contrast. |
Gamma | Get or set color gamma correction value. |
Hue | Get or set color hue value. |
Saturation | Get or set color saturation value. |
Luminosity | Get or set color luminosity value. |