Example #1
0
        List <ShaderAsset> loadShaders()
        {
            var shaders = new List <ShaderAsset>();

            if (!Directory.Exists(metadataPath + "Shaders"))
            {
                Directory.CreateDirectory(metadataPath + "Shaders");
            }

            foreach (var filename in Directory.EnumerateFiles(metadataPath + "Shaders"))
            {
                var metadata = File.ReadAllLines(filename);

                var shader = new ShaderAsset();

                shader.Name             = System.IO.Path.GetFileNameWithoutExtension(filename);
                shader.Description      = metadata[0].Split('=')[1].Trim();
                shader.Combination      = (ShaderCombination)Enum.Parse(typeof(ShaderCombination), metadata[1].Split('=')[1].Trim());
                shader.LastUpdated      = parseLastUpdatedDate(metadata[2].Split('=')[1].Trim(), "shader", shader.Name);
                shader.SourceFilename   = metadata[3].Split('=')[1].Trim();
                shader.ImportedFilename = metadata[4].Split('=')[1].Trim();
                shader.ImporterVersion  = int.Parse(metadata[5].Split('=')[1].Trim());

                shaders.Add(shader);
            }

            return(shaders);
        }
Example #2
0
        public ShaderAssetControl(ShaderAsset asset)
        {
            InitializeComponent();

            Handler = new ShaderAssetControlHandler(asset, this);

            Data.DataContext = asset;
        }
        private IMaterialAsset TransformMaterial(Material material, string id, ReaderContext context)
        {
            var materialAsset = new MaterialAsset(id);

            materialAsset.AlphaCutoff = material.AlphaCutoff;
            materialAsset.Alpha       = GetAlphaMode(material.Alpha);
            materialAsset.DoubleSided = material.DoubleSided;
            materialAsset.Unlit       = material.Unlit;

            var shaderParameters = material.Channels.Select(_ => TransformShaderParameter(_, context)).SelectMany(_ => _)
                                   .ToDictionary(_ => _.Key, _ => _);
            var metallicRoughness  = 0;
            var specularGlossiness = 0;

            foreach (var shaderParameter in shaderParameters)
            {
                switch (shaderParameter.Key)
                {
                case ShaderParameterKey.BaseColorFactor:
                case ShaderParameterKey.BaseColorTexture:
                case ShaderParameterKey.MetallicFactor:
                case ShaderParameterKey.MetallicRoughnessTexture:
                    ++metallicRoughness;
                    break;

                case ShaderParameterKey.DiffuseFactor:
                case ShaderParameterKey.DiffuseTexture:
                case ShaderParameterKey.SpecularFactor:
                case ShaderParameterKey.GlossinessFactor:
                case ShaderParameterKey.SpecularGlossinessTexture:
                    ++specularGlossiness;
                    break;
                }
            }

            if (metallicRoughness > 0 && specularGlossiness == 0)
            {
                var shader = new MetallicRoughnessShader();
                materialAsset.Shader = shader;
            }
            else if (metallicRoughness == 0 && specularGlossiness >= 0)
            {
                var shader = new SpecularGlossinessShader();
                materialAsset.Shader = shader;
            }
            else
            {
                var shader = new ShaderAsset();
                materialAsset.Shader = shader;
            }

            foreach (var shaderParameter in shaderParameters)
            {
                materialAsset.Shader.Set(shaderParameter.Value);
            }

            return(materialAsset);
        }
 public VanillaInputLayout(ShaderAsset shader)
 {
     InputLayout  = new InputLayout(shader.Device, shader.Signature, new[]
     {
         new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0),
         new InputElement("NORMAL", 0, Format.R32G32B32A32_Float, 16, 0),
         new InputElement("COLOR", 0, Format.R32G32B32A32_Float, 32, 0),
         new InputElement("TEXCOORD", 0, Format.R32G32B32A32_Float, 48, 0),
     });
 }
