rokojori_action_library/Runtime/Procedural/Textures/TextureSettings.cs

122 lines
4.0 KiB
C#

using Godot;
using System;
using Rokojori.Extensions;
namespace Rokojori
{
/** How a texture is filtered when it is sampled at a different resolution
than its own.
Int values are read by the TextureStack blit shaders - do not renumber.
*/
public enum TextureSampling
{
/** One texel, no blending. Correct for index/id maps and for pixel art,
wrong for a low-resolution gradient blown up to 4k, which comes out
visibly banded.
*/
Nearest = 0,
/** Bilinear blend of the four surrounding texels. The default, because a
mask or gradient authored small and used large is the common case.
*/
Linear = 1
}
/** Colour space conversion applied to a texture right after it is sampled.
Godot does not convert between colour spaces for you here: a texture
sampled in a shader arrives in whatever space its own import settings
produced, and whether that is right depends on the space the output is
written in. For a TextureStack that means the target's format - an
Rgba8Srgb target encodes on write, a plain Rgba8 target does not.
So this is the explicit knob for "my source and my output disagree".
Alpha is never touched, only RGB.
Int values are read by the TextureStack blit shaders - do not renumber.
*/
public enum TextureColorSpaceConversion
{
/** Take the sampled value as-is. The default - correct whenever source and
output are already in the same space.
*/
None = 0,
/** Decode sRGB-encoded values to linear. Use when an sRGB source feeds a
linear target, or when a lighting-style calculation has to happen on
linear values.
*/
SRGBToLinear = 1,
/** Encode linear values as sRGB. Use when a linear source feeds a target
that is sampled as sRGB later on.
*/
LinearToSRGB = 2
}
/** How one texture slot is sampled: filtering and colour space conversion.
Shared, reusable settings resource rather than two fields repeated on
every slot, so the same settings object can be assigned to a layer's
content and to its masks at once.
<marked>Leaving the slot empty means Linear sampling and no
conversion</marked>, which is what the static helpers below return for
null. Nothing in the library requires a TextureSettings to exist - it is
only needed when the default is wrong.
*/
[Tool]
[GlobalClass]
public partial class TextureSettings:Resource
{
TextureSampling _sampling = TextureSampling.Linear;
/** Properties rather than fields, because Godot does not emit a scripted
Resource's changed signal for a plain exported field - and a
TextureStack recomposites off that signal. See
TextureStackChangeSource.
*/
[Export]
public TextureSampling sampling
{
get => _sampling;
set { _sampling = value; TextureStackNotify.Changed( this ); }
}
TextureColorSpaceConversion _colorSpaceConversion = TextureColorSpaceConversion.None;
[Export]
public TextureColorSpaceConversion colorSpaceConversion
{
get => _colorSpaceConversion;
set { _colorSpaceConversion = value; TextureStackNotify.Changed( this ); }
}
/** The defaults, for a null settings slot. Static rather than a shared
instance, so nothing has to allocate a Resource to ask.
*/
public static TextureSampling SamplingOf( TextureSettings settings )
{
return settings == null ? TextureSampling.Linear : settings.sampling;
}
public static TextureColorSpaceConversion ColorSpaceConversionOf( TextureSettings settings )
{
return settings == null ? TextureColorSpaceConversion.None : settings.colorSpaceConversion;
}
/** The two as the ints the shaders expect. */
public static int SamplingValueOf( TextureSettings settings )
{
return (int) SamplingOf( settings );
}
public static int ColorSpaceConversionValueOf( TextureSettings settings )
{
return (int) ColorSpaceConversionOf( settings );
}
}
}