264 lines
6.9 KiB
C#
264 lines
6.9 KiB
C#
using Godot;
|
|
using System;
|
|
|
|
public enum DebugType
|
|
{
|
|
None,
|
|
Slope,
|
|
Height,
|
|
Temperature,
|
|
Moisture
|
|
}
|
|
|
|
[Tool]
|
|
public partial class World : Node2D
|
|
{
|
|
[Export]
|
|
public Texture2D HeightMapTexture;
|
|
|
|
[Export]
|
|
public int MapWidth
|
|
{
|
|
get => _mapWidth;
|
|
set
|
|
{
|
|
_mapWidth = value;
|
|
SetupShader();
|
|
}
|
|
}
|
|
private int _mapWidth = 3072;
|
|
|
|
[Export]
|
|
public float RockThreshold
|
|
{
|
|
get => _rockThreshold;
|
|
set
|
|
{
|
|
_rockThreshold = value;
|
|
UpdateShaderParameters();
|
|
}
|
|
}
|
|
private float _rockThreshold = 0.05f;
|
|
|
|
[Export]
|
|
public float SnowHeightThreshold
|
|
{
|
|
get => _snowHeightThreshold;
|
|
set
|
|
{
|
|
_snowHeightThreshold = value;
|
|
UpdateShaderParameters();
|
|
}
|
|
}
|
|
private float _snowHeightThreshold = 0.8f;
|
|
|
|
[Export]
|
|
public float WaterThreshold
|
|
{
|
|
get => _waterThreshold;
|
|
set
|
|
{
|
|
_waterThreshold = value;
|
|
UpdateShaderParameters();
|
|
}
|
|
}
|
|
private float _waterThreshold = 0.0f;
|
|
|
|
[Export]
|
|
public float DesertTemperatureThreshold
|
|
{
|
|
get => _desertTemperatureThreshold;
|
|
set
|
|
{
|
|
_desertTemperatureThreshold = value;
|
|
UpdateShaderParameters();
|
|
}
|
|
}
|
|
private float _desertTemperatureThreshold = 0.7f;
|
|
|
|
[Export]
|
|
public float DesertMoistureThreshold
|
|
{
|
|
get => _desertMoistureThreshold;
|
|
set
|
|
{
|
|
_desertMoistureThreshold = value;
|
|
UpdateShaderParameters();
|
|
}
|
|
}
|
|
private float _desertMoistureThreshold = 0.3f;
|
|
|
|
[Export]
|
|
public float TemperatureNoiseFrequency
|
|
{
|
|
get => _temperatureNoiseFrequency;
|
|
set
|
|
{
|
|
_temperatureNoiseFrequency = value;
|
|
UpdateShaderParameters();
|
|
}
|
|
}
|
|
private float _temperatureNoiseFrequency = 0.01f;
|
|
|
|
[Export]
|
|
public float MoistureNoiseFrequency
|
|
{
|
|
get => _moistureNoiseFrequency;
|
|
set
|
|
{
|
|
_moistureNoiseFrequency = value;
|
|
UpdateShaderParameters();
|
|
}
|
|
}
|
|
private float _moistureNoiseFrequency = 0.01f;
|
|
|
|
[Export]
|
|
public float TemperatureNoiseAmplitude
|
|
{
|
|
get => _temperatureNoiseAmplitude;
|
|
set
|
|
{
|
|
_temperatureNoiseAmplitude = value;
|
|
UpdateShaderParameters();
|
|
}
|
|
}
|
|
private float _temperatureNoiseAmplitude = 0.1f;
|
|
|
|
[Export]
|
|
public float MoistureNoiseAmplitude
|
|
{
|
|
get => _moistureNoiseAmplitude;
|
|
set
|
|
{
|
|
_moistureNoiseAmplitude = value;
|
|
UpdateShaderParameters();
|
|
}
|
|
}
|
|
private float _moistureNoiseAmplitude = 0.1f;
|
|
|
|
[Export]
|
|
public DebugType DebugType
|
|
{
|
|
get => _debugType;
|
|
set
|
|
{
|
|
_debugType = value;
|
|
UpdateShaderParameters();
|
|
}
|
|
}
|
|
private DebugType _debugType = DebugType.None;
|
|
|
|
private Sprite2D _terrainSprite;
|
|
private ShaderMaterial _shaderMaterial;
|
|
|
|
public override void _Ready()
|
|
{
|
|
// If the height map image is not assigned, log an error and return
|
|
if (HeightMapTexture == null)
|
|
{
|
|
GD.PrintErr("Height map texture is not assigned.");
|
|
return;
|
|
}
|
|
|
|
SetupShader();
|
|
}
|
|
|
|
private void SetupShader()
|
|
{
|
|
// Don't run during initialization if not ready
|
|
if (HeightMapTexture == null) return;
|
|
|
|
// Clear any existing terrain sprite
|
|
if (_terrainSprite != null)
|
|
{
|
|
_terrainSprite.QueueFree();
|
|
_terrainSprite = null;
|
|
}
|
|
|
|
// Load the shader
|
|
Shader terrainShader = GD.Load<Shader>("res://Shaders/terrain.gdshader");
|
|
if (terrainShader == null)
|
|
{
|
|
GD.PrintErr("Failed to load terrain shader.");
|
|
return;
|
|
}
|
|
|
|
// Create shader material
|
|
_shaderMaterial = new ShaderMaterial();
|
|
_shaderMaterial.Shader = terrainShader;
|
|
|
|
// Get heightmap dimensions
|
|
Image heightImage = HeightMapTexture.GetImage();
|
|
if (heightImage == null)
|
|
{
|
|
GD.PrintErr("Failed to get image from HeightMapTexture.");
|
|
return;
|
|
}
|
|
|
|
Vector2I heightMapSize = new Vector2I(heightImage.GetWidth(), heightImage.GetHeight());
|
|
|
|
// Calculate output resolution
|
|
// Height is always calculated based on heightmap aspect ratio
|
|
int outputWidth = MapWidth;
|
|
float aspectRatio = (float)heightMapSize.Y / heightMapSize.X;
|
|
int outputHeight = (int)(outputWidth * aspectRatio);
|
|
|
|
// Create a sprite to display the shader
|
|
_terrainSprite = new Sprite2D();
|
|
_terrainSprite.Material = _shaderMaterial;
|
|
_terrainSprite.TextureFilter = TextureFilterEnum.Nearest;
|
|
|
|
// Create a white texture with the desired output size
|
|
// The shader will render over this
|
|
Image whiteImage = Image.CreateEmpty(outputWidth, outputHeight, false, Image.Format.Rgba8);
|
|
whiteImage.Fill(Colors.White);
|
|
_terrainSprite.Texture = ImageTexture.CreateFromImage(whiteImage);
|
|
|
|
// Center the sprite
|
|
_terrainSprite.Centered = false;
|
|
|
|
AddChild(_terrainSprite);
|
|
|
|
// Update all shader parameters
|
|
UpdateShaderParameters();
|
|
}
|
|
|
|
private void UpdateShaderParameters()
|
|
{
|
|
if (_shaderMaterial == null)
|
|
{
|
|
GD.PrintErr("ShaderMaterial is null, cannot update parameters");
|
|
return;
|
|
}
|
|
|
|
if (HeightMapTexture == null)
|
|
{
|
|
GD.PrintErr("HeightMapTexture is null, cannot update parameters");
|
|
return;
|
|
}
|
|
|
|
GD.Print($"Setting height_map texture: {HeightMapTexture.ResourcePath}");
|
|
|
|
// Set the heightmap texture
|
|
_shaderMaterial.SetShaderParameter("height_map", HeightMapTexture);
|
|
|
|
// Set all threshold parameters
|
|
_shaderMaterial.SetShaderParameter("water_threshold", WaterThreshold);
|
|
_shaderMaterial.SetShaderParameter("rock_threshold", RockThreshold);
|
|
_shaderMaterial.SetShaderParameter("snow_height_threshold", SnowHeightThreshold);
|
|
_shaderMaterial.SetShaderParameter("desert_temperature_threshold", DesertTemperatureThreshold);
|
|
_shaderMaterial.SetShaderParameter("desert_moisture_threshold", DesertMoistureThreshold);
|
|
|
|
// Set noise parameters
|
|
_shaderMaterial.SetShaderParameter("temperature_noise_frequency", TemperatureNoiseFrequency);
|
|
_shaderMaterial.SetShaderParameter("temperature_noise_amplitude", TemperatureNoiseAmplitude);
|
|
_shaderMaterial.SetShaderParameter("moisture_noise_frequency", MoistureNoiseFrequency);
|
|
_shaderMaterial.SetShaderParameter("moisture_noise_amplitude", MoistureNoiseAmplitude);
|
|
|
|
// Set debug mode
|
|
_shaderMaterial.SetShaderParameter("debug_type", (int)DebugType);
|
|
|
|
GD.Print("Shader parameters updated successfully");
|
|
}
|
|
}
|