initial commit
This commit is contained in:
commit
c2bb3893a9
1038 changed files with 75846 additions and 0 deletions
199
docs/FUNC_GODOT_TRENCHBROOM_SETUP.md
Normal file
199
docs/FUNC_GODOT_TRENCHBROOM_SETUP.md
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
# Setting Up a New Godot Project with FuncGodot + TrenchBroom
|
||||
|
||||
Step-by-step guide for using TrenchBroom as a level editor with Godot via the FuncGodot addon.
|
||||
Tested on Linux with Godot 4.6, FuncGodot 2025.12, and TrenchBroom (v9 game config format).
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
There are three things you configure, and they must agree with each other:
|
||||
|
||||
| What | Where it lives | What it controls |
|
||||
|---|---|---|
|
||||
| **FuncGodotLocalConfig** | `addons/func_godot/func_godot_local_config.tres` | Machine-specific paths (where to export configs, where your project lives on disk) |
|
||||
| **Your FGD resource** | A `.tres` you create in your project | Entity definitions + the FGD filename used in TrenchBroom |
|
||||
| **Your TrenchBroom GameConfig resource** | A `.tres` you create in your project | Game name, texture root, FGD reference — exports to TrenchBroom's games directory |
|
||||
|
||||
FuncGodotMapSettings also matters but has sane defaults. The critical thing is that paths line up.
|
||||
|
||||
---
|
||||
|
||||
## Step 1: Install FuncGodot
|
||||
|
||||
1. Copy the `addons/func_godot/` folder into your project's `addons/` directory (or install via AssetLib).
|
||||
2. In Godot: **Project > Project Settings > Plugins** — enable FuncGodot.
|
||||
3. Restart the editor if prompted.
|
||||
|
||||
---
|
||||
|
||||
## Step 2: Create Your Texture Directory
|
||||
|
||||
Put your textures in a **subdirectory** inside `res://textures/`. Do NOT put them directly in `res://textures/`.
|
||||
|
||||
```
|
||||
your_project/
|
||||
textures/
|
||||
my_textures/ <-- subdirectory required
|
||||
brick.png
|
||||
stone.png
|
||||
metal.png
|
||||
```
|
||||
|
||||
**Linux users:** Make sure file extensions are lowercase (`.png` not `.PNG`). Both TrenchBroom and Godot are case-sensitive on Linux.
|
||||
|
||||
---
|
||||
|
||||
## Step 3: Create Your FGD Resource
|
||||
|
||||
Do NOT edit the default `addons/func_godot/fgd/func_godot_fgd.tres`. Create your own.
|
||||
|
||||
1. In the Godot FileSystem panel, right-click your project root.
|
||||
2. **New Resource** > search for `FuncGodotFGDFile` > Create.
|
||||
3. Save it as something like `my_game_fgd.tres` in your project root.
|
||||
4. In the inspector, set:
|
||||
- **FGD Name**: `my_game` (this becomes the `.fgd` filename — no spaces, no extension)
|
||||
- **Base FGD Files**: Add `res://addons/func_godot/fgd/func_godot_fgd.tres` (this pulls in all the default entities like worldspawn, func_geo, etc.)
|
||||
- **Entity Definitions**: Leave empty for now. Add your custom entities here later.
|
||||
|
||||
**Why this matters:** The FGD Name you set here becomes both the exported `.fgd` filename AND the filename referenced inside `GameConfig.cfg`. If these don't match, TrenchBroom silently falls back to a different FGD or fails to load entities.
|
||||
|
||||
---
|
||||
|
||||
## Step 4: Create Your TrenchBroom GameConfig Resource
|
||||
|
||||
1. In Godot FileSystem, right-click your project root.
|
||||
2. **New Resource** > search for `TrenchBroomGameConfig` > Create.
|
||||
3. Save it as something like `my_game_tb_config.tres` in your project root.
|
||||
4. In the inspector, set:
|
||||
- **Game Name**: Something unique to this project (e.g. `my_game`). This is the name shown in TrenchBroom's game list. **Do not reuse "FuncGodot"** — it will collide with other projects.
|
||||
- **Textures > Textures Root Folder**: `textures` (this is relative to the game path, NOT a res:// path)
|
||||
- **Entities > FGD File**: Point to your FGD resource from Step 3 (`res://my_game_fgd.tres`)
|
||||
- Leave everything else at defaults unless you have a reason to change it.
|
||||
|
||||
---
|
||||
|
||||
## Step 5: Configure FuncGodotLocalConfig
|
||||
|
||||
This stores machine-specific paths in a JSON file outside your project, so it won't break when you move the project or work on a different machine.
|
||||
|
||||
1. Open `addons/func_godot/func_godot_local_config.tres` in the inspector.
|
||||
2. Set these fields:
|
||||
|
||||
| Field | Value | Example |
|
||||
|---|---|---|
|
||||
| **Trenchbroom Game Config Folder** | The folder inside TrenchBroom's games directory for THIS game. Must be a full filesystem path. | `/home/you/.TrenchBroom/games/my_game` |
|
||||
| **Map Editor Game Path** | Your Godot project root as a full filesystem path. TrenchBroom uses this to find textures. | `/home/you/godot_projects/my_game` |
|
||||
| **FGD Output Folder** | Usually same as your project root. Only used for standalone FGD export. | `/home/you/godot_projects/my_game` |
|
||||
|
||||
3. Click **Export func_godot settings** (the save button) to write these to disk.
|
||||
|
||||
**Where this actually saves:** `~/.local/share/godot/app_userdata/<YourProjectName>/func_godot_config.json` on Linux. If you clone the project to a new machine, you'll need to redo this step.
|
||||
|
||||
---
|
||||
|
||||
## Step 6: Export the GameConfig to TrenchBroom
|
||||
|
||||
1. Click on your TrenchBroom GameConfig resource (`my_game_tb_config.tres`) in the inspector.
|
||||
2. Click **Export GameConfig** (the button at the top of the inspector).
|
||||
3. Check the Godot output panel — it should print paths for the icon, GameConfig.cfg, and FGD file.
|
||||
|
||||
This creates three files in your TrenchBroom games folder:
|
||||
```
|
||||
~/.TrenchBroom/games/my_game/
|
||||
GameConfig.cfg <-- tells TrenchBroom about your game
|
||||
my_game.fgd <-- entity definitions (name matches your fgd_name)
|
||||
icon.png <-- 32x32 icon
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 7: Configure TrenchBroom
|
||||
|
||||
1. Open TrenchBroom.
|
||||
2. Your game should appear in the game list on the welcome screen. Select it.
|
||||
3. If it doesn't appear or textures don't load, go to **View > Preferences > Games**:
|
||||
- Select your game name.
|
||||
- Set **Game Path** to your Godot project root (same path as Map Editor Game Path from Step 5).
|
||||
4. Create a new map. Choose **Valve** format (recommended — it has per-face UV axes).
|
||||
|
||||
Your textures should now appear in TrenchBroom's texture browser under `my_textures/brick`, `my_textures/stone`, etc.
|
||||
|
||||
---
|
||||
|
||||
## Step 8: Build a Map and Import into Godot
|
||||
|
||||
1. Build your map in TrenchBroom. Save the `.map` file inside your Godot project directory (e.g. `res://maps/my_level.map`).
|
||||
2. Back in Godot, the `.map` file will auto-import as a resource.
|
||||
3. Create a new 3D scene. Add a **FuncGodotMap** node.
|
||||
4. In the inspector:
|
||||
- **Local Map File**: Set to your `.map` file (`res://maps/my_level.map`)
|
||||
- **Map Settings**: You can use the default (`addons/func_godot/func_godot_default_map_settings.tres`) or create your own FuncGodotMapSettings resource. Make sure `base_texture_dir` is `res://textures` and `entity_fgd` points to your FGD resource.
|
||||
5. Click **Build Map** in the toolbar (or the button on the FuncGodotMap node).
|
||||
|
||||
---
|
||||
|
||||
## How the Paths Must Align
|
||||
|
||||
This is where things break if you're not careful. The texture name in the `.map` file must resolve to the same file in both TrenchBroom and Godot.
|
||||
|
||||
```
|
||||
TrenchBroom resolves textures as:
|
||||
<Game Path> / <textures_root_folder> / <subdirectory> / <texture>.png
|
||||
/home/you/my_project / textures / my_textures / brick.png
|
||||
|
||||
Godot resolves textures as:
|
||||
<base_texture_dir> / <texture_name_from_map> . <extension>
|
||||
res://textures / my_textures/brick . png
|
||||
|
||||
The .map file stores: my_textures/brick
|
||||
```
|
||||
|
||||
If `Game Path + textures_root_folder` doesn't point to the same physical directory as `base_texture_dir`, textures will show in TrenchBroom but not in Godot (or vice versa).
|
||||
|
||||
---
|
||||
|
||||
## Quick Checklist for New Projects
|
||||
|
||||
- [ ] FuncGodot addon installed and enabled
|
||||
- [ ] Textures in a subdirectory of `res://textures/` with lowercase extensions
|
||||
- [ ] Created your own FGD resource (not editing the addon default)
|
||||
- [ ] `fgd_name` set to something unique
|
||||
- [ ] Default FGD added to `base_fgd_files`
|
||||
- [ ] Created your own TrenchBroom GameConfig resource
|
||||
- [ ] `game_name` set to something unique (not "FuncGodot")
|
||||
- [ ] `textures_root_folder` set to `textures`
|
||||
- [ ] `fgd_file` pointing to your FGD resource
|
||||
- [ ] FuncGodotLocalConfig paths set and exported:
|
||||
- [ ] `trenchbroom_game_config_folder` = `~/.TrenchBroom/games/<your_game>`
|
||||
- [ ] `map_editor_game_path` = your project root (full filesystem path)
|
||||
- [ ] Clicked "Export GameConfig" on your TrenchBroom GameConfig resource
|
||||
- [ ] In TrenchBroom: game path set to your Godot project root
|
||||
- [ ] No leftover `~/.TrenchBroom/games/` directories from old projects with the same game name
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Textures don't appear in TrenchBroom:**
|
||||
- Check that the Game Path in TrenchBroom preferences points to your Godot project root.
|
||||
- Verify `textures_root_folder` in your GameConfig resource matches your actual directory name.
|
||||
- On Linux: file extensions must be lowercase (`.png` not `.PNG`).
|
||||
- Re-export GameConfig after any changes.
|
||||
|
||||
**TrenchBroom loads wrong FGD / entities missing:**
|
||||
- Check `~/.TrenchBroom/games/` for duplicate directories with the same `"name"` in their GameConfig.cfg. Delete stale ones.
|
||||
- The FGD filename in `GameConfig.cfg` (`"definitions"` field) must match the actual `.fgd` file on disk. Both come from your FGD resource's `fgd_name` property — re-export to resync.
|
||||
|
||||
**Textures show in TrenchBroom but not in Godot after map build:**
|
||||
- `base_texture_dir` in your FuncGodotMapSettings must be `res://textures` (matching the physical directory that TrenchBroom's game path + textures root points to).
|
||||
- Texture names are case-sensitive on Linux. The name in the `.map` file must match the filename exactly.
|
||||
- Check the Godot output panel for "Error: Texture load failed" messages.
|
||||
|
||||
**FuncGodotLocalConfig settings don't stick:**
|
||||
- You must click "Export func_godot settings" after changing values. The `.tres` file itself doesn't store the data — it goes to a JSON file in Godot's user data directory.
|
||||
- After cloning to a new machine, re-enter and re-export all local config settings.
|
||||
|
||||
**Map file not recognized by Godot:**
|
||||
- The `.map` file must be inside your Godot project directory (under `res://`).
|
||||
- FuncGodot must be enabled in Project Settings > Plugins.
|
||||
204
docs/weathered_wall_shader.md
Normal file
204
docs/weathered_wall_shader.md
Normal file
|
|
@ -0,0 +1,204 @@
|
|||
# Weathered Wall Fragment Shader
|
||||
|
||||
## Setup
|
||||
|
||||
1. Create a new `ShaderMaterial` in Godot
|
||||
2. Assign this shader code
|
||||
3. Set your base wall texture in the `base_texture` slot
|
||||
4. Apply the material to your FuncGodot map geometry
|
||||
|
||||
Every surface using this material will look different because the noise samples from **world position**, not UV space. Two walls with the same texture and UVs get completely different weathering patterns because they're at different world coordinates.
|
||||
|
||||
---
|
||||
|
||||
## Shader Code
|
||||
|
||||
```gdshader
|
||||
shader_type spatial;
|
||||
|
||||
// Base texture
|
||||
uniform sampler2D base_texture : source_color, filter_nearest, repeat_enable;
|
||||
|
||||
// === WEATHERING CONTROLS ===
|
||||
// Gradient (rising damp)
|
||||
uniform float gradient_strength : hint_range(0.0, 1.0) = 0.6;
|
||||
uniform float gradient_exponent : hint_range(1.0, 5.0) = 3.0;
|
||||
uniform float gradient_noise_warp : hint_range(0.0, 1.0) = 0.4;
|
||||
|
||||
// Hue shifting
|
||||
uniform float shadow_cool_shift : hint_range(0.0, 0.15) = 0.06;
|
||||
uniform float highlight_warm_shift : hint_range(0.0, 0.15) = 0.04;
|
||||
|
||||
// Surface grime (noise overlay)
|
||||
uniform float grime_strength : hint_range(0.0, 1.0) = 0.3;
|
||||
uniform float grime_scale : hint_range(0.5, 10.0) = 3.0;
|
||||
|
||||
// Noise scale for large weathering patterns
|
||||
uniform float weather_scale : hint_range(0.1, 5.0) = 1.2;
|
||||
|
||||
// Stain blotches
|
||||
uniform float stain_strength : hint_range(0.0, 1.0) = 0.35;
|
||||
uniform float stain_scale : hint_range(0.5, 5.0) = 2.0;
|
||||
|
||||
// Overall intensity multiplier
|
||||
uniform float weathering_intensity : hint_range(0.0, 2.0) = 1.0;
|
||||
|
||||
|
||||
// ============================================================
|
||||
// Noise functions (no external texture needed)
|
||||
// ============================================================
|
||||
|
||||
vec2 hash22(vec2 p) {
|
||||
p = vec2(dot(p, vec2(127.1, 311.7)),
|
||||
dot(p, vec2(269.5, 183.3)));
|
||||
return -1.0 + 2.0 * fract(sin(p) * 43758.5453123);
|
||||
}
|
||||
|
||||
float noise(vec2 p) {
|
||||
vec2 i = floor(p);
|
||||
vec2 f = fract(p);
|
||||
vec2 u = f * f * (3.0 - 2.0 * f);
|
||||
|
||||
return mix(mix(dot(hash22(i + vec2(0.0, 0.0)), f - vec2(0.0, 0.0)),
|
||||
dot(hash22(i + vec2(1.0, 0.0)), f - vec2(1.0, 0.0)), u.x),
|
||||
mix(dot(hash22(i + vec2(0.0, 1.0)), f - vec2(0.0, 1.0)),
|
||||
dot(hash22(i + vec2(1.0, 1.0)), f - vec2(1.0, 1.0)), u.x), u.y);
|
||||
}
|
||||
|
||||
float fbm(vec2 p, int octaves) {
|
||||
float value = 0.0;
|
||||
float amplitude = 0.5;
|
||||
float frequency = 1.0;
|
||||
for (int i = 0; i < octaves; i++) {
|
||||
value += amplitude * noise(p * frequency);
|
||||
frequency *= 2.0;
|
||||
amplitude *= 0.5;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
// ============================================================
|
||||
// RGB <-> HSV conversion
|
||||
// ============================================================
|
||||
|
||||
vec3 rgb2hsv(vec3 c) {
|
||||
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
|
||||
vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
|
||||
vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
|
||||
float d = q.x - min(q.w, q.y);
|
||||
float e = 1.0e-10;
|
||||
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
|
||||
}
|
||||
|
||||
vec3 hsv2rgb(vec3 c) {
|
||||
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
||||
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
|
||||
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
||||
}
|
||||
|
||||
|
||||
// ============================================================
|
||||
// Main fragment
|
||||
// ============================================================
|
||||
|
||||
void fragment() {
|
||||
// Sample base texture
|
||||
vec4 tex = texture(base_texture, UV);
|
||||
vec3 color = tex.rgb;
|
||||
|
||||
// World position for noise - makes each wall unique
|
||||
vec3 world_pos = (INV_VIEW_MATRIX * vec4(VERTEX, 1.0)).xyz;
|
||||
vec2 wp = world_pos.xz;
|
||||
|
||||
// UV.y for vertical gradient (0 = top, 1 = bottom)
|
||||
float v_pos = UV.y;
|
||||
|
||||
// ---- COARSE WEATHERING NOISE ----
|
||||
float weather_noise = fbm(wp * weather_scale, 3) * 0.5 + 0.5;
|
||||
|
||||
// ---- FINE SURFACE GRIME ----
|
||||
float grime_noise = fbm(wp * grime_scale + vec2(50.0, 50.0), 3);
|
||||
|
||||
// ---- STAIN BLOTCHES ----
|
||||
float stain_noise = fbm(wp * stain_scale + vec2(100.0, 200.0), 4);
|
||||
stain_noise = smoothstep(0.15, 0.45, stain_noise);
|
||||
|
||||
// Convert to HSV
|
||||
vec3 hsv = rgb2hsv(color);
|
||||
|
||||
// ---- GRADIENT: RISING DAMP ----
|
||||
float gradient = pow(v_pos, gradient_exponent);
|
||||
float warped_gradient = gradient * mix(1.0, weather_noise * 1.6, gradient_noise_warp);
|
||||
warped_gradient = clamp(warped_gradient, 0.0, 1.0);
|
||||
|
||||
float grad_effect = warped_gradient * gradient_strength * weathering_intensity;
|
||||
hsv.z -= grad_effect * 0.35;
|
||||
hsv.x += grad_effect * shadow_cool_shift;
|
||||
hsv.y += grad_effect * 0.12;
|
||||
|
||||
// ---- HUE SHIFTING ----
|
||||
float luminance = hsv.z;
|
||||
float cool_warm = (luminance - 0.5) * 2.0;
|
||||
hsv.x += mix(shadow_cool_shift, -highlight_warm_shift, cool_warm * 0.5 + 0.5)
|
||||
* weathering_intensity;
|
||||
|
||||
// ---- SURFACE GRIME ----
|
||||
float grime_effect = grime_noise * grime_strength * weathering_intensity * 0.08;
|
||||
hsv.z -= grime_effect;
|
||||
hsv.y += abs(grime_effect) * 0.5;
|
||||
|
||||
// ---- STAIN BLOTCHES ----
|
||||
float stain_effect = stain_noise * stain_strength * weathering_intensity;
|
||||
hsv.z -= stain_effect * 0.1;
|
||||
hsv.x += stain_effect * 0.02;
|
||||
|
||||
// Clamp HSV
|
||||
hsv.x = fract(hsv.x);
|
||||
hsv.y = clamp(hsv.y, 0.0, 1.0);
|
||||
hsv.z = clamp(hsv.z, 0.0, 1.0);
|
||||
|
||||
// Back to RGB
|
||||
color = hsv2rgb(hsv);
|
||||
|
||||
ALBEDO = color;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## What Each Pass Does
|
||||
|
||||
**Rising damp gradient:** Runs on `UV.y` (top to bottom of the face) with the cubic exponent keeping the top clean. Coarse FBM noise warps the damp line so it's not perfectly horizontal — moisture follows porosity, not a ruler.
|
||||
|
||||
**Hue shifting:** Automatic based on luminance. Darker areas shift cool (blue-green), brighter areas shift warm (yellow). Same principle as palette ramps but continuous.
|
||||
|
||||
**Surface grime:** Fine-scale FBM that slightly varies value across brick faces. Every brick reads slightly different.
|
||||
|
||||
**Stain blotches:** Thresholded FBM that creates irregular dark patches, different on every wall.
|
||||
|
||||
---
|
||||
|
||||
## Uniform Reference
|
||||
|
||||
| Uniform | Default | What it does |
|
||||
|---|---|---|
|
||||
| `gradient_strength` | 0.6 | How dark the bottom gets |
|
||||
| `gradient_exponent` | 3.0 | Curve shape (higher = top stays cleaner longer) |
|
||||
| `gradient_noise_warp` | 0.4 | How much noise distorts the damp line |
|
||||
| `shadow_cool_shift` | 0.06 | Blue shift in dark areas |
|
||||
| `highlight_warm_shift` | 0.04 | Yellow shift in bright areas |
|
||||
| `grime_strength` | 0.3 | Fine surface dirt intensity |
|
||||
| `grime_scale` | 3.0 | Size of grime noise pattern |
|
||||
| `weather_scale` | 1.2 | Size of large weather blotches |
|
||||
| `stain_strength` | 0.35 | Dark stain patch intensity |
|
||||
| `stain_scale` | 2.0 | Size of stain blotch pattern |
|
||||
| `weathering_intensity` | 1.0 | Master dial — 0 = clean, 2 = ancient |
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
|
||||
- **UV.y assumption:** The gradient assumes UVs run top-to-bottom on wall faces. If FuncGodot generates UVs differently, swap `v_pos = UV.y` to `v_pos = 1.0 - (world_pos.y / wall_height)` or similar.
|
||||
- **Performance:** The FBM loops are the most expensive part. Reduce octave counts if needed. On your Radeon 890M this should be fine.
|
||||
- **Combining with Python script:** You can use the Python script for baking variant textures for your material browser in TrenchBroom (visual reference while editing), then apply this shader at runtime for the actual in-game look. Best of both worlds.
|
||||
Loading…
Add table
Add a link
Reference in a new issue