Пример #1
0
        public MainPage()
        {
            this.InitializeComponent();

            m_ctx       = new ResourceCreateContext();
            m_swapChain = new CompositionSwapChainResources(m_ctx, m_swapChainPanel);

            var display = DisplayInformation.GetForCurrentView();

            display.DpiChanged += new TypedEventHandler <DisplayInformation, object>(OnDpiChanged);
            m_triangle          = makeTriangle(m_ctx);
            m_compute           = makeCompute(m_ctx);

            m_buffer  = m_ctx.CreateByteAddressBuffer(4096, ResourceState.CopyDestination);
            m_texture = m_ctx.CreateTexture2D(256, 256, 1, GraphicsFormat.R8_UNORM, ResourceState.CopyDestination);

            var ctx = m_swapChain.CreateGraphicsComputeCommandContext();

            {
                float[] positions =
                {
                    0.0f,  0.5f, 0.5f, 1.0f,
                    -0.5f, 0.0f, 0.5f, 1.0f,
                    0.5f,  0.0f, 0.5f, 1.0f
                };

                byte[] b0 = new byte[positions.Length * 4];
                Buffer.BlockCopy(positions, 0, b0, 0, b0.Length);

                float[] colors =
                {
                    1.0f, 0.0f, 0.0f,
                    0.0f, 1.0f, 0.0f,
                    0.0f, 0.0f, 1.0f
                };

                byte[] b1 = new byte[colors.Length * 4];
                Buffer.BlockCopy(colors, 0, b1, 0, b1.Length);

                ctx.UpdateBuffer(m_buffer, 0, b0);
                ctx.UpdateBuffer(m_buffer, (uint)b0.Length, b1);
            }

            {
                var subResourceData = new SubresourceData();

                subResourceData.Data       = GenerateTextureData();
                subResourceData.RowPitch   = 256;
                subResourceData.SlicePitch = 256 * 256;

                SubresourceData[] datas = { subResourceData };

                ctx.UploadResource(m_texture, 0, 1, datas);
            }

            ctx.TransitionResource(m_texture, ResourceState.CopyDestination, ResourceState.PixelShaderResource | ResourceState.NonPixelShaderResource);
            ctx.TransitionResource(m_buffer, ResourceState.CopyDestination, ResourceState.NonPixelShaderResource);

            ctx.SubmitAndWaitToExecute();
        }
Пример #2
0
        public Cube(Vector3 position, Vector3 size, Vector4 color, bool IsCull)
        {
            Transform.Scale    = new Vector3(size.X, size.Y, size.Z);
            Transform.Position = new Vector3(position.X, position.Y, position.Z);

            cubeBuffer = new CubeBuffer()
            {
                color = color
            };

            cubeBufferUploader = new ConstantBuffer <CubeBuffer>(cubeBuffer);

            if (IsCull is true)
            {
                graphicsPipelineState = new GraphicsPipelineState(Window.vertexShader,
                                                                  Window.pixelShader, Window.inputLayout, Window.resourceLayout,
                                                                  null, new DepthStencilState(true), null);
            }
            else
            {
                graphicsPipelineState = new GraphicsPipelineState(Window.vertexShader,
                                                                  Window.pixelShader, Window.inputLayout, Window.resourceLayout, null,
                                                                  new DepthStencilState(true), Window.blendState);
            }
        }
Пример #3
0
        protected override async void InternalLoad()
        {
            // Compile Vertex and Pixel shaders
            var vertexShaderDescription = await this.assetsDirectory.ReadAndCompileShader(this.graphicsContext, "HLSL", "VertexShader", ShaderStages.Vertex, "VS");

            var pixelShaderDescription = await this.assetsDirectory.ReadAndCompileShader(this.graphicsContext, "HLSL", "FragmentShader", ShaderStages.Pixel, "PS");

            var vertexShader = this.graphicsContext.Factory.CreateShader(ref vertexShaderDescription);
            var pixelShader  = this.graphicsContext.Factory.CreateShader(ref pixelShaderDescription);

            var vertexBufferDescription = new BufferDescription((uint)Unsafe.SizeOf <Vector4>() * (uint)this.vertexData.Length, BufferFlags.VertexBuffer, ResourceUsage.Default);
            var vertexBuffer            = this.graphicsContext.Factory.CreateBuffer(this.vertexData, ref vertexBufferDescription);

            // Prepare Pipeline
            var vertexLayouts = new InputLayouts()
                                .Add(new LayoutDescription()
                                     .Add(new ElementDescription(ElementFormat.Float4, ElementSemanticType.Position))
                                     .Add(new ElementDescription(ElementFormat.Float4, ElementSemanticType.Color)));

            var pipelineDescription = new GraphicsPipelineDescription
            {
                PrimitiveTopology = PrimitiveTopology.TriangleList,
                InputLayouts      = vertexLayouts,
                Shaders           = new GraphicsShaderStateDescription()
                {
                    VertexShader = vertexShader,
                    PixelShader  = pixelShader,
                },
                RenderStates = new RenderStateDescription()
                {
                    RasterizerState   = RasterizerStates.CullBack,
                    BlendState        = BlendStates.Opaque,
                    DepthStencilState = DepthStencilStates.ReadWrite,
                },
                Outputs = this.frameBuffer.OutputDescription,
            };

            this.pipelineState = this.graphicsContext.Factory.CreateGraphicsPipeline(ref pipelineDescription);
            this.commandQueue  = this.graphicsContext.Factory.CreateCommandQueue();

            var swapChainDescription = this.swapChain?.SwapChainDescription;
            var width  = swapChainDescription.HasValue ? swapChainDescription.Value.Width : this.surface.Width;
            var height = swapChainDescription.HasValue ? swapChainDescription.Value.Height : this.surface.Height;

            this.viewports    = new Viewport[1];
            this.viewports[0] = new Viewport(0, 0, width, height);
            this.scissors     = new Rectangle[1];
            this.scissors[0]  = new Rectangle(0, 0, (int)width, (int)height);

            this.vertexBuffers    = new Buffer[1];
            this.vertexBuffers[0] = vertexBuffer;
        }
Пример #4
0
        public Window(string Title, int Width, int Height) : base(Title, Width, Height)
        {
            IsVisible = true;

            presenter = new Present(Handle, true);

            vertexShader = new VertexShader(Properties.Resources.shader, "vs_main");
            pixelShader  = new PixelShader(Properties.Resources.shader, "ps_main");

            inputLayout = new InputLayout(
                new InputLayout.Element[] {
                new InputLayout.Element("POSITION", ElementSize.eFloat3),
                new InputLayout.Element("COLOR", ElementSize.eFlaot4)
            });

            resourceLayout = new ResourceLayout(
                new ResourceLayout.Element[]
            {
                new ResourceLayout.Element(ResourceType.ConstantBufferView, 0),
                new ResourceLayout.Element(ResourceType.ConstantBufferView, 1)
            });

            graphicsPipelineState = new GraphicsPipelineState(vertexShader, pixelShader, inputLayout,
                                                              resourceLayout, new RasterizerState()
            {
                FillMode = FillMode.Wireframe
            }, new DepthStencilState(true), new BlendState());

            Micos.Camera = new Camera();
            Micos.Camera.Transform.Position = new Vector3(0, 0, -100);

            Micos.Camera.Project = TMatrix.CreatePerspectiveFieldOfViewLH((float)Math.PI * 0.55f,
                                                                          (float)Width / Height, 1.0f, 2000.0f);

            for (int i = 0; i < EventThing.ObjectCount; i++)
            {
                Cube cube = new Cube(10, 10, 10);
                cube.Transform.Position = new Vector3(EventThing.INT, EventThing.INT, EventThing.INT);
                cube.Forward            = Vector3.Normalize(new Vector3(EventThing.INT, EventThing.INT, 0));
                cube.RotateSpeed        = new Vector3(EventThing.FLOAT, EventThing.FLOAT, 0);
                Micos.Add(cube);
            }

            Micos.Add(fpsCounter = new FpsCounter());

            Resource.cameraBuffer.view   = Micos.Camera;
            Resource.cameraBuffer.proj   = Micos.Camera.Project;
            Resource.cameraBuffer.eyePos = new Vector4(Micos.Camera.Transform.Position, 1);

            CameraBuffer.View.Update(ref Resource.cameraBuffer);
        }
