Merge branch 'LoA-c.Bertrand-master-patch-24626' into 'master'
BERTRAND Loic authored
Added source code link

See merge request !1
a19a2974

Computer graphics project (TELECOM Nancy 2020-2021)

GIF capture of a shader christmasy scenery: a christmas tree, a snowman and two colored gifts.

  • Spheres based on Bruno Levy's work
  • Boxes based on Scratchapixel 2.0
  • Combination of the two and artwork by Loïc Bertrand
  • Language: GLSL, compatible with shadertoy.com
  • To see the code, click here. You can then click on the "Copy file contents" button on the top right corner and paste it in shadertoy.com to see it in action.

Creation strategy

  • I started with a shader example by Bruno Levy, demonstrating how to render spheres.
  • Then I build the snowman and added falling snow. To simulate randomness, I used an arbitrary height for each snowflake, related to their position (x * y * 2.0). To make them fall in a loop, I used the iTime variable combined with a floatModulo function that I created. This like a modulo function, but for float values.
float floatModulo(in float value, in float upperBound) {
    if (value < upperBound)
        return value;
    float n = floor(value / upperBound);
    return value - n * upperBound;
}

// Snowflakes
for (float x = -1.5; x <= 0.5; x += 0.5) {
    for (float y = -0.75; y <= 0.75; y += 0.5) {
        float height = -floatModulo(iTime + x * y * 2.0, 2.) + 1.0;
        spheres[sphereIndex++] = SphereObject(
            Sphere(vec3(x, y, height), 0.01),
            diffuse(white));
    }
}
  • For the boxes, I used the intersection function of a ray to a box provided by Scratchapixel 2.0. So I refactored the variable names a bit and added Box related structs and the intersection function. I defined a box as two points: min and max.
struct Box { vec3 min; vec3 max; };
struct BoxObject { Box box; Material material; };
  • I created a helper function to build boxes by providing its center point, width, height, depth. This greatly simplified the creation of the two gifts and the tree.
Box BoxWHD(in vec3 center, in float half_w, in float half_h, in float half_d) {
    vec3 offset = vec3(half_d, half_w, half_h);
    vec3 min = center - offset;
    vec3 max = center + offset;
    return Box(min, max);
}

Possible improvements

  • This shader runs a little slowly and could be improved by storing the objects instead of recreating them for each animation frame.
  • For the surface shadow boxes, I use the same implementation as for the spheres: casting a ray to the center of the box and taking the normal of this ray to determine the color of the box surface. This works fine but this is not realistic.
  • The boxes could maybe be rotated by rotating the ray we cast to them.
  • We could add reflection to certain spheres and also cones, but a polymorphism desing would help. Unfortunately, GLSL doesn't have polmorphism capabilities that I know of.

GIF capture of a shader christmasy scenery: a christmas tree, a snowman and two colored gifts.