2026-10-28 20:47:04 +00:00
|
|
|
using Godot;
|
|
|
|
|
using System;
|
|
|
|
|
|
|
|
|
|
using Rokojori.Extensions;
|
|
|
|
|
namespace Rokojori
|
|
|
|
|
{
|
|
|
|
|
/** Which primitive HeightMapShape.gdshader draws.
|
|
|
|
|
|
|
|
|
|
Int values are switched on in the shader - do not renumber.
|
|
|
|
|
*/
|
|
|
|
|
public enum HeightMapShapeType
|
|
|
|
|
{
|
2026-10-29 13:31:38 +00:00
|
|
|
Circle = 0,
|
|
|
|
|
Image = 1
|
2026-10-28 20:47:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class HeightMapShapeShader
|
|
|
|
|
{
|
|
|
|
|
public static readonly CachedResource<Shader> shader = new CachedResource<Shader>(
|
|
|
|
|
"res://addons/rokojori_action_library/Runtime/Procedural/HeightMaps/Shaders/HeightMapShape.gdshader"
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
public static readonly Vector2PropertyName rectWorldMin = Vector2PropertyName.Create( "shape_rect_world_min" );
|
|
|
|
|
public static readonly Vector2PropertyName rectWorldSize = Vector2PropertyName.Create( "shape_rect_world_size" );
|
|
|
|
|
|
|
|
|
|
public static readonly IntPropertyName shapeType = IntPropertyName.Create( "shape_type" );
|
|
|
|
|
public static readonly IntPropertyName blendMode = IntPropertyName.Create( "shape_blend_mode" );
|
2026-10-29 13:31:38 +00:00
|
|
|
|
|
|
|
|
public static readonly FloatPropertyName valueBase = FloatPropertyName.Create( "shape_value_base" );
|
|
|
|
|
public static readonly FloatPropertyName valueScale = FloatPropertyName.Create( "shape_value_scale" );
|
2026-10-28 20:47:04 +00:00
|
|
|
|
|
|
|
|
public static readonly Vector2PropertyName center = Vector2PropertyName.Create( "shape_center" );
|
|
|
|
|
public static readonly FloatPropertyName innerRadius = FloatPropertyName.Create( "shape_inner_radius" );
|
|
|
|
|
public static readonly FloatPropertyName outerRadius = FloatPropertyName.Create( "shape_outer_radius" );
|
|
|
|
|
public static readonly BoolPropertyName smoothFalloff = BoolPropertyName.Create( "shape_smooth_falloff" );
|
2026-10-29 13:31:38 +00:00
|
|
|
|
|
|
|
|
public static readonly Vector2PropertyName axisX = Vector2PropertyName.Create( "shape_axis_x" );
|
|
|
|
|
public static readonly Vector2PropertyName axisZ = Vector2PropertyName.Create( "shape_axis_z" );
|
|
|
|
|
public static readonly Vector2PropertyName imageSize = Vector2PropertyName.Create( "shape_size" );
|
|
|
|
|
public static readonly IntPropertyName imageChannel = IntPropertyName.Create( "shape_image_channel" );
|
|
|
|
|
public static readonly BoolPropertyName imageTiling = BoolPropertyName.Create( "shape_image_tiling" );
|
|
|
|
|
|
|
|
|
|
public static readonly IntPropertyName maskChannel = IntPropertyName.Create( "shape_mask_channel" );
|
|
|
|
|
public static readonly Vector2PropertyName maskCenter = Vector2PropertyName.Create( "shape_mask_center" );
|
|
|
|
|
public static readonly Vector2PropertyName maskAxisX = Vector2PropertyName.Create( "shape_mask_axis_x" );
|
|
|
|
|
public static readonly Vector2PropertyName maskAxisZ = Vector2PropertyName.Create( "shape_mask_axis_z" );
|
|
|
|
|
public static readonly Vector2PropertyName maskSize = Vector2PropertyName.Create( "shape_mask_size" );
|
2026-10-28 20:47:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Material for HeightMapShape.gdshader.
|
|
|
|
|
|
|
|
|
|
One instance per HeightMapGenerator, re-set per layer. The TextureStack's
|
|
|
|
|
session-2 live test already proved that re-setting a shared blit material
|
|
|
|
|
between queued blits is safe - the earlier blits do not pick up the later
|
|
|
|
|
values - which is why every layer can share one material instead of
|
|
|
|
|
allocating its own.
|
2026-10-29 13:31:38 +00:00
|
|
|
|
|
|
|
|
The image texture is <marked>not</marked> a property here: it arrives as
|
|
|
|
|
the blit's source, which is what hint_blit_source0 binds to.
|
2026-10-28 20:47:04 +00:00
|
|
|
*/
|
|
|
|
|
[Tool]
|
|
|
|
|
public partial class HeightMapShapeMaterial:CustomMaterial
|
|
|
|
|
{
|
|
|
|
|
public readonly CustomMaterialProperty<Vector2> rectWorldMin;
|
|
|
|
|
public readonly CustomMaterialProperty<Vector2> rectWorldSize;
|
|
|
|
|
|
|
|
|
|
public readonly CustomMaterialProperty<int> shapeType;
|
|
|
|
|
public readonly CustomMaterialProperty<int> blendMode;
|
2026-10-29 13:31:38 +00:00
|
|
|
|
|
|
|
|
public readonly CustomMaterialProperty<float> valueBase;
|
|
|
|
|
public readonly CustomMaterialProperty<float> valueScale;
|
2026-10-28 20:47:04 +00:00
|
|
|
|
|
|
|
|
public readonly CustomMaterialProperty<Vector2> center;
|
|
|
|
|
public readonly CustomMaterialProperty<float> innerRadius;
|
|
|
|
|
public readonly CustomMaterialProperty<float> outerRadius;
|
|
|
|
|
public readonly CustomMaterialProperty<bool> smoothFalloff;
|
|
|
|
|
|
2026-10-29 13:31:38 +00:00
|
|
|
public readonly CustomMaterialProperty<Vector2> axisX;
|
|
|
|
|
public readonly CustomMaterialProperty<Vector2> axisZ;
|
|
|
|
|
public readonly CustomMaterialProperty<Vector2> imageSize;
|
|
|
|
|
public readonly CustomMaterialProperty<int> imageChannel;
|
|
|
|
|
public readonly CustomMaterialProperty<bool> imageTiling;
|
|
|
|
|
|
|
|
|
|
public readonly CustomMaterialProperty<int> maskChannel;
|
|
|
|
|
public readonly CustomMaterialProperty<Vector2> maskCenter;
|
|
|
|
|
public readonly CustomMaterialProperty<Vector2> maskAxisX;
|
|
|
|
|
public readonly CustomMaterialProperty<Vector2> maskAxisZ;
|
|
|
|
|
public readonly CustomMaterialProperty<Vector2> maskSize;
|
|
|
|
|
|
2026-10-28 20:47:04 +00:00
|
|
|
public HeightMapShapeMaterial()
|
|
|
|
|
{
|
|
|
|
|
Shader = HeightMapShapeShader.shader.Get();
|
|
|
|
|
|
|
|
|
|
rectWorldMin = new CustomMaterialProperty<Vector2>( this, HeightMapShapeShader.rectWorldMin );
|
|
|
|
|
rectWorldSize = new CustomMaterialProperty<Vector2>( this, HeightMapShapeShader.rectWorldSize );
|
|
|
|
|
|
|
|
|
|
shapeType = new CustomMaterialProperty<int>( this, HeightMapShapeShader.shapeType );
|
|
|
|
|
blendMode = new CustomMaterialProperty<int>( this, HeightMapShapeShader.blendMode );
|
2026-10-29 13:31:38 +00:00
|
|
|
|
|
|
|
|
valueBase = new CustomMaterialProperty<float>( this, HeightMapShapeShader.valueBase );
|
|
|
|
|
valueScale = new CustomMaterialProperty<float>( this, HeightMapShapeShader.valueScale );
|
2026-10-28 20:47:04 +00:00
|
|
|
|
|
|
|
|
center = new CustomMaterialProperty<Vector2>( this, HeightMapShapeShader.center );
|
|
|
|
|
innerRadius = new CustomMaterialProperty<float>( this, HeightMapShapeShader.innerRadius );
|
|
|
|
|
outerRadius = new CustomMaterialProperty<float>( this, HeightMapShapeShader.outerRadius );
|
|
|
|
|
smoothFalloff = new CustomMaterialProperty<bool>( this, HeightMapShapeShader.smoothFalloff );
|
2026-10-29 13:31:38 +00:00
|
|
|
|
|
|
|
|
axisX = new CustomMaterialProperty<Vector2>( this, HeightMapShapeShader.axisX );
|
|
|
|
|
axisZ = new CustomMaterialProperty<Vector2>( this, HeightMapShapeShader.axisZ );
|
|
|
|
|
imageSize = new CustomMaterialProperty<Vector2>( this, HeightMapShapeShader.imageSize );
|
|
|
|
|
imageChannel = new CustomMaterialProperty<int>( this, HeightMapShapeShader.imageChannel );
|
|
|
|
|
imageTiling = new CustomMaterialProperty<bool>( this, HeightMapShapeShader.imageTiling );
|
|
|
|
|
|
|
|
|
|
maskChannel = new CustomMaterialProperty<int>( this, HeightMapShapeShader.maskChannel );
|
|
|
|
|
maskCenter = new CustomMaterialProperty<Vector2>( this, HeightMapShapeShader.maskCenter );
|
|
|
|
|
maskAxisX = new CustomMaterialProperty<Vector2>( this, HeightMapShapeShader.maskAxisX );
|
|
|
|
|
maskAxisZ = new CustomMaterialProperty<Vector2>( this, HeightMapShapeShader.maskAxisZ );
|
|
|
|
|
maskSize = new CustomMaterialProperty<Vector2>( this, HeightMapShapeShader.maskSize );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** The mask rect, for a layer that has no opinion about it: anything the
|
|
|
|
|
mask's own rect does not cover takes its border value, so a 1x1 rect
|
|
|
|
|
centered on the shape is a flat multiplier over the whole shape.
|
|
|
|
|
*/
|
|
|
|
|
public void SetMaskRect( Vector2 center, Vector2 axisX, Vector2 axisZ, Vector2 size )
|
|
|
|
|
{
|
|
|
|
|
maskCenter.Set( center );
|
|
|
|
|
maskAxisX.Set( axisX );
|
|
|
|
|
maskAxisZ.Set( axisZ );
|
|
|
|
|
maskSize.Set( size );
|
2026-10-28 20:47:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Back to a shape that contributes nothing, so a layer that only sets some
|
|
|
|
|
of the uniforms does not inherit the previous layer's.
|
|
|
|
|
|
|
|
|
|
The rect uniforms are deliberately not reset - HeightMapGenerator.DrawShape
|
|
|
|
|
owns those and sets them after the layer has configured the shape.
|
|
|
|
|
*/
|
|
|
|
|
public void Reset()
|
|
|
|
|
{
|
|
|
|
|
shapeType.Set( (int) HeightMapShapeType.Circle );
|
|
|
|
|
blendMode.Set( (int) HeightMapBlendMode.Add );
|
2026-10-29 13:31:38 +00:00
|
|
|
|
|
|
|
|
valueBase.Set( 0 );
|
|
|
|
|
valueScale.Set( 0 );
|
2026-10-28 20:47:04 +00:00
|
|
|
|
|
|
|
|
center.Set( Vector2.Zero );
|
|
|
|
|
innerRadius.Set( 0 );
|
|
|
|
|
outerRadius.Set( 0 );
|
|
|
|
|
smoothFalloff.Set( true );
|
2026-10-29 13:31:38 +00:00
|
|
|
|
|
|
|
|
axisX.Set( new Vector2( 1, 0 ) );
|
|
|
|
|
axisZ.Set( new Vector2( 0, 1 ) );
|
|
|
|
|
imageSize.Set( Vector2.One );
|
|
|
|
|
imageChannel.Set( (int) HeightMapChannel.R );
|
|
|
|
|
imageTiling.Set( false );
|
|
|
|
|
|
|
|
|
|
maskChannel.Set( (int) HeightMapChannel.A );
|
|
|
|
|
SetMaskRect( Vector2.Zero, new Vector2( 1, 0 ), new Vector2( 0, 1 ), Vector2.One );
|
2026-10-28 20:47:04 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|