Quick answer: Your ProcessMaterial is probably a shared external .tres resource referenced by more than one GPUParticles3D or scene. When another scene with the same material saves, your edits are overwritten. Right-click the ProcessMaterial in the inspector and choose Make Unique, or save it as a dedicated external resource for this node.

Here is how to fix Godot GPUParticles3D ProcessMaterial tweaks that disappear when you save the scene or reopen the editor. You spend an hour dialing in emission shape, initial velocity, color ramp, and turbulence. You save. You reopen the scene. Half your settings have reverted to defaults or to some other configuration. The material you edited is not the one being saved.

The Symptom

You drop a GPUParticles3D into a scene and assign it a ParticleProcessMaterial (or a ShaderMaterial custom process). You tune a dozen properties — direction vector, spread, gravity scale, color curve. Everything looks great in the viewport. You press Ctrl+S. The scene saves without warning. You close and reopen the scene. Some of your changes have vanished. Or you switch scenes and come back, and half the settings look like they belong to a different particle system entirely.

A telltale sign: the same material applied to multiple particle systems in different scenes is showing up with inconsistent values depending on which scene you opened last. You edit in Scene A, save, then open Scene B and see Scene A’s values on that scene’s particles too. The resource file is being mutated globally.

What Causes This

Godot resources come in two flavors: built-in and external. A built-in resource lives inside the scene file (.tscn) that uses it. It has no path on disk. Every scene that wants a built-in resource must create its own. Edits are local to the scene.

An external resource is a standalone .tres or .res file. Every scene or node that references it points to the same on-disk file. Edits to the resource modify that file, and every scene that uses it sees the change. This is incredibly useful for sharing materials across particle systems, but it becomes a bug when you do not realize the resource is shared.

When you drag a particle system into a new scene, Godot often duplicates the reference to the source scene’s ProcessMaterial rather than creating a fresh one. Both scenes now reference the same .tres. Editing from either scene overwrites the file. The edits are not “lost” — they are being clobbered the moment another scene with the same reference saves.

There is a second related issue with inherited scenes. If you inherit a base scene that contains a GPUParticles3D with a built-in ProcessMaterial, changing the material properties in the inherited scene creates a property override. If that override is later reset — for example, by pressing the revert-arrow icon in the inspector — the inherited scene reverts to the base material without visible warning.

The Fix

Step 1: Determine whether your ProcessMaterial is shared. Click the GPUParticles3D node. In the Inspector, expand the Process Material field. If the resource shows a file path like res://materials/fire_process.tres, it is external and potentially shared. If it shows <ParticleProcessMaterial> without a path, it is built-in and unique to this scene.

Search the project for references:

# In a terminal from the project root
grep -rn "fire_process.tres" --include="*.tscn" .

If more than one scene references the file, edits will race.

Step 2: Make the material unique if you need per-scene customization. Right-click the Process Material in the Inspector and choose Make Unique. Godot duplicates the resource and attaches the copy to this node. If you want to keep it external (for version control diff-friendliness), right-click again and choose Save As... to write a new .tres file.

Programmatically, the equivalent at runtime:

extends GPUParticles3D

func _ready() -> void:
  # Ensure this instance has its own material, not a shared one
  if process_material:
    process_material = process_material.duplicate()
    # Now tweak freely without affecting other particle systems
    process_material.direction = Vector3(0, 1, 0)
    process_material.initial_velocity_min = 5.0
    process_material.initial_velocity_max = 10.0

Step 3: Use external resources deliberately for shared effects. Not every material should be unique. A generic smoke effect used across five scenes benefits from being external — tweaking the file once updates every scene. Design shared effects in a dedicated res://materials/particles/ folder and mark them read-only in mental model. Per-scene customizations should use a unique copy.

Step 4: Audit inherited scenes for property overrides. Open the inherited scene. Select the GPUParticles3D. In the Inspector, look at the Process Material row. A small revert arrow (a curved back-arrow icon) next to a property means this scene overrides the base. If you see a revert arrow on the Process Material field itself, the inherited scene has its own material assignment; the base’s material is not used. If you want base-scene changes to propagate, click revert to drop the override.

Step 5: Prefer .tres over .res for readability. .tres is a text format you can diff in git. .res is binary. Text files make it obvious when a shared resource has been edited, so merge conflicts surface instead of silently overwriting.

The same sharing rule applies to DrawPass Mesh, ShaderMaterial uniforms, Curve resources for color ramps, and Gradient textures. Any resource-type inspector slot can be either built-in or external, and the same Make Unique workflow fixes unintended sharing.

Why This Works

Godot’s resource system is reference-based. When a scene loads, any ext_resource entries in the .tscn file are resolved to loaded resources, and each reference count increases. Saving a scene writes its sub-resources, but external resources are written to their own files independently. Two scenes referencing the same file share its memory and disk representation.

Make Unique clones the in-memory resource and assigns the clone to the referring property. The clone is a fresh resource, either built-in to the current scene or saved separately. Future edits land on the clone, not the original. This is the exact same mechanism that GDScript’s .duplicate() call performs at runtime.

For inherited scenes, Godot tracks property overrides per-scene. Understanding the revert-arrow indicator lets you see at a glance which properties are inherited versus overridden, and decide where material tweaks should live.

Related Issues

If your GPUParticles3D produces no particles in exported builds despite working in the editor, see Fix: Godot GPUParticles3D Empty in Exported Build — usually a shader include issue.

For particle materials whose color ramps look posterized, see Fix: Godot Particle Color Ramp Banding.

External .tres for shared effects. Make Unique for one-offs. Never edit a material you did not intend to share.