Example #5
0
        //FOR TESTING
        public bool CreateShaderGraphAsset(string name, SharpDX.D3DCompiler.ShaderBytecode bytecode)
        {
            BaseAsset asset = new ShaderAsset()
            {
                Name       = name,
                ShaderType = ShaderTypeEnum.Pixel,
                Bytecode   = bytecode,
            };

            return(FSWorker.CreateAssetFile(asset, true));
        }
        static internal void createShaderMetadata(ShaderAsset shader)
        {
            var metadata = new StringBuilder();

            metadata.AppendLine("Description= " + shader.Description)
            .AppendLine("Combination= " + shader.Combination.ToString())
            .AppendLine("LastUpdated= " + shader.LastUpdated.ToString("o"))
            .AppendLine("SourceFilename= " + shader.SourceFilename)
            .AppendLine("ImportedFilename= " + shader.ImportedFilename)
            .AppendLine("ImporterVersion= " + shader.ImporterVersion);

            File.WriteAllText(MetadataPath + "Shaders/" + shader.Name + ".meta", metadata.ToString());
        }
        public override Effect Init(EffectDescription description)
        {
            base.Init(description);

            var mode = _demo.SetupModel.Mode;

            _greetingsRenderTarget = _disposer.Add(new RenderTarget(
                device: _demo.Device,
                width: mode.Width,                    // TODO(mstrandh): Honor setupmodel?
                height: mode.Height,                   // TODO(mstrandh): Honor setupmodel?
                sampleCount: 1,                 // TODO(mstrandh): Honor setupmodel?
                sampleQuality: 0,               // TODO(mstrandh): Honor setupmodel?
                format: Format.R8G8B8A8_UNorm   // TODO(mstrandh): Honor setupmodel?
            ));

            CreateCylinderBuffers();
            var texture = _textures[0];
            _textureHeight = texture.Texture.Description.Height;

            _tubeVertexShader = _demo.ShaderManager["greetingsTube.vs.cso"];
            _tubePixelShader = _demo.ShaderManager["greetingsTube.ps.cso"];

            _tubeInputLayout = _disposer.Add(new InputLayout(_demo.Device, _tubeVertexShader.Signature, new[]
            {
                new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0),
                new InputElement("TEXCOORD", 0, Format.R32G32_Float, 12, 0),
            }));

            _greetingsTexture = _resourceViews[0];
            _renderedCylinderTexture = _greetingsRenderTarget.ShaderResourceView;

            // Create the depth buffer
            var depthBuffer = _disposer.Add(new Texture2D(_demo.Device, new Texture2DDescription
            {
                Format = Format.D32_Float_S8X24_UInt,
                ArraySize = 1,
                MipLevels = 1,
                Width = mode.Width,
                Height = mode.Height,
                SampleDescription = new SampleDescription { Count = 1, Quality = 0 },
                Usage = ResourceUsage.Default,
                BindFlags = BindFlags.DepthStencil,
                CpuAccessFlags = CpuAccessFlags.None,
                OptionFlags = ResourceOptionFlags.None
            }));

            // Create the depth buffer view
            _greetingsDepthView = _disposer.Add(new DepthStencilView(_demo.Device, depthBuffer));

            return this;
        }
        public VanillaEffect Init()
        {
            // vertex stuff
            VertexShader = _demo.ShaderManager["vanillaPlane.vs.cso"];
            InputLayout = _disposer.Add(new VanillaInputLayout(VertexShader));
            PrimitiveTopology = PrimitiveTopology.TriangleList;

            // pixel stuff
            // todo: perhaps add pixelshader
            PixelShader = null;

            //
            return this;
        }
