public static void CreateLightmapTexture(GLContext control, AglLightMap aglLightMap,
                                                 EnvironmentGraphics environmentSettings, string name, GLTextureCube output)
        {
            var lightMapEnv = aglLightMap.LightAreas.FirstOrDefault(x => x.Settings.Name == name);

            if (lightMapEnv == null)
            {
                return;
            }

            //Force generate mipmaps to update the mip allocation so mips can be assigned.
            output.Bind();
            GL.GenerateMipmap(GenerateMipmapTarget.TextureCubeMap);
            GL.BindTexture(TextureTarget.TextureCubeMap, 0);
            GL.Enable(EnableCap.TextureCubeMapSeamless);

            if (FilterLevel0 == null)
            {
                Init(output.Width);
            }

            int CUBE_SIZE = output.Width;

            FilterLevel0.Bind();
            LoadCubemapLevel(control, CUBE_SIZE, 0, aglLightMap, environmentSettings, lightMapEnv, output.ID);
            FilterLevel0.Unbind();

            FilterLevel1.Bind();
            LoadCubemapLevel(control, CUBE_SIZE / 2, 1, aglLightMap, environmentSettings, lightMapEnv, output.ID);
            FilterLevel1.Unbind();

            output.SaveDDS($"LIGHTMAP{name}.dds");
        }
