STAT_OpenGLCreateBoundShaderStateTime hitches

I’ve run into hitches in our mobile game that seem to come from rebuilding the shader state when we spawn objects that have materials otherwise not already in the scene. Is this common and what is a good practice for addressing/preventing this?

Below is the code bit from engine source - OpenGLShaders.cpp - where I added a quick scope to catch the spikes and a screenshot of a sample profile with only an actor that adds a new box to the scene with one of our unique materials once per second.

Thank you for any advice,
Denis



...
	SCOPE_CYCLE_COUNTER(STAT_OpenGLCreateBoundShaderStateTime);

	if(!PixelShaderRHI)
	{
		// use special null pixel shader when PixelShader was set to NULL
		PixelShaderRHI = TShaderMapRef<FNULLPS>(GetGlobalShaderMap(GMaxRHIFeatureLevel))->GetPixelShader();
	}

	// Check for an existing bound shader state which matches the parameters
	FCachedBoundShaderStateLink* CachedBoundShaderStateLink = GetCachedBoundShaderState(
		VertexDeclarationRHI,
		VertexShaderRHI,
		PixelShaderRHI,
		HullShaderRHI,
		DomainShaderRHI,
		GeometryShaderRHI
		);

	if(CachedBoundShaderStateLink)
	{
		// If we've already created a bound shader state with these parameters, reuse it.
		return CachedBoundShaderStateLink->BoundShaderState;
	}
	else
	{
		QUICK_SCOPE_CYCLE_COUNTER(STAT_RedoShaderState);
		check(VertexDeclarationRHI);
		
		FOpenGLVertexDeclaration* VertexDeclaration = ResourceCast(VertexDeclarationRHI);
		FOpenGLVertexShader* VertexShader = ResourceCast(VertexShaderRHI);
		FOpenGLPixelShader* PixelShader = ResourceCast(PixelShaderRHI);
		FOpenGLHullShader* HullShader = ResourceCast(HullShaderRHI);
		FOpenGLDomainShader* DomainShader = ResourceCast(DomainShaderRHI);
		FOpenGLGeometryShader* GeometryShader = ResourceCast(GeometryShaderRHI);

		FOpenGLLinkedProgramConfiguration Config;
...


Hi dkorkh,

I’d suggest at startup looping through all your objects once to get the cache set to remove any hitches while playing.

This worked. Thank you.

Interestingly, I had to include the objects using materials in their context - if it were a material applied to a skeletal mesh then just cycling/pre-spawning a static mesh with that material was not enough to avoid a spike. Another note was that to find which material was causing spikes I ultimately graphed AddPrimitive, SpawnEmitterAtLocation (& attached), FinnishSpawningActor, AddActorComponent to help me track down any objects I may have missed - I imagine there are a number of others that could be useful for this such as SetMaterial and even anything that may be translating an object into the scene. Thank you for your help! :slight_smile:

Ughh, it’s an old thread, but how can I do this exactly? Right now when I first spawn muzzle flash effect, my game freezes momentarily and then goes on smooth after initial spawn.