Skip to content

Instantly share code, notes, and snippets.

@ArieLeo
Forked from Eideren/YourGameDefinition.cs
Created February 13, 2024 15:21
Show Gist options
  • Save ArieLeo/ee449c04ca6764141397f649efc60f53 to your computer and use it in GitHub Desktop.
Save ArieLeo/ee449c04ca6764141397f649efc60f53 to your computer and use it in GitHub Desktop.
How to setup async shader compilation in stride, note that the game will still freeze initially to compile the fallback
public class YourGameDefinition : Stride.Engine.Game
{
protected override void BeginRun()
{
base.BeginRun();
foreach( var feature in SceneSystem.GraphicsCompositor.RenderFeatures )
{
if( feature is MeshRenderFeature meshRf )
{
meshRf.ComputeFallbackEffect += FallbackForAsyncCompilation;
}
}
}
Material fallbackColorMaterial;
Effect FallbackForAsyncCompilation(RenderObject renderObject, RenderEffect renderEffect, RenderEffectState renderEffectState)
{
// Source is 'ComputeMeshFallbackEffect' in EntityHierarchyEditorGame.cs
try
{
var renderMesh = (RenderMesh)renderObject;
fallbackColorMaterial ??= Material.New(GraphicsDevice, new MaterialDescriptor
{
Attributes =
{
Diffuse = new MaterialDiffuseMapFeature(new ComputeColor(new Color4(1f, 1f, 1f))),
DiffuseModel = new MaterialDiffuseLambertModelFeature()
}
});
// High priority
var compilerParameters = new CompilerParameters { EffectParameters = { TaskPriority = -1 } };
// Set material permutations
compilerParameters.Set(MaterialKeys.PixelStageSurfaceShaders, fallbackColorMaterial.Passes[0].Parameters.Get(MaterialKeys.PixelStageSurfaceShaders));
compilerParameters.Set(MaterialKeys.PixelStageStreamInitializer, fallbackColorMaterial.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);
if (renderEffectState == RenderEffectState.Error)
{
// Retry every few seconds
renderEffect.RetryTime = DateTime.UtcNow + TimeSpan.FromSeconds(5);
}
return EffectSystem.LoadEffect(renderEffect.EffectSelector.EffectName, compilerParameters).WaitForResult();
}
catch(Exception e)
{
renderEffect.State = RenderEffectState.Error;
System.Console.WriteLine(e.ToString());
return null;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment