Esempio n. 1
0
        private void FindMaterialAttributes(ValveMaterialFile vmt, List <VertexAttribute> dest)
        {
            dest.Add(VertexAttribute.Position);
            dest.Add(VertexAttribute.Normal);
            dest.Add(VertexAttribute.Uv);

            if (vmt == null)
            {
                return;
            }

            var shader = vmt.Shaders.First();

            switch (shader.ToLower())
            {
            case "lightmappedgeneric":
            case "lightmappedreflective":
            case "water":
                dest.Add(VertexAttribute.Uv2);
                break;

            case "lightmapped_4wayblend":
            case "worldvertextransition":
                dest.Add(VertexAttribute.Alpha);
                goto case "lightmappedgeneric";
            }
        }
Esempio n. 2
0
        private MeshData GetOrCreateMeshData(ValveBspFile bsp, GeometryPage page, string matPath, bool cacheVertices = true)
        {
            MaterialGroup matGroup;

            var matDictIndex = MaterialDictionary.GetResourceIndex(bsp, matPath);

            if (!page.MaterialIndices.TryGetValue(matDictIndex, out int matIndex))
            {
                var vmt = ValveMaterialFile.FromProvider(MaterialDictionary.GetResourcePath(bsp, matDictIndex), bsp.PakFile, Program.Resources);

                matGroup = new MaterialGroup(matIndex = page.Materials.Count, cacheVertices)
                {
                    Material = matDictIndex
                };
                page.MaterialIndices.Add(matDictIndex, matIndex);
                page.Materials.Add(matGroup);

                FindMaterialAttributes(vmt, matGroup.MeshData.Attributes);
            }
            else
            {
                matGroup = page.Materials[matIndex];
            }

            return(matGroup.MeshData);
        }
Esempio n. 3
0
    private void LoadMaterial(MeshRenderer mr, string path)
    {
        if (!_resourceLoader.ContainsFile(path))
        {
            return;
        }

        if (path.ToLower().Contains("tools"))
        {
            mr.enabled = false;
            return;
        }

        Material mat = null;

        var pathLower = path.ToLower();

        if (_materialCache.ContainsKey(pathLower))
        {
            mat = _materialCache[pathLower];
        }
        else
        {
            using (var fs = _resourceLoader.OpenFile(path))
            {
                var vmt = ValveMaterialFile.FromStream(fs);
                mat = VmtToMaterial(_resourceLoader, vmt, path);
                _materialCache.Add(pathLower, mat);
            }
        }

        mr.material = mat;
    }
Esempio n. 4
0
        private void Parse(ValveMaterialFile vmt)
        {
            // idk why this is enumerable
            var e = vmt.Shaders.GetEnumerator();

            while (e.MoveNext())
            {
                VmtShader     = e.Current.ToLower();
                Lightmapped   = VmtShader == "lightmappedgeneric" || VmtShader == "worldvertextransition";
                Transition    = VmtShader == "worldvertextransition";
                AlphaTest     = vmt[VmtShader].ContainsKey("$alphatest") ? vmt[VmtShader]["$alphatest"] : false;
                Translucent   = vmt[VmtShader].ContainsKey("$translucent") ? vmt[VmtShader]["$translucent"] : false;
                NoCull        = vmt[VmtShader].ContainsKey("$nocull") ? vmt[VmtShader]["$nocull"] : false;
                BaseTex       = vmt[VmtShader].ContainsKey("$basetexture") ? vmt[VmtShader]["$basetexture"] : string.Empty;
                BaseTex2      = vmt[VmtShader].ContainsKey("$basetexture2") ? vmt[VmtShader]["$basetexture2"] : string.Empty;
                BumpMap       = vmt[VmtShader].ContainsKey("bumpmap") ? vmt[VmtShader]["bumpmap"] : string.Empty;
                Color         = vmt[VmtShader].ContainsKey("$color") ? vmt[VmtShader]["$color"] : new SourceUtils.Color32(255, 255, 255, 255);
                RefractTint   = vmt[VmtShader].ContainsKey("$refracttint") ? vmt[VmtShader]["$refracttint"] : new SourceUtils.Color32(255, 255, 255, 255);
                SurfaceProp   = vmt[VmtShader].ContainsKey("$surfaceprop") ? vmt[VmtShader]["$surfaceprop"] : "grass";
                Include       = vmt[VmtShader].ContainsKey("include") ? vmt[VmtShader]["include"] : string.Empty;
                Alpha         = vmt[VmtShader].ContainsKey("$alpha") ? vmt[VmtShader]["$alpha"] : 1.0f;
                RefractAmount = vmt[VmtShader].ContainsKey("$refractamount") ? vmt[VmtShader]["$refractamount"] : 0.2f;
                CompileSky    = vmt[VmtShader].ContainsKey("%compilesky") ? vmt[VmtShader]["%compilesky"] : 0;
                break;
            }
        }
Esempio n. 5
0
        private VmtInfo GetVmtInfo(string vmtPath)
        {
            if (!_resourceLoader.ContainsFile(vmtPath))
            {
                return(null);
            }

            using var fs = _resourceLoader.OpenFile(vmtPath);
            var vmt    = ValveMaterialFile.FromStream(fs);
            var result = new VmtInfo(vmtPath, vmt);

            return(result);
        }
Esempio n. 6
0
        public static Material Get(ValveBspFile bsp, string path)
        {
            var vmt = bsp == null
                ? ValveMaterialFile.FromProvider(path, Program.Resources)
                : ValveMaterialFile.FromProvider(path, bsp.PakFile, Program.Resources);

            if (vmt == null)
            {
                return(null);
            }

            var mat = new Material();

            AddMaterialProperties(mat, vmt, path, bsp);

            return(mat);
        }
Esempio n. 7
0
        private static void AddMaterialProperties(Material mat, ValveMaterialFile vmt, string vmtPath, ValveBspFile bsp)
        {
            var shader = vmt.Shaders.First();
            var props  = vmt[shader];

            switch (shader.ToLower())
            {
            case "lightmappedgeneric":
            case "lightmappedreflective":
            {
                mat.Shader = "SourceUtils.Shaders.LightmappedGeneric";
                break;
            }

            case "lightmapped_4wayblend":     // todo: temp
            case "worldvertextransition":
            {
                mat.Shader = "SourceUtils.Shaders.Lightmapped2WayBlend";
                break;
            }

            case "worldtwotextureblend":     // todo: temp
            {
                mat.Shader = "SourceUtils.Shaders.WorldTwoTextureBlend";
                break;
            }

            case "vertexlitgeneric":
            {
                mat.Shader = "SourceUtils.Shaders.VertexLitGeneric";
                break;
            }

            case "unlittwotexture":
            case "unlitgeneric":
            case "monitorscreen":
            case "sprite":
            {
                mat.Shader = "SourceUtils.Shaders.UnlitGeneric";
                break;
            }

            case "water":
            {
                mat.Shader = "SourceUtils.Shaders.Water";
                break;
            }

            case "splinerope":
            case "cable":
            {
                mat.Shader = "SourceUtils.Shaders.SplineRope";
                break;
            }

            default:
            {
                mat.Shader = shader;
                break;
            }
            }

            foreach (var name in props.Keys)
            {
                var value = props[name];
                switch (name.ToLower())
                {
                case "$basetexture":
                    mat.SetTextureUrl("basetexture", GetTextureUrl(value, vmtPath, bsp));
                    break;

                case "$hdrcompressedtexture":
                    mat.SetTextureUrl("hdrcompressedtexture", GetTextureUrl(value, vmtPath, bsp));
                    break;

                case "$texture2":
                case "$basetexture2":
                    mat.SetTextureUrl("basetexture2", GetTextureUrl(value, vmtPath, bsp));
                    break;

                case "$detail":
                    mat.SetTextureUrl("detail", GetTextureUrl(value, vmtPath, bsp));
                    break;

                case "$blendmodulatetexture":
                    mat.SetTextureUrl("blendModulateTexture", GetTextureUrl(value, vmtPath, bsp));
                    break;

                case "$normalmap":
                    mat.SetTextureUrl("normalMap", GetTextureUrl(value, vmtPath, bsp));
                    break;

                case "$simpleoverlay":
                    mat.SetTextureUrl("simpleOverlay", GetTextureUrl(value, vmtPath, bsp));
                    break;

                case "$nofog":
                    mat.SetBoolean("fogEnabled", !value);
                    break;

                case "$alphatest":
                    if (!Program.BaseOptions.Untextured)
                    {
                        mat.SetBoolean("alphaTest", value);
                    }
                    break;

                case "$translucent":
                    mat.SetBoolean("translucent", value);
                    break;

                case "$refract":
                    mat.SetBoolean("refract", value);
                    break;

                case "$alpha":
                    mat.SetNumber("alpha", value);
                    break;

                case "$detailscale":
                    mat.SetNumber("detailScale", value);
                    break;

                case "$nocull":
                    mat.SetBoolean("cullFace", !value);
                    break;

                case "$notint":
                    mat.SetBoolean("tint", !value);
                    break;

                case "$blendtintbybasealpha":
                    mat.SetBoolean("baseAlphaTint", value);
                    break;

                case "$fogstart":
                    mat.SetNumber("fogStart", value);
                    break;

                case "$fogend":
                    mat.SetNumber("fogEnd", value);
                    break;

                case "$fogcolor":
                    mat.SetColor("fogColor", new MaterialColor(value));
                    break;

                case "$lightmapwaterfog":
                    mat.SetBoolean("fogLightmapped", value);
                    break;

                case "$reflecttint":
                    mat.SetColor("reflectTint", new MaterialColor(value));
                    break;

                case "$refracttint":
                    mat.SetColor("refractTint", new MaterialColor(value));
                    break;

                case "$refractamount":
                    mat.SetNumber("refractAmount", value);
                    break;

                case "$selfillum":
                    mat.SetBoolean("emission", value);
                    break;

                case "$selfillumtint":
                    mat.SetColor("emissionTint", new MaterialColor(value));
                    break;

                default:
                    if (Program.BaseOptions.DebugMaterials)
                    {
                        mat.SetString($"{name}", value);
                    }
                    break;
                }
            }
        }
Esempio n. 8
0
        static FoamModel LoadMdl(string FilePath)
        {
            FilePath = FilePath.Substring(0, FilePath.Length - Path.GetExtension(FilePath).Length);

            StudioModelFile Mdl = StudioModelFile.FromProvider(FilePath + ".mdl", VFS);

            if (Mdl == null)
            {
                throw new FileNotFoundException("File not found", FilePath + ".mdl");
            }

            ValveVertexFile   Verts = ValveVertexFile.FromProvider(FilePath + ".vvd", VFS);
            ValveTriangleFile Tris  = ValveTriangleFile.FromProvider(FilePath + ".dx90.vtx", Mdl, Verts, VFS);


            // Foam stuff

            List <FoamMaterial> FoamMaterials = new List <FoamMaterial>();

            string[] TexNames = Mdl.TextureNames.ToArray();

            for (int i = 0; i < Mdl.MaterialCount; i++)
            {
                string MatName      = Mdl.GetMaterialName(i, VFS);
                string ShortMatName = Path.GetFileNameWithoutExtension(MatName);

                ValveMaterialFile VMF = ValveMaterialFile.FromProvider(MatName, VFS);
                FoamMaterials.Add(new FoamMaterial(ShortMatName, new FoamTexture[] { new FoamTexture(TexNames[i], FoamTextureType.Diffuse) }));
            }

            List <FoamMesh> FoamMeshes = new List <FoamMesh>();
            List <FoamBone> FoamBones  = new List <FoamBone>();

            StudioModelFile.StudioBone[] Bones = Mdl.GetBones();
            for (int i = 0; i < Bones.Length; i++)
            {
                string BoneName = Mdl.GetBoneName(i);
                FoamBones.Add(new FoamBone(BoneName, Bones[i].Parent, Matrix4x4.Identity));
            }

            // BODIES
            for (int BodyPartIdx = 0; BodyPartIdx < Mdl.BodyPartCount; BodyPartIdx++)
            {
                StudioModelFile.StudioModel[] StudioModels = Mdl.GetModels(BodyPartIdx).ToArray();

                // MODELS
                for (int ModelIdx = 0; ModelIdx < StudioModels.Length; ModelIdx++)
                {
                    ref StudioModelFile.StudioModel StudioModel  = ref StudioModels[ModelIdx];
                    StudioModelFile.StudioMesh[]    StudioMeshes = Mdl.GetMeshes(ref StudioModel).ToArray();

                    // MESHES
                    for (int MeshIdx = 0; MeshIdx < StudioMeshes.Length; MeshIdx++)
                    {
                        ref StudioModelFile.StudioMesh StudioMesh = ref StudioMeshes[MeshIdx];

                        StudioVertex[] StudioVerts = new StudioVertex[Tris.GetVertexCount(BodyPartIdx, ModelIdx, 0, MeshIdx)];
                        Tris.GetVertices(BodyPartIdx, ModelIdx, 0, MeshIdx, StudioVerts);

                        int[] Indices = new int[Tris.GetIndexCount(BodyPartIdx, ModelIdx, 0, MeshIdx)];
                        Tris.GetIndices(BodyPartIdx, ModelIdx, 0, MeshIdx, Indices);


                        // Foam converted
                        List <FoamVertex3> FoamVerts = new List <FoamVertex3>(StudioVerts.Select(V => {
                            // TODO: CCW
                            nVector2 UV = new nVector2(V.TexCoordX, V.TexCoordY);
                            return(new FoamVertex3(Conv(V.Position), UV, nVector2.Zero, Conv(V.Normal), nVector3.Zero, FoamColor.White));
                        }));

                        List <FoamBoneInfo> FoamInfo = new List <FoamBoneInfo>(StudioVerts.Select(V => {
                            FoamBoneInfo Info = new FoamBoneInfo();
                            Info.Bone1        = V.BoneWeights.Bone0;
                            Info.Bone2        = V.BoneWeights.Bone1;
                            Info.Bone3        = V.BoneWeights.Bone1;

                            Info.Weight1 = V.BoneWeights.Weight0;
                            Info.Weight2 = V.BoneWeights.Weight1;
                            Info.Weight3 = V.BoneWeights.Weight2;
                            return(Info);
                        }));

                        List <ushort> FoamInds = new List <ushort>(Indices.Select(I => (ushort)I));

                        if (ConvertToCCW)
                        {
                            FoamInds.Reverse();
                        }

                        FoamMeshes.Add(new FoamMesh(FoamVerts.ToArray(), FoamInds.ToArray(), FoamInfo.ToArray(), StudioModel.Name + ";" + MeshIdx, StudioMesh.Material));

                        /*List<FoamVertex3> Vts = new List<FoamVertex3>();
                         * for (int i = 0; i < Indices.Length; i++) {
                         *      ref StudioVertex V = ref StudioVerts[Indices[i]];
                         *      Vts.Add(new Vertex3(new Vector3(V.Position.X, V.Position.Y, V.Position.Z), new Vector2(V.TexCoordX, 1.0f - V.TexCoordY), Color.White));
                         * }*/

                        /*string MatName = MaterialNames[StudioMesh.Material];
                         * Material Mat = Engine.GetMaterial(MatName);
                         *
                         * if (Mat == Engine.GetMaterial("error")) {
                         *      Mat = ValveMaterial.CreateMaterial(MatName);
                         *
                         *      if (Mat != Engine.GetMaterial("error"))
                         *              Engine.RegisterMaterial(Mat);
                         * }
                         *
                         * libTechMesh Msh = new libTechMesh(Vts.ToArray(), Mat);
                         * Msh.Name = StudioModel.Name;
                         * Model.AddMesh(Msh);*/
                    }
                }
Esempio n. 9
0
 public VmtInfo(string vmtName, ValveMaterialFile vmt)
 {
     VmtName = vmtName;
     Parse(vmt);
 }
Esempio n. 10
0
    private Material VmtToMaterial(ResourceLoader resourceLoader, ValveMaterialFile vmt, string vmtPath)
    {
        string vmtShader     = default;
        bool   lightmapped   = default;
        bool   alphaTest     = default;
        bool   translucent   = default;
        bool   noCull        = default;
        bool   transition    = default;
        string baseTex       = default;
        string baseTex2      = default;
        string bumpMap       = default;
        string surfaceProp   = default;
        string include       = default;
        float  alpha         = default;
        float  refractAmount = default;
        int    compileSky    = default;

        SourceUtils.Color32 color       = default;
        SourceUtils.Color32 refractTint = default;

        var e = vmt.Shaders.GetEnumerator();

        while (e.MoveNext())
        {
            vmtShader     = e.Current.ToLower();
            lightmapped   = vmtShader == "lightmappedgeneric" || vmtShader == "worldvertextransition";
            transition    = vmtShader == "worldvertextransition";
            alphaTest     = vmt[vmtShader].ContainsKey("$alphatest") ? vmt[vmtShader]["$alphatest"] : false;
            translucent   = vmt[vmtShader].ContainsKey("$translucent") ? vmt[vmtShader]["$translucent"] : false;
            noCull        = vmt[vmtShader].ContainsKey("$nocull") ? vmt[vmtShader]["$nocull"] : false;
            baseTex       = vmt[vmtShader].ContainsKey("$basetexture") ? vmt[vmtShader]["$basetexture"] : string.Empty;
            baseTex2      = vmt[vmtShader].ContainsKey("$basetexture2") ? vmt[vmtShader]["$basetexture2"] : string.Empty;
            bumpMap       = vmt[vmtShader].ContainsKey("bumpmap") ? vmt[vmtShader]["bumpmap"] : string.Empty;
            color         = vmt[vmtShader].ContainsKey("$color") ? vmt[vmtShader]["$color"] : new SourceUtils.Color32(255, 255, 255, 255);
            refractTint   = vmt[vmtShader].ContainsKey("$refracttint") ? vmt[vmtShader]["$refracttint"] : new SourceUtils.Color32(255, 255, 255, 255);
            surfaceProp   = vmt[vmtShader].ContainsKey("$surfaceprop") ? vmt[vmtShader]["$surfaceprop"] : "grass";
            include       = vmt[vmtShader].ContainsKey("include") ? vmt[vmtShader]["include"] : string.Empty;
            alpha         = vmt[vmtShader].ContainsKey("$alpha") ? vmt[vmtShader]["$alpha"] : 1.0f;
            refractAmount = vmt[vmtShader].ContainsKey("$refractamount") ? vmt[vmtShader]["$refractamount"] : 0.2f;
            compileSky    = vmt[vmtShader].ContainsKey("%compilesky") ? vmt[vmtShader]["%compilesky"] : 0;
            break;
        }

        if (!string.IsNullOrEmpty(include))
        {
            using (var fs = resourceLoader.OpenFile(include))
            {
                var includedVmt = ValveMaterialFile.FromStream(fs);
                return(VmtToMaterial(resourceLoader, includedVmt, include));
            }
        }

        Object   materialResource;
        Material result;

        materialResource = surfaceProp == "water"
            ? _options.WaterMaterial
            : _options.FaceMaterial;

        if (materialResource == null)
        {
            var shader = Shader.Find("BSP/Lightmapped")
                         ?? Shader.Find("HDRP/Lit")
                         ?? Shader.Find("URP/Lit")
                         ?? Shader.Find("Lightweight Render Pipeline/Lit")
                         ?? Shader.Find("Standard");
            result = new Material(shader);
        }
        else
        {
            result = GameObject.Instantiate(materialResource) as Material;
        }

        //result.SetTexture("_MainTex", LoadTexture(resourceLoader, baseTex));
        result.mainTexture = LoadTexture(resourceLoader, baseTex);
        result.SetFloat("_Smoothness", 0);
        result.SetFloat("_Metallic", .8f);
        result.name = vmtPath;

        if (!string.IsNullOrEmpty(bumpMap))
        {
            result.SetTexture("_BumpMap", LoadTexture(resourceLoader, bumpMap));
        }

        if (transition)
        {
            result.SetTexture("_MainTex2", LoadTexture(resourceLoader, baseTex2));
        }

        if (translucent)
        {
            var baseColor = result.GetColor("_BaseColor");
            baseColor.a = alpha;
            result.SetColor("_BaseColor", baseColor);
            result.SetFloat("_SurfaceType", 1);
        }

        return(result);
    }
Esempio n. 11
0
        public static JToken SerializeVmt(HttpListenerRequest request, ValveBspFile bsp, ValveMaterialFile vmt, string path)
        {
            // TODO: Proper patch shader support
            var firstShader = vmt.Shaders.FirstOrDefault();
            var shader      = firstShader;

            if (shader == null)
            {
                return(null);
            }

            var propArray = new JArray();
            var vmtDir    = Path.GetDirectoryName(path).Replace('\\', '/');

            SerializeShaderProperties(request, bsp, vmt, ref shader, vmtDir, propArray);

            var variant = "Generic";

            if (propArray.Any(x => (string)x["name"] == "translucent" && (bool)x["value"]))
            {
                variant = "Translucent";
            }

            var shaderName = $"Lightmapped{variant}";

            switch (shader.ToLower())
            {
            case "lightmappedgeneric":
                shaderName = $"Lightmapped{variant}";
                break;

            case "vertexlitgeneric":
                shaderName = $"VertexLit{variant}";
                break;

            case "unlittwotexture":     // TODO
            case "unlitgeneric":
                shaderName = $"Unlit{variant}";
                break;

            case "worldvertextransition":
                shaderName = "Lightmapped2WayBlend";
                break;

            case "water":
                shaderName = "Water";
                AddBooleanProperty(propArray, "refract", true);
                break;
            }

            return(new JObject
            {
                { "shader", shaderName },
                { "properties", propArray },
#if DEBUG
                { "debug", new JObject
                  {
                      { "shader", shader },
                      { "properties", new JArray(vmt[firstShader].PropertyNames.Select(x => new JArray(x, vmt[firstShader][x]))) }
                  } }
#endif
            });
        }
Esempio n. 12
0
 public static JToken SerializeVmt(HttpListenerRequest request, ValveMaterialFile vmt, string path)
 {
     return(SerializeVmt(request, null, vmt, path));
 }
Esempio n. 13
0
        private static void SerializeShaderProperties(HttpListenerRequest request, ValveBspFile bsp, ValveMaterialFile vmt, ref string shaderName, string vmtDir, JArray destArray)
        {
            if (!vmt.ContainsShader(shaderName))
            {
                shaderName = vmt.Shaders.FirstOrDefault();
            }

            var props = vmt[shaderName];

            foreach (var name in props.PropertyNames)
            {
                switch (name.ToLower())
                {
                case "include":
                {
                    var includePath = props[name];
                    var includeDir  = Path.GetDirectoryName(includePath);
                    var includeVmt  = OpenVmt(bsp, includePath);
                    SerializeShaderProperties(request, bsp, includeVmt, ref shaderName, includeDir, destArray);
                    break;
                }

                case "$basetexture":
                    AddTexture2DProperty(destArray, "baseTexture", GetTextureUrl(request, bsp, props[name], vmtDir));
                    break;

                case "$texture2":
                case "$basetexture2":
                    AddTexture2DProperty(destArray, "baseTexture2", GetTextureUrl(request, bsp, props[name], vmtDir));
                    break;

                case "$blendmodulatetexture":
                    AddTexture2DProperty(destArray, "blendModulateTexture", GetTextureUrl(request, bsp, props[name], vmtDir));
                    break;

                case "$normalmap":
                    AddTexture2DProperty(destArray, "normalMap", GetTextureUrl(request, bsp, props[name], vmtDir));
                    break;

                case "$simpleoverlay":
                    AddTexture2DProperty(destArray, "simpleOverlay", GetTextureUrl(request, bsp, props[name], vmtDir));
                    break;

                case "$nofog":
                    AddBooleanProperty(destArray, "noFog", props.GetBoolean(name));
                    break;

                case "$alphatest":
                    AddBooleanProperty(destArray, "alphaTest", props.GetBoolean(name));
                    break;

                case "$translucent":
                    AddBooleanProperty(destArray, "translucent", props.GetBoolean(name));
                    break;

                case "$refract":
                    AddBooleanProperty(destArray, "refract", props.GetBoolean(name));
                    break;

                case "$alpha":
                    AddNumberProperty(destArray, "alpha", props.GetSingle(name));
                    break;

                case "$nocull":
                    AddBooleanProperty(destArray, "noCull", props.GetBoolean(name));
                    break;

                case "$notint":
                    AddBooleanProperty(destArray, "noTint", props.GetBoolean(name));
                    break;

                case "$blendtintbybasealpha":
                    AddBooleanProperty(destArray, "baseAlphaTint", props.GetBoolean(name));
                    break;

                case "$fogstart":
                    AddNumberProperty(destArray, "fogStart", props.GetSingle(name));
                    break;

                case "$fogend":
                    AddNumberProperty(destArray, "fogEnd", props.GetSingle(name));
                    break;

                case "$fogcolor":
                    AddColorProperty(destArray, "fogColor", props.GetColor(name));
                    break;

                case "$reflecttint":
                    AddColorProperty(destArray, "reflectTint", props.GetColor(name));
                    break;

                case "$refractamount":
                    AddNumberProperty(destArray, "refractAmount", props.GetSingle(name));
                    break;
                }
            }
        }