Example #9
0
        public void Load()
        {
            // Load assets
            _ubuntuFontAsset = Engine.AssetLoader.Get <FontAsset>(RESOURCE_NAME_FONT_UBUNTU).GetAtlas(12);
            _tileTexture     = Engine.AssetLoader.Get <TextureAsset>(RESOURCE_NAME_TEXTURE_TILE_OUTLINED_CARDINAL);
            _shader          = Engine.AssetLoader.Get <ShaderAsset>(RESOURCE_NAME_SHADER);

            // tile count is vertexCount-1, because end vertices are included in only 1 tile (per axis).
            tiles = new Quadrilateral[MAP_WIDTH - 1, MAP_HEIGHT - 1];

            // Generate a random-ish height map.
            for (var x = 0; x < MAP_WIDTH; x++)
            {
                for (var y = 0; y < MAP_HEIGHT; y++)
                {
                    // Assign in height map @ appropriate position, storing for later use
                    _heightMap[x, y] = _random.Next((int)TileSize.Z);
                }
            }


            for (var y = 0; y < MAP_HEIGHT - 1; y++)
            {
                for (var x = 0; x < MAP_WIDTH - 1; x++)
                {
                    // Assign in height map @ appropriate position, storing for later use
                    var quad = new Quadrilateral(
                        Vector3.Transform(new Vector3(x * TileSize.X, y * TileSize.Y, _heightMap[x, y]), _rotationMatrix),
                        Vector3.Transform(new Vector3((x + 1) * TileSize.X, y * TileSize.Y, _heightMap[x + 1, y]), _rotationMatrix),
                        Vector3.Transform(new Vector3((x + 1) * TileSize.X, (y + 1) * TileSize.Y, _heightMap[x + 1, y + 1]), _rotationMatrix),
                        Vector3.Transform(new Vector3(x * TileSize.X, (y + 1) * TileSize.Y, _heightMap[x, y + 1]), _rotationMatrix)
                        );
                    tiles[x, y] = quad;
                }
            }

            Rectangle boundsOfMap = Rectangle.BoundsFromPolygonPoints(new[]
            {
                tiles[0, 0].Vertex0.ToVec2(),
                tiles[MAP_WIDTH - 2, 0].Vertex1.ToVec2(),
                tiles[MAP_WIDTH - 2, MAP_HEIGHT - 2].Vertex2.ToVec2(),
                tiles[0, MAP_HEIGHT - 2].Vertex3.ToVec2(),
            });

            quadTree = new QuadTree <Quadrilateral>(boundsOfMap, 100);
            foreach (var tile in tiles)
            {
                quadTree.Add(tile);
            }
        }
        private void SetupDefaultShader(Material material, ShaderAsset shader, WriterContext context)
        {
            if (TrySetupTexture(material, "Normal", shader.NormalTexture,
                                context))
            {
                material.WithChannelParameter("Normal", new Vector4(shader.NormalTextureScale, 0, 0, 0));
            }
            if (TrySetupTexture(material, "Occlusion", shader.OcclusionTexture,
                                context))
            {
                material.WithChannelParameter("Occlusion", new Vector4(shader.OcclusionTextureStrength, 0, 0, 0));
            }

            TrySetupTexture(material, "Emissive", shader.EmissiveTexture, context);
            material.WithChannelParameter("Emissive", new Vector4(shader.EmissiveFactor, 0));
        }
Example #11
0
        /// <summary>
        /// Unload previously loaded shader
        /// </summary>
        /// <param name="asset">Shader asset</param>
        public void ShaderUnload(ShaderAsset asset)
        {
            if (asset == null)
            {
                return;
            }

            // Abort any existing async load for this asset
            AbortAsyncShaderLoad(asset);

            asset.InternalSetErrorStatus(RB.AssetStatus.Invalid, RB.Result.Undefined);

            if (asset.shader != null)
            {
                asset.shader = null;
            }
        }
        public void Initialize(ShaderAsset asset)
        {
            ShaderName.Text = asset.AssetName;

            bool isPathValid = asset.EditorPath.IsPathValid();

            string basePath = isPathValid ? Path.GetFileName(asset.EditorPath) : asset.EditorPath;

            VertexFileName.Text   = isPathValid ? basePath.Replace(".glsl", "_vertex.glsl") : asset.EditorPath;
            FragmentFileName.Text = isPathValid ? basePath.Replace(".glsl", "_fragment.glsl") : asset.EditorPath;

            if (isPathValid)
            {
                PreviewVertexTextBox.Text   = File.ReadAllText(asset.EditorPath.Replace(".glsl", "_vertex.glsl"));
                PreviewFragmentTextBox.Text = File.ReadAllText(asset.EditorPath.Replace(".glsl", "_fragment.glsl"));
            }
        }
