Skip to content

Particles, post effects and the camera

Lesson 14.7

Your mod can paint on the world, not just add blocks: sparks, blood on the floor, a red haze over the screen, a tilted camera, thick fog. This lesson shows the tools in one small mod. The details are in the guides: Particles and Decals, Post-processing, Fog, Sky and Camera and Menus and Themes.

Particles

A particle type is a sprite sheet plus a few numbers. Register it in lifecycle.register (it runs on both sides):

cl.on("lifecycle.register", function()
  cl.render.particle_type("spark", {
    texture = "my_mod:textures/particle/spark.png", frames = 4, columns = 2,
    lifetime = 30, size = 0.12, size_end = 0.02, gravity = 0.02,
    color = "#FFFFD080", color_end = "#FFFF4000", emissive = true, additive = true,
    fallback = "minecraft:flame",   -- what players without your mod see
  })
end)

Spawn them anywhere you have a level: level:particle(type, pos, vel, count, spread).

world:particle("my_mod:spark", pos, cl.vec(0, 0.1, 0), 20, 0.3)

Called on the server, everyone nearby sees them. Called on the client, only that player does.

Decals

world:decal("my_mod:textures/decal/scorch.png", hit_pos, hit_normal, 2.0)

The texture lies on the blocks it touches and fades after 30 seconds (the sixth argument is the lifetime in ticks).

A post effect

A post pass is a small shader in your assets. It receives the picture and returns a new colour:

// assets/my_mod/shaders/post/red.glsl
vec4 cl_post(vec2 uv) {
    vec4 c = cl_scene(uv);
    return vec4(mix(c.rgb, vec3(c.r, 0.0, 0.0), amount), 1.0);
}
local amount = 0
local red = cl.render.post_pass{
  id = "red", shader = "my_mod:shaders/post/red.glsl",
  uniforms = function() return { amount = amount } end,   -- every frame
}

Change amount from anywhere and the screen follows. red:remove() takes the effect away.

Fog and the camera

cl.on("render.fog", function(ev)
  ev.render_distance_end = 24                  -- blocks
  ev.red, ev.green, ev.blue = 0.2, 0.2, 0.25
end)

cl.camera.set_effects{ fov_mult = 0.9, roll = 5, vignette = 0.5 }

Camera effects follow the player’s accessibility settings, and camera shake only happens if the player turned Mod Camera Shake on.

Try it

Make water murkier: under water, end the fog at half its usual distance and tint it green.

Show a solution
cl.on("render.fog", function(ev)
  if ev.fog_type == 1 then   -- 1 = water
    ev.environmental_end = ev.environmental_end / 2
    ev.red, ev.green, ev.blue = 0.1, 0.35, 0.15
  end
end)

Recap: cl.render.particle_type + level:particle for particles, level:decal for marks on blocks, cl.render.post_pass for screen effects, render.fog for fog, cl.camera.set_effects for the camera.