protected override void CreateResources(ResourceFactory factory) { _vertexLayout = new VertexLayoutDescription( new VertexElementDescription("Position", VertexElementSemantic.Position, VertexElementFormat.Float3), new VertexElementDescription("UV", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float2), new VertexElementDescription("Color", VertexElementSemantic.Color, VertexElementFormat.Float3), new VertexElementDescription("Normal", VertexElementSemantic.Normal, VertexElementFormat.Float3)); using (Stream planeModelStream = OpenEmbeddedAssetStream("plane2.dae")) { _planeModel = new Model( GraphicsDevice, factory, planeModelStream, "dae", _vertexLayout, new Model.ModelCreateInfo(new Vector3(0.5f, 0.5f, 0.5f), Vector2.One, Vector3.Zero)); } using (Stream dragonModelStream = OpenEmbeddedAssetStream("chinesedragon.dae")) { _dragonModel = new Model( GraphicsDevice, factory, dragonModelStream, "dae", _vertexLayout, new Model.ModelCreateInfo(new Vector3(0.3f, -0.3f, 0.3f), Vector2.One, Vector3.Zero)); } using (Stream colorMapStream = OpenEmbeddedAssetStream("darkmetal_bc3_unorm.ktx")) { _colorMap = KtxFile.LoadTexture( GraphicsDevice, factory, colorMapStream, PixelFormat.BC3_UNorm); } _colorView = factory.CreateTextureView(_colorMap); _offscreenColor = factory.CreateTexture(TextureDescription.Texture2D( OffscreenWidth, OffscreenHeight, 1, 1, PixelFormat.R8_G8_B8_A8_UNorm, TextureUsage.RenderTarget | TextureUsage.Sampled)); _offscreenView = factory.CreateTextureView(_offscreenColor); Texture offscreenDepth = factory.CreateTexture(TextureDescription.Texture2D( OffscreenWidth, OffscreenHeight, 1, 1, PixelFormat.R16_UNorm, TextureUsage.DepthStencil)); _offscreenFB = factory.CreateFramebuffer(new FramebufferDescription(offscreenDepth, _offscreenColor)); ShaderSetDescription phongShaders = new ShaderSetDescription( new[] { _vertexLayout }, new[] { LoadShader(factory, "Phong", ShaderStages.Vertex, "VS"), LoadShader(factory, "Phong", ShaderStages.Fragment, "FS") }); ResourceLayout phongLayout = factory.CreateResourceLayout(new ResourceLayoutDescription( new ResourceLayoutElementDescription("UBO", ResourceKind.UniformBuffer, ShaderStages.Vertex))); GraphicsPipelineDescription pd = new GraphicsPipelineDescription( BlendStateDescription.SingleOverrideBlend, DepthStencilStateDescription.DepthOnlyLessEqual, new RasterizerStateDescription(FaceCullMode.Front, PolygonFillMode.Solid, FrontFace.Clockwise, true, false), PrimitiveTopology.TriangleList, phongShaders, phongLayout, _offscreenFB.OutputDescription); _offscreenPipeline = factory.CreateGraphicsPipeline(pd); pd.Outputs = GraphicsDevice.SwapchainFramebuffer.OutputDescription; pd.RasterizerState = RasterizerStateDescription.Default; _dragonPipeline = factory.CreateGraphicsPipeline(pd); ResourceLayout mirrorLayout = factory.CreateResourceLayout(new ResourceLayoutDescription( new ResourceLayoutElementDescription("UBO", ResourceKind.UniformBuffer, ShaderStages.Vertex), new ResourceLayoutElementDescription("ReflectionMap", ResourceKind.TextureReadOnly, ShaderStages.Fragment), new ResourceLayoutElementDescription("ReflectionMapSampler", ResourceKind.Sampler, ShaderStages.Fragment), new ResourceLayoutElementDescription("ColorMap", ResourceKind.TextureReadOnly, ShaderStages.Fragment), new ResourceLayoutElementDescription("ColorMapSampler", ResourceKind.Sampler, ShaderStages.Fragment))); ShaderSetDescription mirrorShaders = new ShaderSetDescription( new[] { _vertexLayout }, new[] { LoadShader(factory, "Mirror", ShaderStages.Vertex, "VS"), LoadShader(factory, "Mirror", ShaderStages.Fragment, "FS") }); GraphicsPipelineDescription mirrorPD = new GraphicsPipelineDescription( BlendStateDescription.SingleOverrideBlend, DepthStencilStateDescription.DepthOnlyLessEqual, new RasterizerStateDescription(FaceCullMode.None, PolygonFillMode.Solid, FrontFace.Clockwise, true, false), PrimitiveTopology.TriangleList, mirrorShaders, mirrorLayout, GraphicsDevice.SwapchainFramebuffer.OutputDescription); _mirrorPipeline = factory.CreateGraphicsPipeline(ref mirrorPD); _uniformBuffers_vsShared = factory.CreateBuffer(new BufferDescription(208, BufferUsage.UniformBuffer | BufferUsage.Dynamic)); _uniformBuffers_vsMirror = factory.CreateBuffer(new BufferDescription(208, BufferUsage.UniformBuffer | BufferUsage.Dynamic)); _uniformBuffers_vsOffScreen = factory.CreateBuffer(new BufferDescription(208, BufferUsage.UniformBuffer | BufferUsage.Dynamic)); _offscreenResourceSet = factory.CreateResourceSet(new ResourceSetDescription(phongLayout, _uniformBuffers_vsOffScreen)); _dragonResourceSet = factory.CreateResourceSet(new ResourceSetDescription(phongLayout, _uniformBuffers_vsShared)); _mirrorResourceSet = factory.CreateResourceSet(new ResourceSetDescription(mirrorLayout, _uniformBuffers_vsMirror, _offscreenView, GraphicsDevice.LinearSampler, _colorView, GraphicsDevice.Aniso4xSampler)); _cl = factory.CreateCommandList(); }
protected override void CreateResources(ResourceFactory factory) { _instanceCount = 8000u; _camera.Position = new Vector3(-36f, 20f, 100f); _camera.Pitch = -0.3f; _camera.Yaw = 0.1f; _cameraProjViewBuffer = factory.CreateBuffer( new BufferDescription((uint)(Unsafe.SizeOf <Matrix4x4>() * 2), BufferUsage.UniformBuffer | BufferUsage.Dynamic)); _lightInfoBuffer = factory.CreateBuffer(new BufferDescription(32, BufferUsage.UniformBuffer | BufferUsage.Dynamic)); _rotationInfoBuffer = factory.CreateBuffer(new BufferDescription(16, BufferUsage.UniformBuffer | BufferUsage.Dynamic)); _lightDir = Vector3.Normalize(new Vector3(0.3f, -0.75f, -0.3f)); VertexLayoutDescription sharedVertexLayout = new VertexLayoutDescription( new VertexElementDescription("Position", VertexElementSemantic.Position, VertexElementFormat.Float3), new VertexElementDescription("Normal", VertexElementSemantic.Normal, VertexElementFormat.Float3), new VertexElementDescription("TexCoord", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float2)); bool etc2Supported = GraphicsDevice.GetPixelFormatSupport( PixelFormat.ETC2_R8_G8_B8_UNorm, TextureType.Texture2D, TextureUsage.Sampled); PixelFormat pixelFormat = etc2Supported ? PixelFormat.ETC2_R8_G8_B8_UNorm : PixelFormat.BC3_UNorm; byte[] rockTextureData = LoadEmbeddedAsset <byte[]>( etc2Supported ? "texturearray_rocks_etc2_unorm.binary" : "texturearray_rocks_bc3_unorm.binary"); Texture rockTexture = KtxFile.LoadTexture( GraphicsDevice, ResourceFactory, rockTextureData, pixelFormat); TextureView rockTextureView = ResourceFactory.CreateTextureView(rockTexture); ResourceLayoutElementDescription[] resourceLayoutElementDescriptions = { new ResourceLayoutElementDescription("ProjView", ResourceKind.UniformBuffer, ShaderStages.Vertex), new ResourceLayoutElementDescription("RotationInfo", ResourceKind.UniformBuffer, ShaderStages.Vertex), new ResourceLayoutElementDescription("LightInfo", ResourceKind.UniformBuffer, ShaderStages.Fragment), }; ResourceLayoutDescription resourceLayoutDescription = new ResourceLayoutDescription(resourceLayoutElementDescriptions); ResourceLayout sharedLayout = factory.CreateResourceLayout(resourceLayoutDescription); ResourceLayoutElementDescription[] textureLayoutDescriptions = { new ResourceLayoutElementDescription("Tex", ResourceKind.TextureReadOnly, ShaderStages.Fragment), new ResourceLayoutElementDescription("Samp", ResourceKind.Sampler, ShaderStages.Fragment) }; ResourceLayout textureLayout = factory.CreateResourceLayout(new ResourceLayoutDescription(textureLayoutDescriptions)); BindableResource[] bindableResources = new BindableResource[] { _cameraProjViewBuffer, _rotationInfoBuffer, _lightInfoBuffer }; ResourceSetDescription resourceSetDescription = new ResourceSetDescription(sharedLayout, bindableResources); _sharedResourceSet = factory.CreateResourceSet(resourceSetDescription); BindableResource[] instanceBindableResources = { rockTextureView, GraphicsDevice.LinearSampler }; _instanceTextureSet = factory.CreateResourceSet(new ResourceSetDescription(textureLayout, instanceBindableResources)); ProcessedModel rock = LoadEmbeddedAsset <ProcessedModel>("rock01.binary"); _rockModel = rock.MeshParts[0].CreateDeviceResources(GraphicsDevice, ResourceFactory); VertexLayoutDescription vertexLayoutPerInstance = new VertexLayoutDescription( new VertexElementDescription("InstancePosition", VertexElementSemantic.Position, VertexElementFormat.Float3), new VertexElementDescription("InstanceRotation", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float3), new VertexElementDescription("InstanceScale", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float3), new VertexElementDescription("InstanceTexArrayIndex", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Int1)); vertexLayoutPerInstance.InstanceStepRate = 1; _instanceVB = ResourceFactory.CreateBuffer(new BufferDescription(InstanceInfo.Size * _instanceCount, BufferUsage.VertexBuffer)); InstanceInfo[] infos = new InstanceInfo[_instanceCount]; Random r = new Random(); float orbitDistance = 50f; for (uint i = 0; i < _instanceCount / 2; i++) { float angle = (float)(r.NextDouble() * Math.PI * 2); infos[i] = new InstanceInfo( new Vector3( ((float)Math.Cos(angle) * orbitDistance) + (float)(-10 + r.NextDouble() * 20), (float)(-1.5 + r.NextDouble() * 3), ((float)Math.Sin(angle) * orbitDistance) + (float)(-10 + r.NextDouble() * 20)), new Vector3( (float)(r.NextDouble() * Math.PI * 2), (float)(r.NextDouble() * Math.PI * 2), (float)(r.NextDouble() * Math.PI * 2)), new Vector3((float)(0.65 + r.NextDouble() * 0.35)), r.Next(0, (int)rockTexture.ArrayLayers)); } orbitDistance = 100f; for (uint i = _instanceCount / 2; i < _instanceCount; i++) { float angle = (float)(r.NextDouble() * Math.PI * 2); infos[i] = new InstanceInfo( new Vector3( ((float)Math.Cos(angle) * orbitDistance) + (float)(-10 + r.NextDouble() * 20), (float)(-1.5 + r.NextDouble() * 3), ((float)Math.Sin(angle) * orbitDistance) + (float)(-10 + r.NextDouble() * 20)), new Vector3( (float)(r.NextDouble() * Math.PI * 2), (float)(r.NextDouble() * Math.PI * 2), (float)(r.NextDouble() * Math.PI * 2)), new Vector3((float)(0.65 + r.NextDouble() * 0.35)), r.Next(0, (int)rockTexture.ArrayLayers)); } GraphicsDevice.UpdateBuffer(_instanceVB, 0, infos); Shader instanceVS = LoadShader(ResourceFactory, "Instance", ShaderStages.Vertex, "VS"); Shader instanceFS = LoadShader(ResourceFactory, "Instance", ShaderStages.Fragment, "FS"); GraphicsPipelineDescription pipelineDescription = new GraphicsPipelineDescription() { BlendState = BlendStateDescription.SingleOverrideBlend, DepthStencilState = new DepthStencilStateDescription( depthTestEnabled: true, depthWriteEnabled: true, comparisonKind: ComparisonKind.LessEqual), RasterizerState = new RasterizerStateDescription( cullMode: FaceCullMode.Back, fillMode: PolygonFillMode.Solid, frontFace: FrontFace.Clockwise, depthClipEnabled: true, scissorTestEnabled: false ), PrimitiveTopology = PrimitiveTopology.TriangleList, ResourceLayouts = new ResourceLayout[] { sharedLayout, textureLayout }, ShaderSet = new ShaderSetDescription( // The ordering of layouts directly impacts shader layout schemes vertexLayouts: new VertexLayoutDescription[] { sharedVertexLayout, vertexLayoutPerInstance }, shaders: new Shader[] { instanceVS, instanceFS } ), Outputs = MainSwapchain.Framebuffer.OutputDescription }; _instancePipeline = factory.CreateGraphicsPipeline(pipelineDescription); // Create planet Pipeline // Almost everything is the same as the rock Pipeline, // except no instance vertex buffer is needed, and different shaders are used. pipelineDescription.ShaderSet = new ShaderSetDescription( new[] { sharedVertexLayout }, new[] { LoadShader(ResourceFactory, "Planet", ShaderStages.Vertex, "VS"), LoadShader(ResourceFactory, "Planet", ShaderStages.Fragment, "FS"), }); _planetPipeline = ResourceFactory.CreateGraphicsPipeline(pipelineDescription); ProcessedModel planet = LoadEmbeddedAsset <ProcessedModel>("sphere.binary"); _planetModel = planet.MeshParts[0].CreateDeviceResources(GraphicsDevice, ResourceFactory); byte[] planetTexData = LoadEmbeddedAsset <byte[]>( etc2Supported ? "lavaplanet_etc2_unorm.binary" : "lavaplanet_bc3_unorm.binary"); Texture planetTexture = KtxFile.LoadTexture(GraphicsDevice, ResourceFactory, planetTexData, pixelFormat); TextureView planetTextureView = ResourceFactory.CreateTextureView(planetTexture); _planetTextureSet = ResourceFactory.CreateResourceSet(new ResourceSetDescription(textureLayout, planetTextureView, GraphicsDevice.Aniso4xSampler)); // Starfield resources ResourceLayout invCameraInfoLayout = ResourceFactory.CreateResourceLayout(new ResourceLayoutDescription( new ResourceLayoutElementDescription("InvCameraInfo", ResourceKind.UniformBuffer, ShaderStages.Fragment))); _viewInfoBuffer = ResourceFactory.CreateBuffer(new BufferDescription((uint)Unsafe.SizeOf <InvCameraInfo>(), BufferUsage.UniformBuffer | BufferUsage.Dynamic)); _viewInfoSet = ResourceFactory.CreateResourceSet(new ResourceSetDescription(invCameraInfoLayout, _viewInfoBuffer)); ShaderSetDescription starfieldShaders = new ShaderSetDescription( Array.Empty <VertexLayoutDescription>(), new[] { LoadShader(ResourceFactory, "Starfield", ShaderStages.Vertex, "VS"), LoadShader(ResourceFactory, "Starfield", ShaderStages.Fragment, "FS"), }); _starfieldPipeline = ResourceFactory.CreateGraphicsPipeline(new GraphicsPipelineDescription( BlendStateDescription.SingleOverrideBlend, DepthStencilStateDescription.Disabled, RasterizerStateDescription.CullNone, PrimitiveTopology.TriangleList, starfieldShaders, new[] { invCameraInfoLayout }, MainSwapchain.Framebuffer.OutputDescription)); _commandList = factory.CreateCommandList(); }
protected override void CreateResources(ResourceFactory factory) { _projectionBuffer = factory.CreateBuffer(new BufferDescription(64, BufferUsage.UniformBuffer | BufferUsage.Dynamic)); _viewBuffer = factory.CreateBuffer(new BufferDescription(64, BufferUsage.UniformBuffer | BufferUsage.Dynamic)); _worldBuffer = factory.CreateBuffer(new BufferDescription(64, BufferUsage.UniformBuffer | BufferUsage.Dynamic)); Matrix4x4 worldMatrix = Matrix4x4.CreateTranslation(0, 15000, -5000) * Matrix4x4.CreateRotationX(3 * (float)Math.PI / 2) * Matrix4x4.CreateScale(0.05f); GraphicsDevice.UpdateBuffer(_worldBuffer, 0, ref worldMatrix); ResourceLayout layout = factory.CreateResourceLayout(new ResourceLayoutDescription( new ResourceLayoutElementDescription("Projection", ResourceKind.UniformBuffer, ShaderStages.Vertex), new ResourceLayoutElementDescription("View", ResourceKind.UniformBuffer, ShaderStages.Vertex), new ResourceLayoutElementDescription("World", ResourceKind.UniformBuffer, ShaderStages.Vertex), new ResourceLayoutElementDescription("Bones", ResourceKind.UniformBuffer, ShaderStages.Vertex), new ResourceLayoutElementDescription("SurfaceTex", ResourceKind.TextureReadOnly, ShaderStages.Fragment), new ResourceLayoutElementDescription("SurfaceSampler", ResourceKind.Sampler, ShaderStages.Fragment))); Texture texture; using (Stream ktxStream = OpenEmbeddedAssetStream("goblin_bc3_unorm.ktx")) { texture = KtxFile.LoadTexture( GraphicsDevice, factory, ktxStream, PixelFormat.BC3_UNorm); } _texView = ResourceFactory.CreateTextureView(texture); VertexLayoutDescription vertexLayouts = new VertexLayoutDescription( new[] { new VertexElementDescription("Position", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float3), new VertexElementDescription("UV", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float2), new VertexElementDescription("BoneWeights", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float4), new VertexElementDescription("BoneIndices", VertexElementSemantic.TextureCoordinate, VertexElementFormat.UInt4), }); GraphicsPipelineDescription gpd = new GraphicsPipelineDescription( BlendStateDescription.SingleOverrideBlend, DepthStencilStateDescription.DepthOnlyLessEqual, new RasterizerStateDescription(FaceCullMode.Back, PolygonFillMode.Solid, FrontFace.CounterClockwise, true, false), PrimitiveTopology.TriangleList, new ShaderSetDescription( new[] { vertexLayouts }, factory.CreateFromSpirv( new ShaderDescription(ShaderStages.Vertex, Encoding.UTF8.GetBytes(VertexCode), "main"), new ShaderDescription(ShaderStages.Fragment, Encoding.UTF8.GetBytes(FragmentCode), "main"))), layout, GraphicsDevice.SwapchainFramebuffer.OutputDescription); _pipeline = factory.CreateGraphicsPipeline(ref gpd); AssimpContext ac = new AssimpContext(); using (Stream modelStream = OpenEmbeddedAssetStream("goblin.dae")) { _scene = ac.ImportFileFromStream(modelStream, "dae"); } _rootNodeInverseTransform = _scene.RootNode.Transform; _rootNodeInverseTransform.Inverse(); _firstMesh = _scene.Meshes[0]; AnimatedVertex[] vertices = new AnimatedVertex[_firstMesh.VertexCount]; for (int i = 0; i < vertices.Length; i++) { vertices[i].Position = new Vector3(_firstMesh.Vertices[i].X, _firstMesh.Vertices[i].Y, _firstMesh.Vertices[i].Z); vertices[i].UV = new Vector2(_firstMesh.TextureCoordinateChannels[0][i].X, _firstMesh.TextureCoordinateChannels[0][i].Y); } _animation = _scene.Animations[0]; List <int> indices = new List <int>(); foreach (Face face in _firstMesh.Faces) { if (face.IndexCount == 3) { indices.Add(face.Indices[0]); indices.Add(face.Indices[1]); indices.Add(face.Indices[2]); } } for (uint boneID = 0; boneID < _firstMesh.BoneCount; boneID++) { Bone bone = _firstMesh.Bones[(int)boneID]; _boneIDsByName.Add(bone.Name, boneID); foreach (VertexWeight weight in bone.VertexWeights) { vertices[weight.VertexID].AddBone(boneID, weight.Weight); } } Array.Resize(ref _boneTransformations, _firstMesh.BoneCount); _bonesBuffer = ResourceFactory.CreateBuffer(new BufferDescription( 64 * 64, BufferUsage.UniformBuffer | BufferUsage.Dynamic)); _rs = factory.CreateResourceSet(new ResourceSetDescription(layout, _projectionBuffer, _viewBuffer, _worldBuffer, _bonesBuffer, _texView, GraphicsDevice.Aniso4xSampler)); _indexCount = (uint)indices.Count; _vertexBuffer = ResourceFactory.CreateBuffer(new BufferDescription( (uint)(vertices.Length * Unsafe.SizeOf <AnimatedVertex>()), BufferUsage.VertexBuffer)); GraphicsDevice.UpdateBuffer(_vertexBuffer, 0, vertices); _indexBuffer = ResourceFactory.CreateBuffer(new BufferDescription( _indexCount * 4, BufferUsage.IndexBuffer)); GraphicsDevice.UpdateBuffer(_indexBuffer, 0, indices.ToArray()); _cl = factory.CreateCommandList(); _camera.Position = new Vector3(110, -87, -532); _camera.Yaw = 0.45f; _camera.Pitch = -0.55f; _camera.MoveSpeed = 1000f; _camera.FarDistance = 100000; }
protected override void CreateResources(ResourceFactory factory) { _instanceCount = 1 << 14; _camera.Position = new Vector3(-36f, 20f, 100f); _camera.Pitch = -0.3f; _camera.Yaw = 0.1f; _cameraProjViewBuffer = factory.CreateBuffer( new BufferDescription((uint)(Unsafe.SizeOf <Matrix4x4>() * 2), BufferUsage.UniformBuffer | BufferUsage.Dynamic)); _lightInfoBuffer = factory.CreateBuffer(new BufferDescription(32, BufferUsage.UniformBuffer | BufferUsage.Dynamic)); _rotationInfoBuffer = factory.CreateBuffer(new BufferDescription(16, BufferUsage.UniformBuffer | BufferUsage.Dynamic)); _lightDir = Vector3.Normalize(new Vector3(0.3f, -0.75f, -0.3f)); VertexLayoutDescription sharedVertexLayout = new VertexLayoutDescription( new VertexElementDescription("Position", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float3), new VertexElementDescription("Normal", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float3), new VertexElementDescription("TexCoord", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float2)); bool etc2Supported = GraphicsDevice.GetPixelFormatSupport( PixelFormat.ETC2_R8_G8_B8_UNorm, TextureType.Texture2D, TextureUsage.Sampled); PixelFormat pixelFormat = etc2Supported ? PixelFormat.ETC2_R8_G8_B8_UNorm : PixelFormat.BC3_UNorm; byte[] rockTextureData = LoadEmbeddedAsset <byte[]>( etc2Supported ? "texturearray_rocks_etc2_unorm.binary" : "texturearray_rocks_bc3_unorm.binary"); Texture rockTexture = KtxFile.LoadTexture( GraphicsDevice, ResourceFactory, rockTextureData, pixelFormat); TextureView rockTextureView = ResourceFactory.CreateTextureView(rockTexture); ResourceLayoutElementDescription[] resourceLayoutElementDescriptions = { new ResourceLayoutElementDescription("LightInfo", ResourceKind.UniformBuffer, ShaderStages.Fragment), new ResourceLayoutElementDescription("ProjView", ResourceKind.UniformBuffer, ShaderStages.Vertex), new ResourceLayoutElementDescription("RotationInfo", ResourceKind.UniformBuffer, ShaderStages.Vertex), }; ResourceLayoutDescription resourceLayoutDescription = new ResourceLayoutDescription(resourceLayoutElementDescriptions); ResourceLayout sharedLayout = factory.CreateResourceLayout(resourceLayoutDescription); ResourceLayoutElementDescription[] textureLayoutDescriptions = { new ResourceLayoutElementDescription("Tex", ResourceKind.TextureReadOnly, ShaderStages.Fragment), new ResourceLayoutElementDescription("Samp", ResourceKind.Sampler, ShaderStages.Fragment) }; ResourceLayout textureLayout = factory.CreateResourceLayout(new ResourceLayoutDescription(textureLayoutDescriptions)); BindableResource[] bindableResources = new BindableResource[] { _lightInfoBuffer, _cameraProjViewBuffer, _rotationInfoBuffer }; ResourceSetDescription resourceSetDescription = new ResourceSetDescription(sharedLayout, bindableResources); _sharedResourceSet = factory.CreateResourceSet(resourceSetDescription); BindableResource[] instanceBindableResources = { rockTextureView, GraphicsDevice.LinearSampler }; _instanceTextureSet = factory.CreateResourceSet(new ResourceSetDescription(textureLayout, instanceBindableResources)); ProcessedModel rock = LoadEmbeddedAsset <ProcessedModel>("sphere.binary"); _rockModel = rock.MeshParts[0].CreateDeviceResources(GraphicsDevice, ResourceFactory); VertexLayoutDescription vertexLayoutPerInstancePos = new VertexLayoutDescription( new VertexElementDescription("InstancePosition", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float3)); VertexLayoutDescription vertexLayoutPerInstanceScale = new VertexLayoutDescription( new VertexElementDescription("InstanceScale", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float3)); VertexLayoutDescription vertexLayoutPerInstanceColor = new VertexLayoutDescription( new VertexElementDescription("InstanceColor", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float3)); vertexLayoutPerInstancePos.InstanceStepRate = 1; vertexLayoutPerInstanceScale.InstanceStepRate = 1; vertexLayoutPerInstanceColor.InstanceStepRate = 1; _instanceVBPos = ResourceFactory.CreateBuffer(new BufferDescription(Vector3.Size * _instanceCount, BufferUsage.VertexBuffer)); _instanceVBScale = ResourceFactory.CreateBuffer(new BufferDescription(Vector3.Size * _instanceCount, BufferUsage.VertexBuffer)); _instanceVBColor = ResourceFactory.CreateBuffer(new BufferDescription(Vector3.Size * _instanceCount, BufferUsage.VertexBuffer)); Vector3[] instancePos = new Vector3[_instanceCount]; Vector3[] instanceScale = new Vector3[_instanceCount]; Vector3[] instanceColors = new Vector3[_instanceCount]; Random r = new Random(); for (uint i = 0; i < _instanceCount; i++) { instancePos[i] = new Vector3( 1000.0f * ((float)r.NextDouble() - 0.5f), 200.0f * ((float)r.NextDouble() - 0.5f), 1000.0f * ((float)r.NextDouble() - 0.5f)); instanceScale[i] = new Vector3((float)(r.NextDouble() * 0.3)); instanceColors[i] = new Vector3((float)r.NextDouble() * 0.5f + 0.5f, (float)r.NextDouble() * 0.5f + 0.5f, (float)r.NextDouble() * 0.5f + 0.5f); } GraphicsDevice.UpdateBuffer(_instanceVBPos, 0, instancePos); GraphicsDevice.UpdateBuffer(_instanceVBScale, 0, instanceScale); GraphicsDevice.UpdateBuffer(_instanceVBColor, 0, instanceColors); GraphicsPipelineDescription pipelineDescriptionRocks = new GraphicsPipelineDescription() { BlendState = BlendStateDescription.SingleOverrideBlend, DepthStencilState = new DepthStencilStateDescription( depthTestEnabled: true, depthWriteEnabled: true, comparisonKind: ComparisonKind.LessEqual), RasterizerState = new RasterizerStateDescription( cullMode: FaceCullMode.Back, fillMode: PolygonFillMode.Solid, frontFace: FrontFace.Clockwise, depthClipEnabled: true, scissorTestEnabled: false ), PrimitiveTopology = PrimitiveTopology.TriangleList, ResourceLayouts = new ResourceLayout[] { sharedLayout, textureLayout }, ShaderSet = new ShaderSetDescription( // The ordering of layouts directly impacts shader layout schemes vertexLayouts: new VertexLayoutDescription[] { sharedVertexLayout, vertexLayoutPerInstancePos, vertexLayoutPerInstanceScale, vertexLayoutPerInstanceColor }, shaders: LoadShaders("Instance") ), Outputs = MainSwapchain.Framebuffer.OutputDescription }; _instancePipeline = factory.CreateGraphicsPipeline(pipelineDescriptionRocks); // Starfield resources ResourceLayout invCameraInfoLayout = ResourceFactory.CreateResourceLayout(new ResourceLayoutDescription( new ResourceLayoutElementDescription("InvCameraInfo", ResourceKind.UniformBuffer, ShaderStages.Fragment))); _viewInfoBuffer = ResourceFactory.CreateBuffer(new BufferDescription((uint)Unsafe.SizeOf <MatrixPair>(), BufferUsage.UniformBuffer | BufferUsage.Dynamic)); _commandList = factory.CreateCommandList(); }