Example #13
0
        static public void LoadShader(string assetName)
        {
            ShaderAsset SA = AssetsManagerInstance.GetManager().LoadAsset <ShaderAsset>(assetName);

            Debug.Log("AssetManager", SA.ShaderType.ToString() + " Shader " + assetName + " loaded. ");

            ShaderPlusSignature pack = new ShaderPlusSignature();
            ShaderBytecode      sb   = new ShaderBytecode(SA.Bytecode);

            switch (SA.ShaderType)
            {
            case ShaderTypeEnum.Vertex:
                pack.shader = new VertexShader(RenderBackend.Device, sb);
                break;

            case ShaderTypeEnum.Pixel:
                pack.shader = new PixelShader(RenderBackend.Device, sb);
                break;

            case ShaderTypeEnum.Geometry:
                pack.shader = new GeometryShader(RenderBackend.Device, sb);
                break;

            case ShaderTypeEnum.Compute:
                pack.shader = new ComputeShader(RenderBackend.Device, sb);
                break;

            case ShaderTypeEnum.Hull:
                pack.shader = new HullShader(RenderBackend.Device, sb);
                break;

            case ShaderTypeEnum.Domain:
                pack.shader = new DomainShader(RenderBackend.Device, sb);
                break;

            default:
                break;
            }
            ;
            SA = null;
            pack.shader.DebugName = assetName;
            pack.signature        = ShaderSignature.GetInputSignature(sb);
            Shaders.Add(assetName, pack);
        }
Example #14
0
        private void AbortAsyncShaderLoad(ShaderAsset asset)
        {
            /* Check if any of the existing pending async assets are loading for the same slot, if so we abandon them */
            for (int i = mASyncShaders.Count - 1; i >= 0; i--)
            {
                if (mASyncShaders[i].shaderAsset == asset)
                {
                    // If it was already loaded then be sure to release resources
                    if (mASyncShaders[i].shaderAsset.status == RB.AssetStatus.Ready)
                    {
                        mASyncShaders[i].shaderAsset.shader = null;
                    }

                    mASyncShaders.RemoveAt(i);

                    // There should never be more than one
                    break;
                }
            }
        }
        public virtual Effect Init(EffectDescription description)
        {
            // vertex stuff
            VertexShader = _demo.ShaderManager[description.VertexShaderName ?? "vanillaPlane.vs.cso"];
            InputLayout = _disposer.Add(new VanillaInputLayout(VertexShader));
            PrimitiveTopology = PrimitiveTopology.TriangleList;

            // pixel stuff
            var addressMode = GetTextureAddressMode();
            PixelShader = _demo.ShaderManager[description.PixelShaderName];
            _textures = (description.TextureNames ?? new string[0])
                .Select(textureName => string.IsNullOrEmpty(textureName) 
                    ? null 
                    : _demo.TextureManager[textureName])
                .ToArray();
            _resourceViews = _textures
                .Select(texture => (texture == null) 
                    ? null
                    : _disposer.Add(new ShaderResourceView(_demo.Device, texture.Texture)))
                .ToArray();
            _samplers = _textures
                .Select(texture => (texture == null)
                    ? null
                    : _disposer.Add(new SamplerState(_demo.Device, new SamplerStateDescription() {
                        Filter = Filter.Anisotropic,
                        AddressU = addressMode,
                        AddressV = addressMode,
                        AddressW = addressMode,
                        BorderColor = Color.Black,
                        ComparisonFunction = Comparison.Never,
                        MaximumAnisotropy = 1, // 16
                        MipLodBias = 0,
                        MinimumLod = 0,
                        MaximumLod = 1, // 16
                })))
                .ToArray();

            //
            return this;
        }
