Download

Mesh shaders in plugins

Greetings. I have a few questions regarding custom mesh formats.

First question is, is it possible to create a custom mesh shading pipeline in a plugin?
I understand how to pass data via Vertex Factories, but i could not find any info on shaders themselves. Like how would you create a VS->GS->PS pipeline with a vertex factory, and then expose new data passed to the PS to the material editor.

I’m basically trying to achieve a paintable mesh via passing indecies as part of the vertex data, same as colors, basically. Color painting is non-sufficient for me since it oly allows blending of 5 textures per material.

To your point. By 5 textures what do you mean exactly?

You have a max of 128 shared samplers
And a max of 16 clamped samplers
Using DX11.

You literally have to do things wrong to run out of shared samplers. So I’m not sure what your 5 textures means.

Regardless, it would likely be a lot easier to split your models into more parts manually if you acrually happen to be hitting limitations.

More static meshes with more samples = more drawcalls. But it beats the overhead and complexity of doing what you asked for…

I meant that using colors you have a limited amount of channels.
Yeah, i thought about splitting models, but that would not allow me to blend materials between them.

I’m basically trying to port my hermite data based voxel landscape to UE. And i’m kinda struggling with its rendering system.

template <ELightMapPolicyType Policy>
bool GetUniformBasePassShaders(
	const FMaterial& Material,
	FVertexFactoryType* VertexFactoryType,
	ERHIFeatureLevel::Type FeatureLevel,
	bool bEnableAtmosphericFog,
	bool bEnableSkyLight,
	bool bUse128bitRT,
	TShaderRef<TBasePassVertexShaderPolicyParamType<FUniformLightMapPolicy>>* VertexShader,
	TShaderRef<TBasePassPixelShaderPolicyParamType<FUniformLightMapPolicy>>* PixelShader
)
{
	FMaterialShaderTypes ShaderTypes;
	if(VertexShader)
	{
		if (bEnableAtmosphericFog)
		{
			ShaderTypes.AddShaderType<TBasePassVS<TUniformLightMapPolicy<Policy>, true>>();
		}
		else
		{
			ShaderTypes.AddShaderType<TBasePassVS<TUniformLightMapPolicy<Policy>, false>>();
		}
	}

	if(PixelShader)
	{
		if (bEnableSkyLight)
		{
			ShaderTypes.AddShaderType<TBasePassPS<TUniformLightMapPolicy<Policy>, true>>();
		}
		else
		{
			if (bUse128bitRT && (Policy == LMP_NO_LIGHTMAP))
			{
				ShaderTypes.AddShaderType<F128BitRTBasePassPS>();
			}
			else
			{
				ShaderTypes.AddShaderType<TBasePassPS<TUniformLightMapPolicy<Policy>, false>>();
			}
		}
	}

	FMaterialShaders Shaders;
	if (!Material.TryGetShaders(ShaderTypes, VertexFactoryType, Shaders))
	{
		return false;
	}

	Shaders.TryGetVertexShader(VertexShader);
	Shaders.TryGetPixelShader(PixelShader);
	return true;
}

Well, I guess this answers my questions. Shaders for base pass are basically hardcoded.
For more info, look into BasePassRendering.cpp

1 Like

Glad you got some sort of an answer.

Colors have 4 channels. So that’s probably why 5 made no sense to me…
R G B A.

You can actually use vertex paint to index your mesh. And you’ll be OK so long as you only have 255^4 vertex.
That’s some 13,922 vertex per mesh.

How you do it, or how you use that, we’ll that’s a different story.

I commonly use vertex paint to preserve the original Z height of some objects that can be made taller via shader.

You could technically just use RGB as a read out of the original XYZ of the vertex in local space.
Works rather well with small floats too since it works for me on a 1m mesh without much of an issue.

No idea what the

Actually is. Will need to look it up out of curiosity.

However if you explain in base terms how it works, in a separate topic about voxels you may actually get some traction on the topic…

1 Like

I said 5 channels because, if i get it correctly, {0,0,0,0} is considered to be base for blending.