Esempio n. 2
0
        public void GenerateLightmap(GLContext control, EnvironmentGraphics env, string name)
        {
            GLTextureCube output = GLTextureCube.CreateEmptyCubemap(
                32, PixelInternalFormat.Rgb32f, PixelFormat.Rgb, PixelType.Float, 2);

            //Allocate mip data. Need 2 seperate mip levels
            output.Bind();
            output.MinFilter = TextureMinFilter.LinearMipmapLinear;
            output.MagFilter = TextureMagFilter.Linear;
            output.UpdateParameters();
            output.GenerateMipmaps();
            output.Unbind();

            if (Lightmaps.ContainsKey(name))
            {
                Lightmaps[name]?.Dispose();
            }

            if (!Lightmaps.ContainsKey(name))
            {
                Lightmaps.Add(name, output);
            }

            LightmapManager.CreateLightmapTexture(control, this, env, name, output);

            Lightmaps[name] = output;
        }
        static void InitTextures()
        {
            CubeMapTextureID = GLTextureCubeArray.FromDDS(new DDS($"Resources\\CubemapHDR.dds"));

            DiffuseCubeTextureID = GLTextureCube.FromDDS(
                new DDS(new MemoryStream(Resources.CubemapLightmap)),
                new DDS(new MemoryStream(Resources.CubemapLightmapShadow)));

            SpecularCubeTextureID = GLTextureCube.CreateEmptyCubemap(32);

            LightingEngine.LightSettings.InitTextures();

            DepthShadowCascadeTextureID = GLTexture2D.FromBitmap(Resources.white);
            ProjectionTextureID         = GLTexture2D.FromBitmap(Resources.white);
            User1Texture = GLTexture2D.FromBitmap(Resources.white);

            //Adjust mip levels
            CubeMapTextureID.Bind();
            GL.TexParameter(CubeMapTextureID.Target, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
            GL.TexParameter(CubeMapTextureID.Target, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.LinearMipmapLinear);
            GL.TexParameter(CubeMapTextureID.Target, TextureParameterName.TextureBaseLevel, 0);
            GL.TexParameter(CubeMapTextureID.Target, TextureParameterName.TextureMaxLevel, 13);
            CubeMapTextureID.Unbind();

            DiffuseCubeTextureID.Bind();
            GL.TexParameter(CubeMapTextureID.Target, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
            GL.TexParameter(CubeMapTextureID.Target, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.LinearMipmapLinear);
            GL.TexParameter(DiffuseCubeTextureID.Target, TextureParameterName.TextureBaseLevel, 0);
            GL.TexParameter(DiffuseCubeTextureID.Target, TextureParameterName.TextureMaxLevel, 2);
            DiffuseCubeTextureID.Unbind();
        }
        static void FilterProbeVolume(GLContext control, GLTexture2D normalsMap, GLTextureCube diffuseCubemap,
                                      Vector4[] shData, int lightmapTexID, int size, int mipLevel)
        {
            if (frameBuffer == null)
            {
                Init(size);
            }

            if (frameBuffer.Width != size)
            {
                frameBuffer.Resize(size, size);
            }

            frameBuffer.Bind();
            GL.Viewport(0, 0, size, size);

            //attach face to fbo as color attachment
            for (int i = 0; i < 6; i++)
            {
                //Each fragment output is a cubemap face
                GL.FramebufferTexture2D(FramebufferTarget.Framebuffer,
                                        FramebufferAttachment.ColorAttachment0 + i,
                                        TextureTarget.TextureCubeMapPositiveX + i, lightmapTexID, mipLevel);
            }

            var shader = GlobalShaders.GetShader("PROBE");

            shader.Enable();

            var programID = shader.program;

            LoadUniforms(programID, shData);

            GL.ActiveTexture(TextureUnit.Texture0 + 1);
            normalsMap.Bind();
            shader.SetInt("sampler0", 1);

            GL.ActiveTexture(TextureUnit.Texture0 + 2);
            diffuseCubemap.Bind();
            shader.SetInt("sampler1", 2);

            //Draw once with 6 fragment outputs to form a cubemap
            GL.ClearColor(0, 0, 0, 1);
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

            ScreenQuadRender.Draw();

            var errorcheck = GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer);

            if (errorcheck != FramebufferErrorCode.FramebufferComplete)
            {
                throw new Exception(errorcheck.ToString());
            }

            frameBuffer.Unbind();
            GL.BindTexture(TextureTarget.TextureCubeMap, 0);
            GL.UseProgram(0);
        }
        public void UpdateProbeLighting(GLContext control)
        {
            return;

            if (!UpdateProbeMap || TurboNXRender.DiffuseLightmapTexture == null /*|| Transform.Position == Vector3.Zero*/)
            {
                return;
            }

            if (DiffuseProbeTexture == null)
            {
                DiffuseProbeTexture = GLTextureCube.CreateEmptyCubemap(
                    32, PixelInternalFormat.Rgb32f, PixelFormat.Rgb, PixelType.Float, 2);

                //Allocate mip data. Need 2 seperate mip levels
                DiffuseProbeTexture.Bind();
                DiffuseProbeTexture.GenerateMipmaps();
                DiffuseProbeTexture.Unbind();
            }


            Transform.Position = new Vector3(ProbeDebugger.Position.X, ProbeDebugger.Position.Y, ProbeDebugger.Position.Z);
            Transform.UpdateMatrix(true);

            var output = LightingEngine.LightSettings.UpdateProbeCubemap(control,
                                                                         DiffuseProbeTexture, new Vector3(
                                                                             ProbeDebugger.Position.X,
                                                                             ProbeDebugger.Position.Y,
                                                                             ProbeDebugger.Position.Z));

            if (output == null)
            {
                return;
            }

            ProbeDebugger.Generated = output.Generated;

            if (output.Generated)
            {
                ProbeDebugger.probeData = output.ProbeData;
            }

            ProbeDebugger.DiffuseProbeTexture = DiffuseProbeTexture;

            // DiffuseProbeTexture.SaveDDS("LIGHT_PROBE.dds");
            //  DiffuseProbeTexture.Save($"LIGHTMAP_PROBE.png");

            ProbeDebugger.ForceUpdate = false;
            UpdateProbeMap            = false;
        }
        static void InitTextures()
        {
            //Reflective cubemap
            CubeMapTexture = GLTextureCubeArray.FromDDS(new DDS($"Resources\\CubemapHDR.dds"));

            CubemapManager.InitDefault(CubeMapTexture);

            //Diffuse cubemap lighting
            //Map gets updated when an object moves using probe lighting.
            DiffuseLightmapTexture = GLTextureCube.FromDDS(
                new DDS(new MemoryStream(Resources.CubemapLightmap)),
                new DDS(new MemoryStream(Resources.CubemapLightmapShadow)));

            //Shadows
            //Channel usage:
            //Red - Dynamic shadows
            //Green - Static shadows (course)
            //Blue - Soft shading (under kart, dynamic AO?)
            //Alpha - Usually gray
            DepthShadowTexture = GLTexture2D.FromBitmap(Resources.white);

            DepthShadowCascadeTexture = GLTexture2D.FromBitmap(Resources.white);

            //Tire marks
            ProjectionTexture = GLTexture2D.FromBitmap(Resources.white);

            //Used for dynamic lights. Ie spot, point, kart lights
            //Dynamic lights are setup using the g buffer pass (normals) and depth information before material pass is drawn
            //Additional slices may be used for bloom intensity
            LightPPTexture = GLTexture2DArray.FromBitmap(Resources.black);

            //Depth information. Likely for shadows
            NormalizedLinearDepth = GLTexture2D.FromBitmap(Resources.black);

            //Adjust mip levels

            CubeMapTexture.Bind();
            GL.TexParameter(CubeMapTexture.Target, TextureParameterName.TextureBaseLevel, 0);
            GL.TexParameter(CubeMapTexture.Target, TextureParameterName.TextureMaxLevel, 13);
            CubeMapTexture.Unbind();

            DiffuseLightmapTexture.Bind();
            GL.TexParameter(DiffuseLightmapTexture.Target, TextureParameterName.TextureBaseLevel, 0);
            GL.TexParameter(DiffuseLightmapTexture.Target, TextureParameterName.TextureMaxLevel, 2);
            DiffuseLightmapTexture.Unbind();
        }
Esempio n. 7
0
        static void InitTextures()
        {
            //Cube maps
            DiffuseCubemapTexture = GLTextureCube.FromDDS(
                new DDS($"Resources\\CubemapIrradianceDefault.dds"));

            DiffuseCubemapTexture.Bind();
            DiffuseCubemapTexture.MagFilter = TextureMagFilter.Linear;
            DiffuseCubemapTexture.MinFilter = TextureMinFilter.Linear;
            DiffuseCubemapTexture.UpdateParameters();

            GL.TexParameter(DiffuseCubemapTexture.Target, TextureParameterName.TextureBaseLevel, 0);
            GL.TexParameter(DiffuseCubemapTexture.Target, TextureParameterName.TextureMaxLevel, 0);
            DiffuseCubemapTexture.Unbind();

            SpecularCubemapTexture = GLTextureCube.FromDDS(new DDS($"Resources\\CubemapDefault.dds"));

            SpecularCubemapTexture.Bind();
            SpecularCubemapTexture.MagFilter = TextureMagFilter.Linear;
            SpecularCubemapTexture.MinFilter = TextureMinFilter.LinearMipmapLinear;
            SpecularCubemapTexture.UpdateParameters();

            GL.TexParameter(SpecularCubemapTexture.Target, TextureParameterName.TextureBaseLevel, 0);
            GL.TexParameter(SpecularCubemapTexture.Target, TextureParameterName.TextureMaxLevel, 7);
            SpecularCubemapTexture.Unbind();

            //Shadows
            ShadowDepthNearTexture = GLTexture2D.FromBitmap(Resources.white);
            ShadowDepthFarTexture  = GLTexture2D.FromBitmap(Resources.white);
            ShadowDepthCharTexture = GLTexture2D.FromBitmap(Resources.white);

            //Extra
            ColorBufferTexture = GLTexture2D.FromBitmap(Resources.black);
            DepthBufferTexture = GLTexture2D.FromBitmap(Resources.black);
            HalfTone           = GLTexture2D.FromBitmap(Resources.dot);
        }
Esempio n. 8
0
        public static void CreateCubemap(GLContext control, GLTextureCube cubemapInput,
                                         GLTexture cubemapOutput, int layer)
        {
            int size = cubemapOutput.Width;

            Matrix4 projection = Matrix4.CreatePerspectiveFieldOfView(MathHelper.DegreesToRadians(90), 1.0f, 0.1f, 10.0f);

            Matrix4[] captureViews =
            {
                Matrix4.LookAt(new Vector3(0.0f, 0.0f, 0.0f), new Vector3(1.0f,   0.0f,  0.0f), new Vector3(0.0f, -1.0f,  0.0f)),
                Matrix4.LookAt(new Vector3(0.0f, 0.0f, 0.0f), new Vector3(-1.0f,  0.0f,  0.0f), new Vector3(0.0f, -1.0f,  0.0f)),
                Matrix4.LookAt(new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f,   1.0f,  0.0f), new Vector3(0.0f,  0.0f,  1.0f)),
                Matrix4.LookAt(new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f,  -1.0f,  0.0f), new Vector3(0.0f,  0.0f, -1.0f)),
                Matrix4.LookAt(new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f,   0.0f,  1.0f), new Vector3(0.0f, -1.0f,  0.0f)),
                Matrix4.LookAt(new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f,   0.0f, -1.0f), new Vector3(0.0f, -1.0f,  0.0f)),
            };

            GL.BindTexture(TextureTarget.TextureCubeMap, 0);

            //Bind the cubemap's texture into a filtered quad.
            //Bind the drawn filter to a cubemap array layer
            Framebuffer frameBuffer = new Framebuffer(FramebufferTarget.Framebuffer, size, size, PixelInternalFormat.Rgba32f);

            frameBuffer.Bind();

            GL.Disable(EnableCap.Blend);

            var cubemapFilter = GlobalShaders.GetShader("CUBEMAP_PREFILTER");

            cubemapFilter.Enable();

            //Allocate mipmaps
            cubemapOutput.Bind();
            cubemapOutput.GenerateMipmaps();
            cubemapOutput.Unbind();

            GL.ActiveTexture(TextureUnit.Texture0 + 1);
            cubemapInput.Bind();
            cubemapFilter.SetInt("environmentMap", 1);
            cubemapFilter.SetMatrix4x4("projection", ref projection);

            //Quick hack, draw once before rendering (first buffer not updating for some reason??)
            RenderTools.DrawCube();

            GL.Disable(EnableCap.CullFace);
            for (int mip = 0; mip < cubemapOutput.MipCount; mip++)
            {
                int mipWidth  = (int)(size * Math.Pow(0.5, mip));
                int mipHeight = (int)(size * Math.Pow(0.5, mip));

                frameBuffer.Resize(mipWidth, mipHeight);
                GL.Viewport(0, 0, mipWidth, mipHeight);

                float roughness = (float)mip / (float)(cubemapOutput.MipCount - 1);
                cubemapFilter.SetFloat("roughness", roughness);

                for (int i = 0; i < 6; i++)
                {
                    //attach face to fbo as color attachment 0
                    if (cubemapOutput is GLTextureCubeArray)
                    {
                        GL.FramebufferTextureLayer(FramebufferTarget.Framebuffer,
                                                   FramebufferAttachment.ColorAttachment0, cubemapOutput.ID, mip, (layer * 6) + i);
                    }
                    else
                    {
                        GL.FramebufferTexture2D(FramebufferTarget.Framebuffer,
                                                FramebufferAttachment.ColorAttachment0,
                                                TextureTarget.TextureCubeMapPositiveX + i, cubemapOutput.ID, mip);
                    }

                    cubemapFilter.SetMatrix4x4("view", ref captureViews[i]);

                    GL.ClearColor(0, 0, 0, 1);
                    GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
                    RenderTools.DrawCube();
                }
            }

            var errorcheck = GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer);

            if (errorcheck != FramebufferErrorCode.FramebufferComplete)
            {
                throw new Exception(errorcheck.ToString());
            }

            GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
            GL.Enable(EnableCap.CullFace);
            GL.Enable(EnableCap.Blend);

            frameBuffer.Dispoe();
            frameBuffer.DisposeRenderBuffer();

            GL.UseProgram(0);
        }
        //Update all existing cubemap uint objects
        public static void GenerateCubemaps(List <GenericRenderer> targetModels, bool isWiiU)
        {
            var texture = isWiiU ? CubeMapTextureArray : CubeMapTexture;

            if (texture != null)
            {
                texture.Dispose();
            }

            if (isWiiU)
            {
                texture = GLTexture2DArray.CreateUncompressedTexture(CUBEMAP_SIZE, CUBEMAP_SIZE, MAX_LAYER_COUNT * 6, MAX_MIP_LEVEL,
                                                                     PixelInternalFormat.Rgba16f, PixelFormat.Rgba, PixelType.Float);
            }
            else
            {
                texture = GLTextureCubeArray.CreateEmptyCubemap(CUBEMAP_SIZE, MAX_LAYER_COUNT, MAX_MIP_LEVEL,
                                                                PixelInternalFormat.Rgba16f, PixelFormat.Rgba, PixelType.Float);
            }

            GLTextureCube cubemapTexture = GLTextureCube.CreateEmptyCubemap(
                CUBEMAP_UPSCALE_SIZE, PixelInternalFormat.Rgba16f, PixelFormat.Rgba, PixelType.Float, 9);

            //Get a list of cubemaps in the scene
            //The lighting engine has cube map objects with the object placement to draw
            var lightingEngine   = LightingEngine.LightSettings;
            var cubemapEnvParams = lightingEngine.Resources.CubeMapFiles.FirstOrDefault().Value;
            var cubeMapUints     = cubemapEnvParams.CubeMapObjects;
            int layer            = 0;

            foreach (var cubeMap in cubeMapUints)
            {
                var cUint = cubeMap.CubeMapUint;
                //Cubemap has no area assigned skip it
                if (cubeMap.CubeMapUint.Name == string.Empty)
                {
                    continue;
                }

                //Setup the camera to render the cube map faces
                CubemapCamera camera = new CubemapCamera(
                    new Vector3(cUint.Position.X, cUint.Position.Y, cUint.Position.Z)
                    * GLContext.PreviewScale, cUint.Near, cUint.Far);

                var context = new GLContext();
                context.Camera = camera;

                GenerateCubemap(context, cubemapTexture, camera, targetModels, MAX_MIP_LEVEL);

                cubemapTexture.Bind();
                cubemapTexture.GenerateMipmaps();
                cubemapTexture.Unbind();

                //HDR encode and output into the array
                CubemapHDREncodeRT.CreateCubemap(cubemapTexture, texture, layer, MAX_MIP_LEVEL, false, true);

                if (SAVE_TO_DISK)
                {
                    cubemapTexture.SaveDDS(cubeMap.Name + "default.dds");
                }

                layer++;
            }

            cubemapTexture.Dispose();

            //Just generate mips to keep things easier
            texture.Bind();
            texture.GenerateMipmaps();
            texture.Unbind();

            if (SAVE_TO_DISK)
            {
                texture.SaveDDS("Cubemap_Array_HDR.dds");
            }

            if (isWiiU)
            {
                CubeMapTextureArray = texture;
            }
            else
            {
                CubeMapTexture = texture;
            }
        }
Esempio n. 10
0
        public static void CreateCubemap(GLContext control, GLTextureCube cubemapInput,
                                         GLTexture cubemapOutput, int layer, int numMips)
        {
            int size = cubemapInput.Width;

            Matrix4 projection = Matrix4.CreatePerspectiveFieldOfView(MathHelper.DegreesToRadians(90), 1.0f, 0.1f, 10.0f);

            Matrix4[] captureViews =
            {
                Matrix4.LookAt(new Vector3(0.0f, 0.0f, 0.0f), new Vector3(1.0f,   0.0f,  0.0f), new Vector3(0.0f, -1.0f,  0.0f)),
                Matrix4.LookAt(new Vector3(0.0f, 0.0f, 0.0f), new Vector3(-1.0f,  0.0f,  0.0f), new Vector3(0.0f, -1.0f,  0.0f)),
                Matrix4.LookAt(new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f,   1.0f,  0.0f), new Vector3(0.0f,  0.0f,  1.0f)),
                Matrix4.LookAt(new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f,  -1.0f,  0.0f), new Vector3(0.0f,  0.0f, -1.0f)),
                Matrix4.LookAt(new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f,   0.0f,  1.0f), new Vector3(0.0f, -1.0f,  0.0f)),
                Matrix4.LookAt(new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f,   0.0f, -1.0f), new Vector3(0.0f, -1.0f,  0.0f)),
            };

            GL.BindTexture(TextureTarget.TextureCubeMap, 0);

            //Bind the cubemap's texture into a filtered quad.
            //Bind the drawn filter to a cubemap array layer
            Framebuffer frameBuffer = new Framebuffer(FramebufferTarget.Framebuffer, size, size, PixelInternalFormat.Rgba32f);

            frameBuffer.Bind();

            GL.Disable(EnableCap.Blend);

            var cubemapFilter = GlobalShaders.GetShader("CUBEMAP_HDRDECODE");

            cubemapFilter.Enable();

            GL.ActiveTexture(TextureUnit.Texture0 + 1);
            cubemapInput.Bind();
            cubemapFilter.SetInt("cubemapTexture", 1);
            cubemapFilter.SetMatrix4x4("projection", ref projection);
            cubemapFilter.SetFloat("gamma", 2.2f);
            cubemapFilter.SetFloat("range", 1024.0f);
            cubemapFilter.SetFloat("scale", 4.0f);

            GL.Disable(EnableCap.CullFace);
            for (int mip = 0; mip < numMips; mip++)
            {
                int mipWidth  = (int)(size * Math.Pow(0.5, mip));
                int mipHeight = (int)(size * Math.Pow(0.5, mip));

                frameBuffer.Resize(mipWidth, mipHeight);
                GL.Viewport(0, 0, mipWidth, mipHeight);

                cubemapFilter.SetFloat("mipLevel", mip);
                for (int i = 0; i < 6; i++)
                {
                    cubemapFilter.SetInt("faceLevel", i);

                    //attach face to fbo as color attachment 0
                    if (cubemapOutput is GLTextureCubeArray)
                    {
                        GL.FramebufferTextureLayer(FramebufferTarget.Framebuffer,
                                                   FramebufferAttachment.ColorAttachment0, cubemapOutput.ID, mip, (layer * 6) + i);
                    }
                    else
                    {
                        GL.FramebufferTexture2D(FramebufferTarget.Framebuffer,
                                                FramebufferAttachment.ColorAttachment0,
                                                TextureTarget.TextureCubeMapPositiveX + i, cubemapOutput.ID, mip);
                    }

                    cubemapFilter.SetMatrix4x4("view", ref captureViews[i]);

                    GL.ClearColor(0, 0, 0, 1);
                    GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
                    RenderTools.DrawCube();
                }
            }

            var errorcheck = GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer);

            if (errorcheck != FramebufferErrorCode.FramebufferComplete)
            {
                throw new Exception(errorcheck.ToString());
            }

            GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
            GL.Enable(EnableCap.CullFace);
            GL.Enable(EnableCap.Blend);

            frameBuffer.Dispoe();
            frameBuffer.DisposeRenderBuffer();

            GL.UseProgram(0);
        }
Esempio n. 11
0
        public override void SetTextureUniforms(GLContext control, ShaderProgram shader, STGenericMaterial mat)
        {
            var bfresMaterial = (FMAT)mat;

            GL.ActiveTexture(TextureUnit.Texture0 + 1);
            GL.BindTexture(TextureTarget.Texture2D, RenderTools.defaultTex.ID);

            int id = 1;

            var pixelShader = ShaderModel.GetGX2PixelShader(BinaryIndex);

            foreach (var sampler in pixelShader.Samplers)
            {
                GL.ActiveTexture(TextureUnit.Texture0 + id);

                switch (sampler.Name)
                {
                case "ice_cube": IceCubeTexture.Bind(); break;

                case "ice_toon": IceToonTexture.Bind(); break;

                case "light_pre_pass": LightPPTexture.Bind(); break;

                case "linear_depth": LinearDepthTexture.Bind(); break;

                case "shadow_pre_pass": ShadowTexture.Bind(); break;

                case "projection_map": ProjectionTexture.Bind(); break;

                default:
                    ProjectionTexture.Bind(); break;
                }
                this.SetSampler(shader, (int)sampler.Location, ref id);
            }

            for (int i = 0; i < bfresMaterial.TextureMaps?.Count; i++)
            {
                var name    = mat.TextureMaps[i].Name;
                var sampler = mat.TextureMaps[i].Sampler;
                //Lookup samplers targeted via animations and use that texture instead if possible
                if (bfresMaterial.AnimatedSamplers.ContainsKey(sampler))
                {
                    name = bfresMaterial.AnimatedSamplers[sampler];
                }

                var location = this.GetSamplerLocation(bfresMaterial.Samplers[i]);
                if (location == -1)
                {
                    continue;
                }

                if (name == "ZBtoonEX")
                {
                    GL.ActiveTexture(TextureUnit.Texture0 + id);
                    ToonTexture.Bind();
                    this.SetSampler(shader, (int)location, ref id);
                    continue;
                }

                var binded = BindTexture(shader, GetTextures(), mat.TextureMaps[i], name, id);
                this.SetSampler(shader, (int)location, ref id);
            }

            GL.ActiveTexture(TextureUnit.Texture0);
            GL.BindTexture(TextureTarget.Texture2D, 0);
        }