private ResourceSet[] CreateShadowMapResourceSets( ResourceFactory sharedFactory, ResourceFactory disposeFactory, CommandList cl, GraphicsSystem sc, ResourceLayout projViewLayout, ResourceLayout worldLayout) { ResourceSet[] ret = new ResourceSet[6]; for (int i = 0; i < 3; i++) { DeviceBuffer viewProjBuffer = i == 0 ? sc.LightViewProjectionBuffer0 : i == 1 ? sc.LightViewProjectionBuffer1 : sc.LightViewProjectionBuffer2; ret[i * 2] = StaticResourceCache.GetResourceSet(sharedFactory, new ResourceSetDescription( projViewLayout, viewProjBuffer)); ResourceSet worldRS = disposeFactory.CreateResourceSet(new ResourceSetDescription( worldLayout, _worldAndInverseBuffer)); ret[i * 2 + 1] = worldRS; } return(ret); }
public unsafe void CreateDeviceObjects(GraphicsDevice gd, CommandList cl, GraphicsSystem sc) { ResourceFactory disposeFactory = new DisposeCollectorResourceFactory(gd.ResourceFactory, _disposeCollector); _vb = _meshData.CreateVertexBuffer(disposeFactory, cl); _vb.Name = _name + "_VB"; _ib = _meshData.CreateIndexBuffer(disposeFactory, cl, out _indexCount); _ib.Name = _name + "_IB"; _worldAndInverseBuffer = disposeFactory.CreateBuffer(new BufferDescription(64 * 2, BufferUsage.UniformBuffer | BufferUsage.Dynamic)); if (_materialPropsOwned) { _materialProps.CreateDeviceObjects(gd, cl, sc); } if (_textureData != null) { _texture = StaticResourceCache.GetTexture2D(gd, gd.ResourceFactory, _textureData); } else { _texture = disposeFactory.CreateTexture(TextureDescription.Texture2D(1, 1, 1, 1, PixelFormat.R8_G8_B8_A8_UNorm, TextureUsage.Sampled)); RgbaByte color = RgbaByte.Pink; gd.UpdateTexture(_texture, (IntPtr)(&color), 4, 0, 0, 0, 1, 1, 1, 0, 0); } _textureView = StaticResourceCache.GetTextureView(gd.ResourceFactory, _texture); if (_alphaTextureData != null) { _alphamapTexture = _alphaTextureData.CreateDeviceTexture(gd, disposeFactory); } else { _alphamapTexture = StaticResourceCache.GetPinkTexture(gd, gd.ResourceFactory); } _alphaMapView = StaticResourceCache.GetTextureView(gd.ResourceFactory, _alphamapTexture); VertexLayoutDescription[] shadowDepthVertexLayouts = new VertexLayoutDescription[] { new VertexLayoutDescription( new VertexElementDescription("Position", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float3), new VertexElementDescription("Normal", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float3), new VertexElementDescription("TexCoord", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float2)) }; (Shader depthVS, Shader depthFS) = StaticResourceCache.GetShaders(gd, gd.ResourceFactory, "ShadowDepth"); ResourceLayout projViewCombinedLayout = StaticResourceCache.GetResourceLayout( gd.ResourceFactory, new ResourceLayoutDescription( new ResourceLayoutElementDescription("ViewProjection", ResourceKind.UniformBuffer, ShaderStages.Vertex))); ResourceLayout worldLayout = StaticResourceCache.GetResourceLayout(gd.ResourceFactory, new ResourceLayoutDescription( new ResourceLayoutElementDescription("WorldAndInverse", ResourceKind.UniformBuffer, ShaderStages.Vertex))); GraphicsPipelineDescription depthPD = new GraphicsPipelineDescription( BlendStateDescription.Empty, gd.IsDepthRangeZeroToOne ? DepthStencilStateDescription.DepthOnlyGreaterEqual : DepthStencilStateDescription.DepthOnlyLessEqual, RasterizerStateDescription.Default, PrimitiveTopology.TriangleList, new ShaderSetDescription(shadowDepthVertexLayouts, new[] { depthVS, depthFS }), new ResourceLayout[] { projViewCombinedLayout, worldLayout }, sc.NearShadowMapFramebuffer.OutputDescription); _shadowMapPipeline = StaticResourceCache.GetPipeline(gd.ResourceFactory, ref depthPD); _shadowMapResourceSets = CreateShadowMapResourceSets(gd.ResourceFactory, disposeFactory, cl, sc, projViewCombinedLayout, worldLayout); VertexLayoutDescription[] mainVertexLayouts = new VertexLayoutDescription[] { new VertexLayoutDescription( new VertexElementDescription("Position", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float3), new VertexElementDescription("Normal", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float3), new VertexElementDescription("TexCoord", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float2)) }; (Shader mainVS, Shader mainFS) = StaticResourceCache.GetShaders(gd, gd.ResourceFactory, "ShadowMain"); ResourceLayout projViewLayout = StaticResourceCache.GetResourceLayout( gd.ResourceFactory, StaticResourceCache.ProjViewLayoutDescription); ResourceLayout mainSharedLayout = StaticResourceCache.GetResourceLayout(gd.ResourceFactory, new ResourceLayoutDescription( new ResourceLayoutElementDescription("LightViewProjection1", ResourceKind.UniformBuffer, ShaderStages.Vertex | ShaderStages.Fragment), new ResourceLayoutElementDescription("LightViewProjection2", ResourceKind.UniformBuffer, ShaderStages.Vertex | ShaderStages.Fragment), new ResourceLayoutElementDescription("LightViewProjection3", ResourceKind.UniformBuffer, ShaderStages.Vertex | ShaderStages.Fragment), new ResourceLayoutElementDescription("DepthLimits", ResourceKind.UniformBuffer, ShaderStages.Vertex | ShaderStages.Fragment), new ResourceLayoutElementDescription("LightInfo", ResourceKind.UniformBuffer, ShaderStages.Vertex | ShaderStages.Fragment), new ResourceLayoutElementDescription("CameraInfo", ResourceKind.UniformBuffer, ShaderStages.Vertex | ShaderStages.Fragment), new ResourceLayoutElementDescription("PointLights", ResourceKind.UniformBuffer, ShaderStages.Vertex | ShaderStages.Fragment))); ResourceLayout mainPerObjectLayout = StaticResourceCache.GetResourceLayout(gd.ResourceFactory, new ResourceLayoutDescription( new ResourceLayoutElementDescription("WorldAndInverse", ResourceKind.UniformBuffer, ShaderStages.Vertex | ShaderStages.Fragment), new ResourceLayoutElementDescription("MaterialProperties", ResourceKind.UniformBuffer, ShaderStages.Vertex | ShaderStages.Fragment), new ResourceLayoutElementDescription("SurfaceTexture", ResourceKind.TextureReadOnly, ShaderStages.Fragment), new ResourceLayoutElementDescription("RegularSampler", ResourceKind.Sampler, ShaderStages.Fragment), new ResourceLayoutElementDescription("AlphaMap", ResourceKind.TextureReadOnly, ShaderStages.Fragment), new ResourceLayoutElementDescription("AlphaMapSampler", ResourceKind.Sampler, ShaderStages.Fragment), new ResourceLayoutElementDescription("ShadowMapNear", ResourceKind.TextureReadOnly, ShaderStages.Fragment), new ResourceLayoutElementDescription("ShadowMapMid", ResourceKind.TextureReadOnly, ShaderStages.Fragment), new ResourceLayoutElementDescription("ShadowMapFar", ResourceKind.TextureReadOnly, ShaderStages.Fragment), new ResourceLayoutElementDescription("ShadowMapSampler", ResourceKind.Sampler, ShaderStages.Fragment))); ResourceLayout reflectionLayout = StaticResourceCache.GetResourceLayout(gd.ResourceFactory, new ResourceLayoutDescription( new ResourceLayoutElementDescription("ReflectionMap", ResourceKind.TextureReadOnly, ShaderStages.Fragment), new ResourceLayoutElementDescription("ReflectionSampler", ResourceKind.Sampler, ShaderStages.Fragment), new ResourceLayoutElementDescription("ReflectionViewProj", ResourceKind.UniformBuffer, ShaderStages.Vertex), new ResourceLayoutElementDescription("ClipPlaneInfo", ResourceKind.UniformBuffer, ShaderStages.Fragment))); GraphicsPipelineDescription mainPD = new GraphicsPipelineDescription( _alphamapTexture != null ? BlendStateDescription.SingleAlphaBlend : BlendStateDescription.SingleOverrideBlend, gd.IsDepthRangeZeroToOne ? DepthStencilStateDescription.DepthOnlyGreaterEqual : DepthStencilStateDescription.DepthOnlyLessEqual, RasterizerStateDescription.Default, PrimitiveTopology.TriangleList, new ShaderSetDescription(mainVertexLayouts, new[] { mainVS, mainFS }), new ResourceLayout[] { projViewLayout, mainSharedLayout, mainPerObjectLayout, reflectionLayout }, sc.MainSceneFramebuffer.OutputDescription); _pipeline = StaticResourceCache.GetPipeline(gd.ResourceFactory, ref mainPD); _pipeline.Name = "MeshRenderer Main Pipeline"; mainPD.RasterizerState.CullMode = FaceCullMode.Front; mainPD.Outputs = sc.ReflectionFramebuffer.OutputDescription; _pipelineFrontCull = StaticResourceCache.GetPipeline(gd.ResourceFactory, ref mainPD); _mainProjViewRS = StaticResourceCache.GetResourceSet(gd.ResourceFactory, new ResourceSetDescription(projViewLayout, sc.ProjectionMatrixBuffer, sc.ViewMatrixBuffer)); _mainSharedRS = StaticResourceCache.GetResourceSet(gd.ResourceFactory, new ResourceSetDescription(mainSharedLayout, sc.LightViewProjectionBuffer0, sc.LightViewProjectionBuffer1, sc.LightViewProjectionBuffer2, sc.DepthLimitsBuffer, sc.LightInfoBuffer, sc.CameraInfoBuffer, sc.PointLightsBuffer)); _mainPerObjectRS = disposeFactory.CreateResourceSet(new ResourceSetDescription(mainPerObjectLayout, _worldAndInverseBuffer, _materialProps.UniformBuffer, _textureView, gd.Aniso4xSampler, _alphaMapView, gd.LinearSampler, sc.NearShadowMapView, sc.MidShadowMapView, sc.FarShadowMapView, gd.PointSampler)); _reflectionRS = StaticResourceCache.GetResourceSet(gd.ResourceFactory, new ResourceSetDescription(reflectionLayout, _alphaMapView, // Doesn't really matter -- just don't bind the actual reflection map since it's being rendered to. gd.PointSampler, sc.ReflectionViewProjBuffer, sc.MirrorClipPlaneBuffer)); _noReflectionRS = StaticResourceCache.GetResourceSet(gd.ResourceFactory, new ResourceSetDescription(reflectionLayout, sc.ReflectionColorView, gd.PointSampler, sc.ReflectionViewProjBuffer, sc.NoClipPlaneBuffer)); }