using Godot; using System; using Rokojori.Extensions; namespace Rokojori { /** The uniform block Shading/Library/ControlMap.gdshaderinc expects a consumer to declare, as property names. Same role TerrainOffsetShader plays for GeometryTerrainOffset: the names live in one place, so ControlMapTerrain.PushToMaterials() feeds any material that declares them without either side holding a string literal. The include itself declares no uniforms - it takes a ControlMapSetup struct the consumer fills. These are the uniforms the consumer needs in order to fill it. */ public class ControlMapShader { /** The packed control map. R32F, read with texelFetch only. */ public static readonly Sampler2DPropertyName controlMap = Sampler2DPropertyName.Create( "control_map" ); /** Ground albedo, with the texture's height in alpha. */ public static readonly Sampler2DArrayPropertyName albedoArray = Sampler2DArrayPropertyName.Create( "control_albedo_array" ); /** Ground normal maps, with roughness in alpha. */ public static readonly Sampler2DArrayPropertyName normalArray = Sampler2DArrayPropertyName.Create( "control_normal_array" ); /** One row of ( metersPerTile, detile, normalStrength, roughness ), one texel per texture index. */ public static readonly Sampler2DPropertyName textureParams = Sampler2DPropertyName.Create( "control_texture_params" ); public static readonly BoolPropertyName hasTextureParams = BoolPropertyName.Create( "control_has_texture_params" ); public static readonly Vector4PropertyName defaultParams = Vector4PropertyName.Create( "control_default_params" ); /* Placement - the same convention as TerrainOffsetShader, so a control map and a height map over the same rect line up texel for texel. */ public static readonly Vector2PropertyName centerXZ = Vector2PropertyName.Create( "control_center_xz" ); public static readonly Vector2PropertyName sizeXZ = Vector2PropertyName.Create( "control_size_xz" ); /* The bit layout. Each is ( offset, bit count ), pushed from ControlMapFormat so the packer and the GPU decoder cannot disagree. angleField is fed from ControlMapFormat.rotationField - the shader calls it an angle because it decodes radians, the authoring side calls it a rotation because that is what the user picks. See ControlMapFormat.PushToMaterial, which is the only place the two meet. */ public static readonly Vector2IPropertyName baseField = Vector2IPropertyName.Create( "control_base_field" ); public static readonly Vector2IPropertyName overlayField = Vector2IPropertyName.Create( "control_overlay_field" ); public static readonly Vector2IPropertyName blendField = Vector2IPropertyName.Create( "control_blend_field" ); public static readonly Vector2IPropertyName angleField = Vector2IPropertyName.Create( "control_angle_field" ); public static readonly Vector2IPropertyName scaleField = Vector2IPropertyName.Create( "control_scale_field" ); public static readonly Vector2IPropertyName holeField = Vector2IPropertyName.Create( "control_hole_field" ); public static readonly Vector2IPropertyName navigableField = Vector2IPropertyName.Create( "control_navigable_field" ); /* Value mapping and shading options. */ public static readonly FloatPropertyName scaleMin = FloatPropertyName.Create( "control_scale_min" ); public static readonly FloatPropertyName scaleStep = FloatPropertyName.Create( "control_scale_step" ); public static readonly FloatPropertyName blendSharpness = FloatPropertyName.Create( "control_blend_sharpness" ); public static readonly BoolPropertyName bilinear = BoolPropertyName.Create( "control_bilinear" ); } }