// SPDX-FileCopyrightText: 2023 Unity Technologies and the glTFast authors // SPDX-License-Identifier: Apache-2.0 using System; using UnityEngine; namespace GLTFast.Schema { /// /// Texture sampler properties for filtering and wrapping modes. /// [Serializable] public class Sampler : NamedObject { /// /// Magnification filter mode. /// public enum MagFilterMode { /// No value None = 0, /// Nearest pixel sampling Nearest = 9728, /// Linear pixel interpolation sampling Linear = 9729, } /// /// Minification filter mode. /// public enum MinFilterMode { /// No value None = 0, /// Nearest pixel sampling Nearest = 9728, /// Linear pixel interpolation sampling Linear = 9729, /// Nearest pixel and nearest mipmap sampling NearestMipmapNearest = 9984, /// Linear pixel interpolation and nearest mipmap sampling LinearMipmapNearest = 9985, /// Nearest pixel and linear mipmap interpolation sampling NearestMipmapLinear = 9986, /// Linear pixel interpolation and linear mipmap interpolation sampling LinearMipmapLinear = 9987 } /// /// Texture wrap mode. /// public enum WrapMode { /// No value None = 0, /// Clamp to edge ClampToEdge = 33071, /// Mirrored repeat MirroredRepeat = 33648, /// Repeat Repeat = 10497 } /// /// Magnification filter. /// Valid values correspond to WebGL enums: `9728` (NEAREST) and `9729` (LINEAR). /// public MagFilterMode magFilter = MagFilterMode.None; /// /// Minification filter. All valid values correspond to WebGL enums. /// public MinFilterMode minFilter = MinFilterMode.None; /// /// s wrapping mode. All valid values correspond to WebGL enums. /// public WrapMode wrapS = WrapMode.Repeat; /// /// t wrapping mode. All valid values correspond to WebGL enums. /// public WrapMode wrapT = WrapMode.Repeat; /// /// Unity filter mode, derived from glTF's /// and . /// public FilterMode FilterMode => ConvertFilterMode(minFilter, magFilter); /// /// Unity texture wrap mode (horizontal), derived from glTF's /// value. /// public TextureWrapMode WrapU => ConvertWrapMode(wrapS); /// /// Unity texture wrap mode (vertical), derived from glTF's /// value. /// public TextureWrapMode WrapV => ConvertWrapMode(wrapT); static FilterMode ConvertFilterMode(MinFilterMode minFilterToConvert, MagFilterMode magFilterToConvert) { switch (minFilterToConvert) { case MinFilterMode.LinearMipmapLinear: return FilterMode.Trilinear; case MinFilterMode.Nearest: case MinFilterMode.NearestMipmapNearest: case MinFilterMode.NearestMipmapLinear: // incorrect mip-map filtering in this case! return FilterMode.Point; } switch (magFilterToConvert) { case MagFilterMode.Nearest: return FilterMode.Point; default: return FilterMode.Bilinear; } } static TextureWrapMode ConvertWrapMode(WrapMode wrapMode) { switch (wrapMode) { case WrapMode.None: case WrapMode.Repeat: default: return TextureWrapMode.Repeat; case WrapMode.ClampToEdge: return TextureWrapMode.Clamp; case WrapMode.MirroredRepeat: return TextureWrapMode.Mirror; } } static WrapMode ConvertWrapMode(TextureWrapMode wrapMode) { switch (wrapMode) { case TextureWrapMode.Clamp: return WrapMode.ClampToEdge; case TextureWrapMode.Mirror: case TextureWrapMode.MirrorOnce: return WrapMode.MirroredRepeat; case TextureWrapMode.Repeat: default: return WrapMode.Repeat; } } /// /// Parameter-less constructor /// public Sampler() { } /// /// Constructs a Sampler with filter and wrap modes. /// /// Unity texture filter mode /// Unity texture wrap mode (horizontal) /// Unity texture wrap mode (vertical) public Sampler(FilterMode filterMode, TextureWrapMode wrapModeU, TextureWrapMode wrapModeV) { switch (filterMode) { case FilterMode.Point: magFilter = MagFilterMode.Nearest; minFilter = MinFilterMode.Nearest; break; case FilterMode.Bilinear: magFilter = MagFilterMode.Linear; minFilter = MinFilterMode.Linear; break; case FilterMode.Trilinear: magFilter = MagFilterMode.Linear; minFilter = MinFilterMode.LinearMipmapLinear; break; } wrapS = ConvertWrapMode(wrapModeU); wrapT = ConvertWrapMode(wrapModeV); } /// /// Applies the Sampler's settings to a Unity texture. /// /// Texture to apply the settings to /// Fallback minification filter /// Fallback magnification filter public void Apply(Texture2D image, MinFilterMode defaultMinFilter = MinFilterMode.Linear, MagFilterMode defaultMagFilter = MagFilterMode.Linear) { if (image == null) return; image.wrapModeU = WrapU; image.wrapModeV = WrapV; // Use the default filtering mode for textures that have no such specification in data image.filterMode = ConvertFilterMode( minFilter == MinFilterMode.None ? defaultMinFilter : minFilter, magFilter == MagFilterMode.None ? defaultMagFilter : magFilter ); } internal void GltfSerialize(JsonWriter writer) { writer.AddObject(); GltfSerializeName(writer); // Assuming MagFilterMode.Linear is the project's default, only // serialize valid, non-default values if (magFilter == MagFilterMode.Nearest) { writer.AddProperty("magFilter", (int)magFilter); } // Assuming MinFilterMode.Linear is the project's default, only // serialize valid, non-default values if (minFilter != MinFilterMode.None && minFilter != MinFilterMode.Linear) { writer.AddProperty("minFilter", (int)minFilter); } if (wrapS != WrapMode.None && wrapS != WrapMode.Repeat) { writer.AddProperty("wrapS", (int)wrapS); } if (wrapT != WrapMode.None && wrapT != WrapMode.Repeat) { writer.AddProperty("wrapT", (int)wrapT); } writer.Close(); } } }