Example #16
0
        public void ShaderFallback()
        {
            ShaderAsset shader = null;

            // Create scene for this test.
            TestScene extScene = new TestScene
            {
                // Load a shader. Also tests whether loading of shaders within another thread works.
                ExtLoad = () => { shader = Engine.AssetLoader.Get <ShaderAsset>("Shaders/BrokenShaderWithFallback.xml"); },
                // Until will unload the shaders.
                ExtUnload = () => { Engine.AssetLoader.Destroy(shader.Name); },
                // Draw all textures in a grid.
                ExtDraw = () =>
                {
                    Engine.Renderer.SetShader(shader.Shader);

                    // Render a blank square.
                    Engine.Renderer.Render(new Vector3(10, 10, 0), new Vector2(10, 10), Color.White);

                    // Reset to default shader.
                    Engine.Renderer.SetShader();
                }
            };

            // Load scene.
            Helpers.LoadScene(extScene);

            // The shader should've loaded its fallback.
            Assert.NotNull(shader.Shader);
            Assert.True(shader.IsFallback);

            // Check if what is currently on screen is what is expected.
            Assert.Equal("PKlb8X5gkVtCWie3LIKpcYzEc5nNjr2Xrz/gCqs54yA=", Helpers.TakeScreenshot());

            // Cleanup.
            Helpers.UnloadScene();

            // Ensure the shaders are unloaded.
            Assert.DoesNotContain(shader.Name, Engine.AssetLoader.LoadedAssets.Select(x => x.Name));
        }
Example #17
0
        public void ShaderBrokenLoad()
        {
            ShaderAsset shader = null;

            // Create scene for this test.
            TestScene extScene = new TestScene
            {
                // Load a shader. Also tests whether loading of shaders within another thread works.
                ExtLoad = () => { shader = Engine.AssetLoader.Get <ShaderAsset>("Shaders/BrokenShader.xml"); },
                // Until will unload the shaders.
                ExtUnload = () => { Engine.AssetLoader.Destroy(shader.Name); },
                // Draw all textures in a grid.
                ExtDraw = () =>
                {
                    Engine.Renderer.SetShader(shader.Shader);

                    // Render a blank square.
                    Engine.Renderer.Render(new Vector3(10, 10, 0), new Vector2(10, 10), Color.White);

                    // Reset to default shader.
                    Engine.Renderer.SetShader();
                }
            };

            // Load scene.
            Helpers.LoadScene(extScene);

            // Even though the shader is broken, and it doesn't specify a fallback, it should load the compat shader.
            Assert.NotNull(shader.Shader);
            Assert.True(shader.IsFallback);

            // Check if what is currently on screen is what is expected.
            Assert.Equal("hC87cJBgdgR51XN76cIe14vmU1vlUWXgN3xxrp8WOdM=", Helpers.TakeScreenshot());

            // Cleanup.
            Helpers.UnloadScene();

            // Ensure the shaders are unloaded.
            Assert.DoesNotContain(shader.Name, Engine.AssetLoader.LoadedAssets.Select(x => x.Name));
        }
Example #18
0
        /// <summary>
        /// Load a shader asset from given location
        /// </summary>
        /// <param name="fileName">Filename</param>
        /// <param name="asset">Asset object to load into</param>
        /// <param name="source">Source type</param>
        /// <returns>True if successful</returns>
        public bool ShaderLoad(string fileName, ShaderAsset asset, RB.AssetSource source)
        {
            if (asset == null)
            {
                return(false);
            }

            asset.progress = 0;

            if (asset.shader != null)
            {
                asset.shader = null;
            }

            // Abort any existing async load for this asset
            AbortAsyncShaderLoad(asset);

            if (fileName == null)
            {
                Debug.LogError("Shader filename is null!");
                asset.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.BadParam);
                return(false);
            }

            fileName.Replace('\\', '/');

            var asyncResource = new RBShaderLoader();

            asyncResource.Load(fileName, asset, source);

            if (asset.status == RB.AssetStatus.Ready)
            {
                return(true);
            }

            // Always add to async queue, even if immediately failed. This gives out consistent async method of error checking
            mASyncShaders.Add(asyncResource);

            return(true);
        }
Example #19
0
 /// <summary>
 /// Set a custom shader effect
 /// </summary>
 /// <param name="shader">Shader asset to use</param>
 public void EffectShaderSet(ShaderAsset shader)
 {
     ParamsGet((RB.Effect)TOTAL_EFFECTS).Shader = shader;
 }
Example #20
0
 public static Shader CreateShader(this Graphics graphics, ShaderAsset shaderAsset)
 {
     return graphics.CreateShader (shaderAsset.Declaration, shaderAsset.Format, shaderAsset.Source);
 }
