# GDScript: Material properties

Source: https://tweens.gd/gdscript/nodes/materials/

Helpers for `BaseMaterial3D`, so they work with both `StandardMaterial3D` and `ORMMaterial3D`.

A material is a resource, so its tweens need a tree or an owner node; see [materials](https://tweens.gd/gdscript/materials/) for how to start them and what each needs enabled.

Each row pairs a helper with the property path it tweens. Names ending in `_x`, `_y`, `_z`, or `_alpha` write one component.

| Helper | Property | Value |
| --- | --- | --- |
| `material_albedo_alpha` | `albedo_color:a` | float |
| `material_albedo_color` | `albedo_color` | Color |
| `material_emission` | `emission` | Color |
| `material_emission_energy_multiplier` | `emission_energy_multiplier` | float |
| `material_emission_intensity` | `emission_intensity` | float |
| `material_metallic` | `metallic` | float |
| `material_metallic_specular` | `metallic_specular` | float |
| `material_normal_scale` | `normal_scale` | float |
| `material_roughness` | `roughness` | float |
| `material_uv1_offset` | `uv1_offset` | Vector3 |
| `material_uv1_offset_x` | `uv1_offset:x` | float |
| `material_uv1_offset_y` | `uv1_offset:y` | float |
| `material_uv1_offset_z` | `uv1_offset:z` | float |
| `material_uv1_scale` | `uv1_scale` | Vector3 |
| `material_uv1_scale_x` | `uv1_scale:x` | float |
| `material_uv1_scale_y` | `uv1_scale:y` | float |
| `material_uv1_scale_z` | `uv1_scale:z` | float |
| `material_uv2_offset` | `uv2_offset` | Vector3 |
| `material_uv2_offset_x` | `uv2_offset:x` | float |
| `material_uv2_offset_y` | `uv2_offset:y` | float |
| `material_uv2_offset_z` | `uv2_offset:z` | float |
| `material_uv2_scale` | `uv2_scale` | Vector3 |
| `material_uv2_scale_x` | `uv2_scale:x` | float |
| `material_uv2_scale_y` | `uv2_scale:y` | float |
| `material_uv2_scale_z` | `uv2_scale:z` | float |

Each UV helper also has `_x`, `_y`, and `_z` variants. A component write reads the other components at each write, including concurrent edits to them.

## Units and constraints

-   Alpha fading requires a suitable transparency mode.
-   Emission and normal mapping need their feature flags enabled; normal mapping also needs a normal map.
-   Emission intensity requires `rendering/lights_and_shadows/use_physical_light_units`.
-   UV changes need suitable textures and mapping to be visible.

### Resource ownership

Automatic material playback requires a scene tree or an in-tree owner node. Owner-bound playback stops when the owner leaves; tree-bound playback stops with the tree. Playback keeps the original resource even when a mesh changes materials, and never duplicates or disposes it. A SceneTree owner binds to its root node, so `Tweens.cancel_tweens(get_tree().root)` also cancels that playback.

A manual scheduler can play resources without an owner. Dispose it when finished. See [resource lifetimes](https://tweens.gd/gdscript/materials/#choose-an-owner).

## Ordinary shader uniforms

```gdscript
# shader: uniform float dissolve = 0.25;
Tweens.play(shader_material, Tweens.shader_parameter(&"dissolve", 1.0, 0.5), get_tree())
Tweens.play(shader_material, Tweens.shader_parameter(&"dissolve", 1.0, 0.5), mesh)

var dissolve := Tweens.shader_parameter(&"dissolve", 1.0, 0.5)
dissolve.fill = Tweens.Fill.NONE
Tweens.play(shader_material, dissolve, get_tree())
```

`Tweens.shader_parameter(name, to = null, seconds = 0.0, easing, delay)` targets a `ShaderMaterial`. As with other resources, pass an owner node or the `SceneTree` as the third argument of `Tweens.play()`. The material is shared as usual, so every node using it sees the change. Uniform names are case-sensitive and captured when the tween starts. A missing shader, an undeclared uniform, an incompatible type, or a non-finite endpoint rejects the start before anything is written; the handle settles with `Tweens.Reason.FAILED` and the message in `handle.error`. If the material has no override for the uniform, the tween captures the declared shader default rather than zero.

| GDScript value | Uniform type |
| --- | --- |
| `float` | float |
| `int` | int |
| `Vector2` / `Vector3` / `Vector4` | Matching vector type |
| `Color` | Color (typically vec4 with source\_color hint) |

Match the uniform type exactly

Endpoints must have the uniform’s exact type. Write `1.0`, not `1`, for a float uniform: an `int` endpoint doesn’t bind to it. Color and Vector4 are distinct too, so neither binds to a uniform of the other type.

During interpolation, integers saturate at signed 32-bit bounds. Non-finite samples fail playback before writing. Textures, resources, arrays, booleans, and quaternions aren’t supported.

When a tween ends with a fill mode that doesn’t keep the final value (`NONE` or `APPLY_FROM_DURING_DELAY`), the original explicit override is restored, or the new override is removed if none originally existed. Cancelling keeps the latest sample, as with node tweens. You can reuse a definition across materials with different initial values and override states, because each start captures its own.

Replacing, freeing, or editing the bound shader fails playback the next time it samples or restores, and the handle settles with `FAILED`. Any shader change signal counts as a binding change, even if the new declaration happens to be compatible, so start a new tween after changing the shader.

Default lookup requires a working renderer. Godot’s dummy headless renderer can expose declarations but return no default value, and then the start is rejected rather than inventing one. Headless tests can use an explicit material override, but verifying defaults and visible behavior takes rendering tests.

## Per-instance shader uniforms

Declare an `instance uniform` in the shader when nodes sharing the same material need independent values:

```gdscript
# shader: instance uniform float pulse = 0.25;
Tweens.play(mesh, Tweens.instance_shader_parameter(&"pulse", 1.0, 0.5))
Tweens.play(sprite, Tweens.instance_shader_parameter(&"pulse", 0.0, 0.5))
```

`Tweens.instance_shader_parameter()` targets a `GeometryInstance3D` or a `CanvasItem`, which is also the owner, so these tweens follow the normal node lifetime and pause rules. Value types, validation, captures, and restoration work the same as for material uniforms. After restoration, an explicit override stays explicit, and an originally absent override is removed.

The tween captures the effective material bindings, including inherited CanvasItem materials, mesh surfaces, overrides, overlays and next passes. Replacing the mesh, a material, or a pass, or editing a bound shader, fails the next write. Binding checks are conservative, so changing a tracked slot can fail playback even if another slot still declares the same uniform. Godot controls instance-uniform indexing, capacity, shader compatibility and multi-material conflicts. The addon doesn’t assign or reconcile those declarations.

See [ShaderMaterial](https://docs.godotengine.org/en/stable/classes/class_shadermaterial.html), [CanvasItem](https://docs.godotengine.org/en/stable/classes/class_canvasitem.html), and [GeometryInstance3D](https://docs.godotengine.org/en/stable/classes/class_geometryinstance3d.html). See [compatibility](https://tweens.gd/compatibility/) for rendering limits and [handles](https://tweens.gd/gdscript/api/handles/#errors) for failure handling.
