protected Graphics.Effect ComputeMeshFallbackEffect(RenderObject renderObject, [NotNull] RenderEffect renderEffect, RenderEffectState renderEffectState) { try { var renderMesh = (RenderMesh)renderObject; bool hasDiffuseMap = renderMesh.MaterialPass.Parameters.ContainsKey(MaterialKeys.DiffuseMap); var fallbackMaterial = hasDiffuseMap ? fallbackTextureMaterial : fallbackColorMaterial; // High priority var compilerParameters = new CompilerParameters { EffectParameters = { TaskPriority = -1 } }; // Support skinning if (renderMesh.Mesh.Skinning != null && renderMesh.Mesh.Skinning.Bones.Length <= 56) { compilerParameters.Set(MaterialKeys.HasSkinningPosition, renderMesh.Mesh.Parameters.Get(MaterialKeys.HasSkinningPosition)); compilerParameters.Set(MaterialKeys.HasSkinningNormal, renderMesh.Mesh.Parameters.Get(MaterialKeys.HasSkinningNormal)); compilerParameters.Set(MaterialKeys.HasSkinningTangent, renderMesh.Mesh.Parameters.Get(MaterialKeys.HasSkinningTangent)); compilerParameters.Set(MaterialKeys.SkinningMaxBones, 56); } // Set material permutations compilerParameters.Set(MaterialKeys.PixelStageSurfaceShaders, fallbackMaterial.Passes[0].Parameters.Get(MaterialKeys.PixelStageSurfaceShaders)); compilerParameters.Set(MaterialKeys.PixelStageStreamInitializer, fallbackMaterial.Passes[0].Parameters.Get(MaterialKeys.PixelStageStreamInitializer)); // Set lighting permutations (use custom white light, since this effect will not be processed by the lighting render feature) compilerParameters.Set(LightingKeys.EnvironmentLights, new ShaderSourceCollection { new ShaderClassSource("LightConstantWhite") }); // Initialize parameters with material ones (need a CopyTo?) renderEffect.FallbackParameters = new ParameterCollection(renderMesh.MaterialPass.Parameters); // Don't show selection wireframe/highlights as compiling var ignoreState = renderEffect.EffectSelector.EffectName.EndsWith(".Wireframe") || renderEffect.EffectSelector.EffectName.EndsWith(".Highlight") || renderEffect.EffectSelector.EffectName.EndsWith(".Picking"); // Also set a value so that we know something is loading (green glowing FX) or error (red glowing FX) if (!ignoreState) { if (renderEffectState == RenderEffectState.Compiling) { compilerParameters.Set(SceneEditorParameters.IsEffectCompiling, true); } else if (renderEffectState == RenderEffectState.Error) { compilerParameters.Set(SceneEditorParameters.IsEffectError, true); } } if (renderEffectState == RenderEffectState.Error) { // Retry every few seconds renderEffect.RetryTime = DateTime.UtcNow + TimeSpan.FromSeconds(5); } return(EffectSystem.LoadEffect(renderEffect.EffectSelector.EffectName, compilerParameters).WaitForResult()); } catch { // TODO: Log or rethrow? renderEffect.State = RenderEffectState.Error; return(null); } }
private ViewResourceGroupLayout CreateViewResourceGroupLayout(ResourceGroupDescription resourceGroupDescription, RenderEffectState effectState) { if (resourceGroupDescription.DescriptorSetLayout == null) { return(null); } // We combine both hash for DescriptorSet and cbuffer itself (if it exists) var hash = resourceGroupDescription.Hash; var effectStateHash = new ObjectId(0, 0, 0, (uint)effectState); ObjectId.Combine(ref effectStateHash, ref hash, out hash); ViewResourceGroupLayout result; if (!viewResourceLayouts.TryGetValue(hash, out result)) { result = new ViewResourceGroupLayout { DescriptorSetLayoutBuilder = resourceGroupDescription.DescriptorSetLayout, DescriptorSetLayout = DescriptorSetLayout.New(RenderSystem.GraphicsDevice, resourceGroupDescription.DescriptorSetLayout), ConstantBufferReflection = resourceGroupDescription.ConstantBufferReflection, Entries = new ResourceGroupEntry[RenderSystem.Views.Count], State = effectState, }; for (int index = 0; index < result.Entries.Length; index++) { result.Entries[index].Resources = new ResourceGroup(); } if (resourceGroupDescription.ConstantBufferReflection != null) { result.ConstantBufferSize = resourceGroupDescription.ConstantBufferReflection.Size; result.ConstantBufferHash = resourceGroupDescription.ConstantBufferReflection.Hash; } // Resolve slots result.ConstantBufferOffsets = new int[viewCBufferOffsetSlots.Count]; for (int index = 0; index < viewCBufferOffsetSlots.Count; index++) { ResolveCBufferOffset(result, index, viewCBufferOffsetSlots[index].Variable); } // Resolve logical groups result.LogicalGroups = new LogicalGroup[viewLogicalGroups.Count]; for (int index = 0; index < viewLogicalGroups.Count; index++) { ResolveLogicalGroup(result, index, viewLogicalGroups[index].Variable); } viewResourceLayouts.Add(hash, result); } return(result); }
private ViewResourceGroupLayout CreateViewResourceGroupLayout(ResourceGroupDescription resourceGroupDescription, RenderEffectState effectState) { if (resourceGroupDescription.DescriptorSetLayout == null) return null; // We combine both hash for DescriptorSet and cbuffer itself (if it exists) var hash = resourceGroupDescription.Hash; var effectStateHash = new ObjectId(0, 0, 0, (uint)effectState); ObjectId.Combine(ref effectStateHash, ref hash, out hash); ViewResourceGroupLayout result; if (!viewResourceLayouts.TryGetValue(hash, out result)) { result = new ViewResourceGroupLayout { DescriptorSetLayoutBuilder = resourceGroupDescription.DescriptorSetLayout, DescriptorSetLayout = DescriptorSetLayout.New(RenderSystem.GraphicsDevice, resourceGroupDescription.DescriptorSetLayout), ConstantBufferReflection = resourceGroupDescription.ConstantBufferReflection, Entries = new ResourceGroupEntry[RenderSystem.Views.Count], State = effectState, }; for (int index = 0; index < result.Entries.Length; index++) { result.Entries[index].Resources = new ResourceGroup(); } if (resourceGroupDescription.ConstantBufferReflection != null) { result.ConstantBufferSize = resourceGroupDescription.ConstantBufferReflection.Size; result.ConstantBufferHash = resourceGroupDescription.ConstantBufferReflection.Hash; } // Resolve slots result.ConstantBufferOffsets = new int[viewCBufferOffsetSlots.Count]; for (int index = 0; index < viewCBufferOffsetSlots.Count; index++) { ResolveCBufferOffset(result, index, viewCBufferOffsetSlots[index].Variable); } // Resolve logical groups result.LogicalGroups = new LogicalGroup[viewLogicalGroups.Count]; for (int index = 0; index < viewLogicalGroups.Count; index++) { ResolveLogicalGroup(result, index, viewLogicalGroups[index].Variable); } viewResourceLayouts.Add(hash, result); } return result; }
private RenderSystemResourceGroupLayout CreateDrawResourceGroupLayout(ResourceGroupDescription resourceGroupDescription, RenderEffectState effectState) { if (resourceGroupDescription.DescriptorSetLayout == null) { return(null); } var result = new RenderSystemResourceGroupLayout { DescriptorSetLayoutBuilder = resourceGroupDescription.DescriptorSetLayout, DescriptorSetLayout = DescriptorSetLayout.New(RenderSystem.GraphicsDevice, resourceGroupDescription.DescriptorSetLayout), ConstantBufferReflection = resourceGroupDescription.ConstantBufferReflection, }; result.State = effectState; if (resourceGroupDescription.ConstantBufferReflection != null) { result.ConstantBufferSize = resourceGroupDescription.ConstantBufferReflection.Size; result.ConstantBufferHash = resourceGroupDescription.ConstantBufferReflection.Hash; } // Resolve slots result.ConstantBufferOffsets = new int[drawCBufferOffsetSlots.Count]; for (int index = 0; index < drawCBufferOffsetSlots.Count; index++) { ResolveCBufferOffset(result, index, drawCBufferOffsetSlots[index].Variable); } // Resolve logical groups result.LogicalGroups = new LogicalGroup[drawLogicalGroups.Count]; for (int index = 0; index < drawLogicalGroups.Count; index++) { ResolveLogicalGroup(result, index, drawLogicalGroups[index].Variable); } return(result); }
private RenderSystemResourceGroupLayout CreateDrawResourceGroupLayout(ResourceGroupDescription resourceGroupDescription, RenderEffectState effectState) { if (resourceGroupDescription.DescriptorSetLayout == null) return null; var result = new RenderSystemResourceGroupLayout { DescriptorSetLayoutBuilder = resourceGroupDescription.DescriptorSetLayout, DescriptorSetLayout = DescriptorSetLayout.New(RenderSystem.GraphicsDevice, resourceGroupDescription.DescriptorSetLayout), ConstantBufferReflection = resourceGroupDescription.ConstantBufferReflection, }; result.State = effectState; if (resourceGroupDescription.ConstantBufferReflection != null) { result.ConstantBufferSize = resourceGroupDescription.ConstantBufferReflection.Size; result.ConstantBufferHash = resourceGroupDescription.ConstantBufferReflection.Hash; } // Resolve slots result.ConstantBufferOffsets = new int[drawCBufferOffsetSlots.Count]; for (int index = 0; index < drawCBufferOffsetSlots.Count; index++) { ResolveCBufferOffset(result, index, drawCBufferOffsetSlots[index].Variable); } // Resolve logical groups result.LogicalGroups = new LogicalGroup[drawLogicalGroups.Count]; for (int index = 0; index < drawLogicalGroups.Count; index++) { ResolveLogicalGroup(result, index, drawLogicalGroups[index].Variable); } return result; }