Example #21
0
 internal void setAsset(ShaderAsset newAsset)
 {
     asset            = newAsset;
     this.DataContext = asset;
 }
Example #22
0
 public void SetShader(ShaderAsset rShader)
 {
     Properties.Shader = rShader;
     Agk.SetObjectShader(Properties.ResourceNumber, Properties.Shader.ResourceNumber);
 }
Example #23
0
        public bool ImportShaderAsset(string Path, string Name, string EntryPoint, Dictionary <string, object> Macro, bool Rewrite, out BaseAsset assetRes)
        {
            string[] arr = Path.Split('.');
            string   ext = arr[arr.Length - 1].ToLower();

            assetRes = null;

            if (!shaderExts.Contains(ext))
            {
                return(false);
            }

            BaseAsset asset;

            ShaderTypeEnum ST = ShaderTypeEnum.Vertex;

            if (Name.EndsWith("VS"))
            {
                ST = ShaderTypeEnum.Vertex;
            }
            else if (Name.EndsWith("PS"))
            {
                ST = ShaderTypeEnum.Pixel;
            }
            else if (Name.EndsWith("GS"))
            {
                ST = ShaderTypeEnum.Geometry;
            }
            else if (Name.EndsWith("CS"))
            {
                ST = ShaderTypeEnum.Compute;
            }
            else if (Name.EndsWith("HS"))
            {
                ST = ShaderTypeEnum.Hull;
            }
            else if (Name.EndsWith("DS"))
            {
                ST = ShaderTypeEnum.Domain;
            }
            else
            {
                Console.WriteLine("Unknown shader type, please add correct postfix e.g. VS");
                return(false);
            }

            asset = new ShaderAsset()
            {
                Name       = Name,
                ShaderType = ST,
                EntryPoint = EntryPoint,
                Macro      = Macro,
            };

            if (!asset.ImportAsset(Path, ext))
            {
                return(false);
            }

            assetRes = asset;
            return(FSWorker.CreateAssetFile(asset, Rewrite));
        }
 static internal void deleteShaderMetadata(ShaderAsset shader)
 {
     deleteMetadata(shader, "Shaders/");
 }