Пример #5
0
        public Window(string Title, int Width, int Height) : base(Title, Width, Height)
        {
            prenster = new Present(Handle, true);

            vertexShader = new VertexShader(Properties.Resources.shader, "vs_main");
            pixelShader  = new PixelShader(Properties.Resources.shader, "ps_main");

            inputLayout = new InputLayout(
                new InputLayout.Element[]
            {
                new InputLayout.Element("POSITION", ElementSize.eFloat3)
            });

            resourceLayout = new ResourceLayout(
                new ResourceLayout.Element[2] {
                new ResourceLayout.Element(ResourceType.ConstantBufferView, 0),
                new ResourceLayout.Element(ResourceType.ConstantBufferView, 1)
            }, null);

            InitalizeBlendState();

            graphicsPipelineState = new GraphicsPipelineState(vertexShader, pixelShader,
                                                              inputLayout, resourceLayout, null, new DepthStencilState(), blendState);

            Micos.Camera = new Camera()
            {
                Project = Mico.Math.TMatrix.CreatePerspectiveFieldOfViewLH((float)Math.PI * 0.55f,
                                                                           800f / 600f, 1.0f, 2000.0f)
            };

            Micos.Camera.Transform.Position = new Vector3(0, 0, -10);
            Micos.Camera.Transform.Forward  = Vector3.Zero - Micos.Camera.Transform.Position;

            Micos.Add(new Cube(new Vector3(0, 0, 3),
                               new Vector3(3, 3, 3), new Vector4(1, 0, 0, 1), true));

            Micos.Add(new Cube(new Vector3(0, 0, 0),
                               new Vector3(5, 5, 5), new Vector4(0, 1, 1, 0.5f), false));

            Micos.Add(fpsCounter = new FpsCounter());

            CameraBuffer cameraBuffer = CameraBuffer.FromCamera(Micos.Camera);

            Resource.CameraBuffer.Update(ref cameraBuffer);

            IsVisible = true;
        }
Пример #6
0
        public Window(string Title, int Width, int Height) : base(Title, Width, Height)
        {
            presenter = new Present(Handle, true);

            vertexShader = new VertexShader(Properties.Resources.shader, "vs_main");
            pixelShader  = new PixelShader(Properties.Resources.shader, "ps_main");

            inputLayout = new InputLayout(
                new InputLayout.Element[2]
            {
                new InputLayout.Element("POSITION", ElementSize.eFloat3),
                new InputLayout.Element("TEXCOORD", ElementSize.eFloat2)
            });

            resourceLayout = new ResourceLayout(
                new ResourceLayout.Element[] {
                new ResourceLayout.Element(ResourceType.ConstantBufferTable, 0, 2),
                new ResourceLayout.Element(ResourceType.ShaderResourceTable, 0, 1)
            },
                new StaticSampler[] {
                new StaticSampler(TextureAddressMode.Clamp, TextureFilter.MinMagMipLinear)
            });

            graphicsPipelineState = new GraphicsPipelineState(vertexShader, pixelShader,
                                                              inputLayout, resourceLayout, new RasterizerState(), new DepthStencilState(), new BlendState());

            Micos.Camera = new Camera()
            {
                Project = Mico.Math.TMatrix.CreatePerspectiveFieldOfViewLH((float)Math.PI * 0.55f,
                                                                           800f / 600f, 1.0f, 2000.0f)
            };

            Micos.Camera.Transform.Position = new Vector3(0, 0, -10);
            Micos.Camera.Transform.Forward  = Vector3.Zero - Micos.Camera.Transform.Position;

            CreateTextureFace();

            Micos.Add(fpsCounter = new FpsCounter());

            Micos.Add(new Grid(20, 20, Resource.TextureFaceTable));

            IsVisible = true;
        }
