Skip to content

Instantly share code, notes, and snippets.

@x2048
Last active August 28, 2022 12:49
Show Gist options
  • Save x2048/7b398f6e10a0f302971d034931dadfa5 to your computer and use it in GitHub Desktop.
Save x2048/7b398f6e10a0f302971d034931dadfa5 to your computer and use it in GitHub Desktop.
Minetest post-processing pipeline basics

Concepts

  • RenderStep - a single step in the pipeline, such as running the 3D render, changing state or applying a shader. Each step has a source and a target
    • RenderSource - a source for the step, a set of textures that are used in the step
    • RenderTarget - a target for the step, a framebuffer with one or more attached textures / renderbuffers.
  • Pipeline - a sequence of steps and associated objects such as TextBuffers.
  • TextureBuffer - an indexed set of textures that you need, you can create up to 254 textures if the driver permits.
    • TextureBuffer is also a RenderSource and a RenderTarget.
    • Normally you have a single texture buffer that all the steps write to and read from
  • PostProcessingStep : RenderStep - draws a full-screen quad with given shader, RenderSource and RenderTarget.

Adding a post-processing step

The pipeline is located in secondstage.cpp.

In order to add a post-processing step:

  1. If you need extra textures, add them to the buffer:
  • Declare TEXTURE_XXX constant
  • Add buffer->setTexture(TEXTURE_XXX, scale, "<some meaningful name>", video::ECF_A8R8G8B8); to register a texture
  1. Create shader code in GLSL:
  1. Set up the postprocessing step:
  • Request a shader with the following code:
IWritableShaderSource *s = client->getShaderSource();
  u32 shader_index = s->getShader(
  		"depth_of_field", // name of the folder with the shader code
  		TILE_MATERIAL_BASIC, // material parameter
  		NDT_NORMAL); // node draw type parameter
  video::E_MATERIAL_TYPE shader = s->getShaderInfo(shader_index).material;
  • Add the step
RenderStep *effect = pipeline->addStep<PostProcessingStep>(
    shader, // ID of the shader renderer
    std::vector<u8> { TEXTURE_XXX, ... }); // IDs of the textures in the buffer to map to samplers 0, 1, 2 ...
  effect->setRenderSource(buffer);
effect->setRenderTarget(pipeline->createOwned<TextureBufferOutput>(buffer, TEXTURE_YYY)

Note: Make sure all steps are wired to the correct textures. Note: Make sure that the final step is returned from the method, so it's output is routed to the screen later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment