Skip to content

Particles, post effects and the camera

Lesson 9.6

Your mod can paint on the world: sparks, scorch marks, a red haze over the screen, thick fog, a tilted camera. This lesson shows each tool once; the guides have every option: Particles and Decals, Post-processing, Fog, Sky and Camera, Menus and Themes.

Particles

#include <clight.hpp>

clight::on<clight::ev::LifecycleRegister>([](cl_ev_lifecycle&) {
    cl_particle_desc d = CL_PARTICLE_DESC_INIT;
    d.texture = CL_STR("my_mod:textures/particle/spark.png");
    d.frames = 4;
    d.columns = 2;
    d.size = 0.12f;
    d.size_end = 0.02f;
    d.gravity = 0.02f;
    d.color = 0xFFFFD080u;
    d.emissive = true;
    d.additive = true;
    d.fallback = CL_STR("minecraft:flame");
    clight::render::particle_type("spark", &d);
}).detach();

Spawning is a method of the level:

cl_particle_spawn s = CL_PARTICLE_SPAWN_INIT;
s.pos = pos;
s.vel = {0, 0.1, 0};
s.count = 20;
s.spread = {0.3, 0.3, 0.3};
level.particle("my_mod:spark", &s);

Decals

cl_decal_desc d = CL_DECAL_DESC_INIT;
d.texture = CL_STR("my_mod:textures/decal/scorch.png");
d.pos = hit_pos;
d.normal = hit_normal;
d.size = 2.0f;
level.decal(&d);

A post effect

The shader (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);
}
static clight::PostPass red;
static float amount = 0.0f;

clight::on<clight::ev::LifecycleClientSetup>([](cl_ev_lifecycle&) {
    cl_post_pass_desc d = CL_POST_PASS_DESC_INIT;
    d.id = CL_STR("red");
    d.shader = CL_STR("my_mod:shaders/post/red.glsl");
    d.uniforms = CL_STR("amount");
    if (auto p = clight::render::post_pass(&d)) red = *p;
}).detach();

clight::on<clight::ev::RenderFrame>([](cl_ev_render_frame&) {
    if (red) red.set_uniform("amount", amount);
}).detach();

Fog and the camera

clight::on<clight::ev::RenderFog>([](cl_ev_render_fog& e) {
    e.render_distance_end = 24.0f;
    e.red = 0.2f, e.green = 0.2f, e.blue = 0.25f;
}).detach();

cl_camera_effects fx = CL_CAMERA_EFFECTS_INIT;
fx.fov_mult = 0.9f;
fx.roll = 5.0f;
fx.vignette = 0.5f;
clight::camera::set_effects(&fx);

The camera effects follow the player’s accessibility settings; shake needs the player’s Mod Camera Shake option.

Try it

Make water murkier: under water (fog_type == 1), halve environmental_end and tint the fog green.

Show a solution
clight::on<clight::ev::RenderFog>([](cl_ev_render_fog& e) {
    if (e.fog_type != 1) return;
    e.environmental_end *= 0.5f;
    e.red = 0.1f, e.green = 0.35f, e.blue = 0.15f;
}).detach();

Recap: clight::render::particle_type and level.particle for particles, level.decal for marks, clight::render::post_pass plus set_uniform for screen effects, ev::RenderFog for fog, clight::camera::set_effects for the camera.