Пример #7
0
        /// <inheritdoc />
        public override void Render(CommandBuffer commandBuffer, DrawContext drawContext, int passId = 0)
        {
            MaterialResourcesCacheEntry materialResource = this.Info.MaterialResources[drawContext.ID];
            GraphicsPipelineState       pipeline         = materialResource.Pipelines[passId];

            commandBuffer.SetGraphicsPipelineState(pipeline);
            //force refresh resource
            //materialResource.PassResources[passId].MakeResourceSetDirty();

            ResourceSet resourceSet = materialResource.PassResources[passId].ResourceSet;

            commandBuffer.SetResourceSet(resourceSet, constantBufferOffsets: this.dynamicCBufferOffsets);
            commandBuffer.SetVertexBuffers(this.Info.Mesh.Buffers, this.Info.Mesh.Offsets);
            uint        instanceCount = this.InstanceCount * (uint)drawContext.MultiviewEyeCount;
            IndexBuffer indexBuffer   = this.Info.Mesh.IndexBuffer;

            if (indexBuffer != null)
            {
                commandBuffer.SetIndexBuffer(indexBuffer.Buffer, indexBuffer.IndexFormat, (uint)this.Info.Mesh.IndexBuffer.Offset);

                if (instanceCount > 1U)
                {
                    commandBuffer.DrawIndexedInstanced((uint)this.Info.Mesh.ElementCount, instanceCount, (uint)this.Info.Mesh.IndexOffset, (uint)this.Info.Mesh.VertexOffset);
                }
                else
                {
                    commandBuffer.DrawIndexed((uint)this.Info.Mesh.ElementCount, (uint)this.Info.Mesh.IndexOffset, (uint)this.Info.Mesh.VertexOffset);
                }
            }
            else if (instanceCount > 1U)
            {
                commandBuffer.DrawInstanced((uint)this.Info.Mesh.ElementCount, instanceCount, (uint)this.Info.Mesh.VertexOffset);
            }
            else
            {
                commandBuffer.Draw((uint)this.Info.Mesh.ElementCount, (uint)this.Info.Mesh.VertexOffset);
            }
        }