Example #25
0
        public static bool UpdateAsset(Object asset,
                                       out string error, out string successMessage)
        {
            error          = "";
            successMessage = "";

            if (asset is MeshAsset)
            {
                MeshAsset mesh = asset as MeshAsset;

                var result = ImportMesh.import(mesh.SourceFilename, mesh.ImportedFilename);

                if (string.IsNullOrEmpty(result))
                {
                    successMessage = "Successfully updated mesh: " + mesh.Name;

                    mesh.LastUpdated = DateTime.Now;
                    AssetMetadata.createMeshMetadata(mesh);

                    return(true);
                }
            }
            else if (asset is TextureAsset)
            {
                TextureAsset texture = asset as TextureAsset;

                var result = ImportTexture.import(texture.Format, texture.ChannelMappings, texture.ImportedFilename);

                if (string.IsNullOrEmpty(result))
                {
                    successMessage      = "Successfully updated texture: " + texture.Name;
                    texture.LastUpdated = DateTime.Now;
                    AssetMetadata.createTextureMetadata(texture);

                    return(true);
                }
                else
                {
                    error = "ERROR: Updating texture: " + texture.Name + " failed!" + Environment.NewLine + result;
                }
            }
            else if (asset is ShaderAsset)
            {
                ShaderAsset shader = asset as ShaderAsset;

                var result = ImportShader.import(shader.SourceFilename, shader.ImportedFilename);

                if (string.IsNullOrEmpty(result))
                {
                    successMessage     = "Successfully updated shader: " + shader.Name;
                    shader.LastUpdated = DateTime.Now;
                    AssetMetadata.createShaderMetadata(shader);

                    return(true);
                }
                else
                {
                    error = "ERROR: Updating shader: " + shader.Name + " failed!" + Environment.NewLine + result;
                }
            }
            else if (asset is MaterialAsset)
            {
                MaterialAsset material = asset as MaterialAsset;

                var result = MaterialImporter.Import(material);

                if (result)
                {
                    successMessage       = "Successfully updated material: " + material.Name;
                    material.LastUpdated = DateTime.Now;
                    AssetMetadata.createMaterialMetadata(material);

                    return(true);
                }
                else
                {
                    error = "ERROR: Updating material: " + material.Name + " failed!" + Environment.NewLine;
                }
            }
            else if (asset is StateGroupAsset)
            {
                var stateGroup = asset as StateGroupAsset;

                var result = StateGroupImporter.Import(stateGroup);

                if (result)
                {
                    successMessage         = "Successfully updated state group: " + stateGroup.Name;
                    stateGroup.LastUpdated = DateTime.Now;
                    AssetMetadata.createStateGroupMetadata(stateGroup);

                    return(true);
                }
                else
                {
                    error = "ERROR: Updating state group: " + stateGroup.Name + " failed!" + Environment.NewLine + result;
                }
            }

            return(false);
        }
        /// <summary>
        /// Load shader asset
        /// </summary>
        /// <param name="path">Path to load from</param>
        /// <param name="asset">ShaderAsset to load into</param>
        /// <param name="source">Source type</param>
        /// <returns>True if successful</returns>
        public bool Load(string path, ShaderAsset asset, RB.AssetSource source)
        {
            shaderAsset = asset;
            this.path   = path;

            if (path == null)
            {
                shaderAsset.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.BadParam);
            }

            if (asset == null)
            {
                Debug.LogError("ShaderAsset is null!");
                return(false);
            }

            if (source == RB.AssetSource.Resources)
            {
                // Synchronous load
                if (path == null)
                {
                    Debug.LogError("Shader filename is null!");
                    shaderAsset.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.BadParam);
                    return(false);
                }

                var shader = Resources.Load <Shader>(path);

                if (shader == null)
                {
                    Debug.LogError("Could not load shader from " + path + ", make sure the resource is placed somehwere in Assets/Resources folder");
                    shaderAsset.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.NotFound);
                    return(false);
                }

                return(FinalizeShader(shader));
            }
            else if (source == RB.AssetSource.WWW)
            {
                // Not a supported source, should never get here
                shaderAsset.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.NotSupported);
                return(false);
            }
            else if (source == RB.AssetSource.ResourcesAsync)
            {
                // Finally attempt async resource load
                mResourceRequest = Resources.LoadAsync <Shader>(this.path);

                if (mResourceRequest == null)
                {
                    shaderAsset.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.NoResources);
                    return(false);
                }

                shaderAsset.progress = 0;
                shaderAsset.InternalSetErrorStatus(RB.AssetStatus.Loading, RB.Result.Pending);
            }
#if ADDRESSABLES_PACKAGE_AVAILABLE
            else if (source == RB.AssetSource.AddressableAssets)
            {
                // Exceptions on LoadAssetAsync can't actually be caught... this might work in the future so leaving it here
                try
                {
                    mAddressableRequest = Addressables.LoadAssetAsync <Shader>(this.path);
                }
                catch (UnityEngine.AddressableAssets.InvalidKeyException e)
                {
                    RBUtil.Unused(e);
                    shaderAsset.SetErrorStatus(RB.AssetStatus.Failed, RB.Result.NotFound);
                    return(false);
                }
                catch (Exception e)
                {
                    RBUtil.Unused(e);
                    shaderAsset.SetErrorStatus(RB.AssetStatus.Failed, RB.Result.Undefined);
                    return(false);
                }

                // Check for an immediate failure
                if (mAddressableRequest.Status == AsyncOperationStatus.Failed)
                {
                    Addressables.Release(mAddressableRequest);
                    shaderAsset.SetErrorStatus(RB.AssetStatus.Failed, RB.Result.Undefined);
                    return(false);
                }

                shaderAsset.SetErrorStatus(RB.AssetStatus.Loading, RB.Result.Pending);
                shaderAsset.progress = 0;

                return(true);
            }
#endif
            else
            {
                shaderAsset.InternalSetErrorStatus(RB.AssetStatus.Failed, RB.Result.NotSupported);
                return(false);
            }

            return(true);
        }