Пример #8
0
        protected override async void InternalLoad()
        {
            var swapChainDescription = this.swapChain?.SwapChainDescription;

            this.width  = swapChainDescription.Value.Width;
            this.height = swapChainDescription.Value.Height;

            // Create Scene
            BasicScene();

            // Compute Resources
            var spheresBufferDescription = new BufferDescription(
                (uint)(Unsafe.SizeOf <Sphere>() * spheres.Length),
                BufferFlags.UnorderedAccess | BufferFlags.ShaderResource | BufferFlags.BufferStructured,
                ResourceUsage.Default,
                ResourceCpuAccess.None,
                Unsafe.SizeOf <Sphere>());

            spheresBuffer = this.graphicsContext.Factory.CreateBuffer(spheres, ref spheresBufferDescription);

            var materialsBufferDescription = new BufferDescription(
                (uint)(Unsafe.SizeOf <Material>() * spheres.Length),
                BufferFlags.UnorderedAccess | BufferFlags.ShaderResource | BufferFlags.BufferStructured,
                ResourceUsage.Default,
                ResourceCpuAccess.None,
                Unsafe.SizeOf <Material>());

            materialsBuffer = this.graphicsContext.Factory.CreateBuffer(materials, ref materialsBufferDescription);

            this.threadGroupX = this.width / 16u;
            this.threadGroupY = this.height / 16u;

            CompilerParameters parameters = new CompilerParameters()
            {
                CompilationMode = CompilationMode.None,
                Profile         = GraphicsProfile.Level_11_0,
            };

            var computeShaderDescription = await this.assetsDirectory.ReadAndCompileShader(this.graphicsContext, "CS", "ComputeShader", ShaderStages.Compute, "CS", parameters);

            var computeShader = this.graphicsContext.Factory.CreateShader(ref computeShaderDescription);

            var textureDescription = new TextureDescription()
            {
                Type        = TextureType.Texture2D,
                Usage       = ResourceUsage.Default,
                Flags       = TextureFlags.UnorderedAccess | TextureFlags.ShaderResource,
                Format      = PixelFormat.R8G8B8A8_UNorm,
                Width       = this.width,
                Height      = this.height,
                Depth       = 1,
                MipLevels   = 1,
                ArraySize   = 1,
                CpuAccess   = ResourceCpuAccess.None,
                SampleCount = TextureSampleCount.None,
            };

            Texture texture2D = this.graphicsContext.Factory.CreateTexture(ref textureDescription);

            this.computeData = new ComputeData()
            {
                time        = 0,
                width       = this.width,
                height      = this.height,
                framecount  = 0,
                samples     = 25,
                recursion   = 5,
                spherecount = (uint)spheres.Length,
                cam         = this.cam
            };

            var constantBufferDescription = new BufferDescription((uint)Unsafe.SizeOf <ComputeData>(), BufferFlags.ConstantBuffer, ResourceUsage.Default);

            this.constantBuffer = this.graphicsContext.Factory.CreateBuffer(ref this.computeData, ref constantBufferDescription);

            ResourceLayoutDescription computeLayoutDescription = new ResourceLayoutDescription(
                new LayoutElementDescription(0, ResourceType.StructuredBuffer, ShaderStages.Compute),
                new LayoutElementDescription(1, ResourceType.StructuredBuffer, ShaderStages.Compute),
                new LayoutElementDescription(0, ResourceType.ConstantBuffer, ShaderStages.Compute),
                new LayoutElementDescription(0, ResourceType.TextureReadWrite, ShaderStages.Compute));

            ResourceLayout computeResourceLayout = this.graphicsContext.Factory.CreateResourceLayout(ref computeLayoutDescription);

            ResourceSetDescription computeResourceSetDescription = new ResourceSetDescription(computeResourceLayout, this.spheresBuffer, this.materialsBuffer, this.constantBuffer, texture2D);

            this.computeResourceSet = this.graphicsContext.Factory.CreateResourceSet(ref computeResourceSetDescription);

            var computePipelineDescription = new ComputePipelineDescription()
            {
                ComputeShader    = computeShader,
                ResourceLayouts  = new[] { computeResourceLayout },
                ThreadGroupSizeX = 16,
                ThreadGroupSizeY = 16,
                ThreadGroupSizeZ = 1,
            };

            this.computePipelineState = this.graphicsContext.Factory.CreateComputePipeline(ref computePipelineDescription);

            // Graphics Resources
            var vertexShaderDescription = await this.assetsDirectory.ReadAndCompileShader(this.graphicsContext, "HLSL", "VertexShader", ShaderStages.Vertex, "VS");

            var pixelShaderDescription = await this.assetsDirectory.ReadAndCompileShader(this.graphicsContext, "HLSL", "FragmentShader", ShaderStages.Pixel, "PS");

            var vertexShader = this.graphicsContext.Factory.CreateShader(ref vertexShaderDescription);
            var pixelShader  = this.graphicsContext.Factory.CreateShader(ref pixelShaderDescription);

            var samplerDescription = SamplerStates.LinearClamp;
            var samplerState       = this.graphicsContext.Factory.CreateSamplerState(ref samplerDescription);

            // Set Params
            this.paramsData.Samples       = 1;
            this.paramsData.IsPathTracing = false;

            var paramsBufferDescription = new BufferDescription((uint)Unsafe.SizeOf <Params>(), BufferFlags.ConstantBuffer, ResourceUsage.Default);

            this.paramsBuffer = this.graphicsContext.Factory.CreateBuffer(ref paramsBufferDescription);

            ResourceLayoutDescription layoutDescription = new ResourceLayoutDescription(
                new LayoutElementDescription(0, ResourceType.ConstantBuffer, ShaderStages.Pixel),
                new LayoutElementDescription(0, ResourceType.Texture, ShaderStages.Pixel),
                new LayoutElementDescription(0, ResourceType.Sampler, ShaderStages.Pixel));
            ResourceLayout resourceLayout = this.graphicsContext.Factory.CreateResourceLayout(ref layoutDescription);

            ResourceSetDescription resourceSetDescription = new ResourceSetDescription(resourceLayout, this.paramsBuffer, texture2D, samplerState);

            this.resourceSet = this.graphicsContext.Factory.CreateResourceSet(ref resourceSetDescription);

            BlendStateDescription blend = BlendStateDescription.Default;

            if (this.paramsData.IsPathTracing)
            {
                blend.RenderTarget0.BlendEnable           = true;
                blend.RenderTarget0.SourceBlendColor      = Blend.SourceAlpha;
                blend.RenderTarget0.DestinationBlendColor = Blend.InverseSourceAlpha;
            }
            else
            {
                blend = BlendStates.Opaque;
            }

            var pipelineDescription = new GraphicsPipelineDescription()
            {
                PrimitiveTopology = PrimitiveTopology.TriangleList,
                InputLayouts      = null,
                ResourceLayouts   = new[] { resourceLayout },
                Shaders           = new ShaderStateDescription()
                {
                    VertexShader = vertexShader,
                    PixelShader  = pixelShader,
                },
                RenderStates = new RenderStateDescription()
                {
                    RasterizerState   = RasterizerStates.CullBack,
                    BlendState        = blend,
                    DepthStencilState = DepthStencilStates.Read,
                },
                Outputs = this.frameBuffer.OutputDescription,
            };

            this.graphicsPipelineState = this.graphicsContext.Factory.CreateGraphicsPipeline(ref pipelineDescription);
            this.graphicsCommandQueue  = this.graphicsContext.Factory.CreateCommandQueue(CommandQueueType.Graphics);
            this.computeCommandQueue   = this.graphicsContext.Factory.CreateCommandQueue(CommandQueueType.Compute);

            this.viewports    = new Viewport[1];
            this.viewports[0] = new Viewport(0, 0, this.width, this.height);
            this.scissors     = new Rectangle[1];
            this.scissors[0]  = new Rectangle(0, 0, (int)this.width, (int)this.height);
        }
        protected override async void InternalLoad()
        {
            var swapChainDescription = this.swapChain?.SwapChainDescription;

            this.width  = swapChainDescription.Value.Width;
            this.height = swapChainDescription.Value.Height;

            // Graphics Resources
            var vertexShaderDescription = await this.assetsDirectory.ReadAndCompileShader(this.graphicsContext, "HLSL", "VertexShader", ShaderStages.Vertex, "VS");

            var pixelShaderDescription = await this.assetsDirectory.ReadAndCompileShader(this.graphicsContext, "HLSL", "FragmentShader", ShaderStages.Pixel, "PS");

            var vertexShader = this.graphicsContext.Factory.CreateShader(ref vertexShaderDescription);
            var pixelShader  = this.graphicsContext.Factory.CreateShader(ref pixelShaderDescription);

            Texture textureCube = null;

            using (var stream = System.IO.File.OpenRead("Content/TextureCubeToSpherical/TextureCube.ktx"))
            {
                if (stream != null)
                {
                    VisualTests.LowLevel.Images.Image image = VisualTests.LowLevel.Images.Image.Load(stream);
                    var textureDescription = image.TextureDescription;
                    textureCube = graphicsContext.Factory.CreateTexture(image.DataBoxes, ref textureDescription);
                }
            }

            var samplerDescription = SamplerStates.LinearClamp;
            var samplerState       = this.graphicsContext.Factory.CreateSamplerState(ref samplerDescription);

            ResourceLayoutDescription layoutDescription = new ResourceLayoutDescription(
                new LayoutElementDescription(0, ResourceType.Texture, ShaderStages.Pixel),
                new LayoutElementDescription(0, ResourceType.Sampler, ShaderStages.Pixel));
            ResourceLayout resourceLayout = this.graphicsContext.Factory.CreateResourceLayout(ref layoutDescription);

            ResourceSetDescription resourceSetDescription = new ResourceSetDescription(resourceLayout, textureCube, samplerState);

            this.resourceSet = this.graphicsContext.Factory.CreateResourceSet(ref resourceSetDescription);

            var pipelineDescription = new GraphicsPipelineDescription()
            {
                PrimitiveTopology = PrimitiveTopology.TriangleList,
                InputLayouts      = null,
                ResourceLayouts   = new[] { resourceLayout },
                Shaders           = new ShaderStateDescription()
                {
                    VertexShader = vertexShader,
                    PixelShader  = pixelShader,
                },
                RenderStates = new RenderStateDescription()
                {
                    RasterizerState   = RasterizerStates.CullBack,
                    BlendState        = BlendStates.Opaque,
                    DepthStencilState = DepthStencilStates.Read,
                },
                Outputs = this.frameBuffer.OutputDescription,
            };

            this.graphicsPipelineState = this.graphicsContext.Factory.CreateGraphicsPipeline(ref pipelineDescription);
            this.graphicsCommandQueue  = this.graphicsContext.Factory.CreateCommandQueue(CommandQueueType.Graphics);

            this.viewports    = new Viewport[1];
            this.viewports[0] = new Viewport(0, 0, this.width, this.height);
            this.scissors     = new Rectangle[1];
            this.scissors[0]  = new Rectangle(0, 0, (int)this.width, (int)this.height);
        }
Пример #10
0
        protected override async void InternalLoad()
        {
            // Compile Vertex and Pixel shaders
            var vertexShaderDescription = await this.assetsDirectory.ReadAndCompileShader(this.graphicsContext, "HLSL", "VertexShader", ShaderStages.Vertex, "VS");

            var pixelShaderDescription = await this.assetsDirectory.ReadAndCompileShader(this.graphicsContext, "HLSL", "FragmentShader", ShaderStages.Pixel, "PS");

            var vertexShader = this.graphicsContext.Factory.CreateShader(ref vertexShaderDescription);
            var pixelShader  = this.graphicsContext.Factory.CreateShader(ref pixelShaderDescription);


            var vertexBufferDescription = new BufferDescription((uint)Unsafe.SizeOf <VertexPositionNormalTexture>() * (uint)vertexData.Length, BufferFlags.VertexBuffer, ResourceUsage.Default);
            var vertexBuffer            = this.graphicsContext.Factory.CreateBuffer(vertexData, ref vertexBufferDescription);

            this.view = Matrix4x4.CreateLookAt(new Vector3(0, 0, 4f), new Vector3(0, 0, 0), Vector3.UnitY);
            this.proj = Matrix4x4.CreatePerspectiveFieldOfView(MathHelper.PiOver4, (float)this.frameBuffer.Width / (float)this.frameBuffer.Height, 0.1f, 100f);

            // Parameters
            float density       = 0.4f;
            float minHairLength = 0.5f;

            this.parameters = new Parameters();
            this.parameters.displacement     = new Vector3(0, -0.05f, 0);
            this.parameters.numLayers        = 50f;
            this.parameters.startShadowValue = 0.2f;
            this.parameters.MaxHairLength    = 0.2f;
            this.parameters.viewProj         = Matrix4x4.Multiply(this.view, this.proj);

            // Constant Buffer
            var constantBufferDescription = new BufferDescription((uint)Unsafe.SizeOf <Parameters>(), BufferFlags.ConstantBuffer, ResourceUsage.Default);

            this.constantBuffer = this.graphicsContext.Factory.CreateBuffer(ref this.parameters, ref constantBufferDescription);

            // Create FurTexture
            uint size        = 1024;
            var  description = new TextureDescription()
            {
                Type        = TextureType.Texture2D,
                Width       = size,
                Height      = size,
                Depth       = 1,
                ArraySize   = 1,
                Faces       = 1,
                Usage       = ResourceUsage.Default,
                CpuAccess   = ResourceCpuAccess.None,
                Flags       = TextureFlags.ShaderResource,
                Format      = PixelFormat.R8_UNorm,
                MipLevels   = 1,
                SampleCount = TextureSampleCount.None,
            };
            var textureFur = this.graphicsContext.Factory.CreateTexture(ref description);

            uint totalPixels = size * size;

            byte[] data = new byte[totalPixels];

            int strands  = (int)(density * totalPixels);
            int minValue = (int)(minHairLength * 255f);

            for (int i = 0; i < strands; i++)
            {
                int x = rand.Next((int)size);
                int y = rand.Next((int)size);
                data[(x * size) + y] = (byte)rand.Next(minValue, 255);
            }

            this.graphicsContext.UpdateTextureData(textureFur, data);

            // Color Texture
            Texture texture2D = null;

            ////using (var stream = this.assetsDirectory.Open("Cat.ktx"))
            using (var stream = this.assetsDirectory.Open("Leopard.ktx"))
            ////using (var stream = this.assetsDirectory.Open("Cheetah.ktx"))
            ////using (var stream = this.assetsDirectory.Open("GrayLeopard.ktx"))
            ////using (var stream = this.assetsDirectory.Open("Tiger.ktx"))
            ////using (var stream = this.assetsDirectory.Open("Zebra.ktx"))
            {
                if (stream != null)
                {
                    VisualTests.LowLevel.Images.Image image = VisualTests.LowLevel.Images.Image.Load(stream);
                    var textureDescription = image.TextureDescription;
                    texture2D = graphicsContext.Factory.CreateTexture(image.DataBoxes, ref textureDescription);
                }
            }

            SamplerStateDescription sampler1Description = SamplerStates.LinearClamp;
            var sampler1 = this.graphicsContext.Factory.CreateSamplerState(ref sampler1Description);

            SamplerStateDescription sampler2Description = SamplerStates.PointClamp;
            var sampler2 = this.graphicsContext.Factory.CreateSamplerState(ref sampler2Description);

            // Prepare Pipeline
            var vertexLayouts = new InputLayouts()
                                .Add(VertexPositionNormalTexture.VertexFormat);

            ResourceLayoutDescription layoutDescription = new ResourceLayoutDescription(
                new LayoutElementDescription(0, ResourceType.ConstantBuffer, ShaderStages.Vertex),
                new LayoutElementDescription(0, ResourceType.Texture, ShaderStages.Pixel),
                new LayoutElementDescription(1, ResourceType.Texture, ShaderStages.Pixel),
                new LayoutElementDescription(0, ResourceType.Sampler, ShaderStages.Pixel),
                new LayoutElementDescription(1, ResourceType.Sampler, ShaderStages.Pixel));

            ResourceLayout resourcesLayout = this.graphicsContext.Factory.CreateResourceLayout(ref layoutDescription);

            ResourceSetDescription resourceSetDescription = new ResourceSetDescription(resourcesLayout, this.constantBuffer, texture2D, textureFur, sampler1, sampler2);

            this.resourceSet = this.graphicsContext.Factory.CreateResourceSet(ref resourceSetDescription);

            var pipelineDescription = new GraphicsPipelineDescription()
            {
                PrimitiveTopology = PrimitiveTopology.TriangleList,
                InputLayouts      = vertexLayouts,
                ResourceLayouts   = new[] { resourcesLayout },
                Shaders           = new ShaderStateDescription()
                {
                    VertexShader = vertexShader,
                    PixelShader  = pixelShader,
                },
                RenderStates = new RenderStateDescription()
                {
                    RasterizerState   = RasterizerStates.None,
                    BlendState        = BlendStates.Opaque,
                    DepthStencilState = DepthStencilStates.None,
                },
                Outputs = this.frameBuffer.OutputDescription,
            };

            this.graphicsPipelineState = this.graphicsContext.Factory.CreateGraphicsPipeline(ref pipelineDescription);
            this.graphicsCommandQueue  = this.graphicsContext.Factory.CreateCommandQueue();

            var swapChainDescription = this.swapChain?.SwapChainDescription;
            var width  = swapChainDescription.HasValue ? swapChainDescription.Value.Width : this.surface.Width;
            var height = swapChainDescription.HasValue ? swapChainDescription.Value.Height : this.surface.Height;

            this.viewports    = new Viewport[1];
            this.viewports[0] = new Viewport(0, 0, width, height);
            this.scissors     = new Rectangle[1];
            this.scissors[0]  = new Rectangle(0, 0, (int)width, (int)height);

            this.vertexBuffers    = new Buffer[1];
            this.vertexBuffers[0] = vertexBuffer;
        }