Color gradient scene background

I just notice there is a small glitch on the gradient, as you can see there is a line slighly visibe on the middle of the screen:

@Epihaius Do you know why ?

Ah, that might indeed affect any colors rendered, although I have to admit that I have never used this RenderAttrib, so I canā€™t speak from experience.

From what I can tell, thatā€™s just the result of the color changing from a gradient to a solid color at that line. No idea what I could do to make this look different, though, sorry.

EDIT:
At second thought, it might help to make the colors of the edges at the very top and bottom of the model customizable as well. Then you could avoid having solid color areas adjacent to the gradient and replace them with additional gradients that could make such lines with an apparent ā€œtightnessā€ disappear.

To that end, I have edited the second code sample to include optional top_color and bottom_color parameters for the create_gradient function. It is now up to you to experiment with all 4 colors to see what looks best. Thatā€™s really all I can do, I think.

Hope it will work the way you want it now.

Thank you @Epihaius ! Unfortunately it is not fixing the issue :confused: Yet the overall result is really satisfactory ! I have integrated your latest version :slight_smile: It will be part of my open-source project Jiminy. I wonā€™t forget to give you credit for it.

Ah, thatā€™s a pity!

Thank you, that is great to hear; your project looks very interesting :slight_smile: !

Actually, now that I look at the screenshots of the associated MeshCat project, it seems the gradient there does seem to somewhat ā€œstickā€ to the direction of the camera. Could it be that this is what you truly wanted after all, as was already suggested by Thaumaturge? My apologies in that case; your mentioning of sky boxes made me think that you wanted something like a true 3D-background/environment that you could more or less look around in.

Perhaps the following could be more in line with what you were expecting, then (basically a simple quad that is attached to the camera and changes size according to the lens properties):

from panda3d.core import *
from direct.showbase.ShowBase import ShowBase
import array


def create_gradient(sky_color, ground_color):

    vertex_format = GeomVertexFormat()
    array_format = GeomVertexArrayFormat()
    array_format.add_column(InternalName.get_vertex(), 3,
        GeomEnums.NT_float32, GeomEnums.C_point)
    vertex_format.add_array(array_format)
    array_format = GeomVertexArrayFormat()
    array_format.add_column(InternalName.make("color"), 4,
        GeomEnums.NT_uint8, GeomEnums.C_color)
    vertex_format.add_array(array_format)
    vertex_format = GeomVertexFormat.register_format(vertex_format)

    vertex_data = GeomVertexData("quad_data", vertex_format, GeomEnums.UH_static)
    vertex_data.unclean_set_num_rows(4)
    # create a simple quad
    values = array.array("f", [
        -.5, 0., -.5,
        .5, 0., -.5,
        -.5, 0., .5,
        .5, 0., .5
    ])
    pos_array = vertex_data.modify_array(0)
    memview = memoryview(pos_array).cast("B").cast("f")
    memview[:] = values
    color1 = tuple(int(round(c * 255)) for c in ground_color)
    color2 = tuple(int(round(c * 255)) for c in sky_color)
    values = array.array("B", color1 * 2 + color2 * 2)
    color_array = vertex_data.modify_array(1)
    memview = memoryview(color_array).cast("B")
    memview[:] = values

    tris_prim = GeomTriangles(GeomEnums.UH_static)
    indices = array.array("H", [
        0, 1, 2,
        1, 3, 2
    ])
    tris_array = tris_prim.modify_vertices()
    tris_array.unclean_set_num_rows(6)
    memview = memoryview(tris_array).cast("B").cast("H")
    memview[:] = indices

    geom = Geom(vertex_data)
    geom.add_primitive(tris_prim)
    node = GeomNode("quad")
    node.add_geom(geom)
    quad = NodePath(node)
    quad.set_light_off()
    quad.set_bin("background", 0)
    quad.set_depth_write(False)
    quad.set_depth_test(False)

    return quad


class MyApp(ShowBase):

    def __init__(self):

        ShowBase.__init__(self)

        # set up a light source
        p_light = PointLight("point_light")
        p_light.set_color((1., 1., 1., 1.))
        self.light = self.camera.attach_new_node(p_light)
        self.light.set_pos(5., -100., 7.)
        self.render.set_light(self.light)

        # add a model as visual reference
        smiley = self.loader.load_model("smiley")
        smiley.reparent_to(self.render)
        smiley.set_y(10.)

        # define the colors at the top ("sky") and bottom ("ground") of the
        # background gradient
        sky_color = (0, 0, 1., 1.)
        ground_color = (0, 1., 0, 1.)
        self.background_gradient = create_gradient(sky_color, ground_color)
        self.background_gradient.reparent_to(self.camera)

        # adjust the position and size of the background model to the properties
        # of the lens whenever these change
        self.camLens.change_event = "lens-event"
        self.accept("lens-event", self.__handle_lens_event)

    def __handle_lens_event(self, lens):

        y = lens.focal_length
        f = (lens.near + 1.) / y if y < lens.near + 1. else 1.
        self.background_gradient.set_y(y * f)
        sx, sz = lens.film_size
        self.background_gradient.set_scale(sx * f, 1., sz * f)


app = MyApp()
app.run()

Note that this may look strange when the ā€œrollā€ angle of the camera changesā€“but since you use a custom camera controller, this might not be a problem. If it is, let me know.

Either way, Iā€™m glad I was able to help :slight_smile: !

Actually, now that I look at the screenshots of the associated MeshCat 1 project, it seems the gradient there does seem to somewhat ā€œstickā€ to the direction of the camera. Could it be that this is what you truly wanted after all, as was already suggested by Thaumaturge?

Indeed it does not stick to the direction of the camera in Meshcat and I find it very weird. It is not an issue in most cases though, since the controls do not allow for tilting / roll the camera.

My apologies in that case; your mentioning of sky boxes made me think that you wanted something like a true 3D-background/environment that you could more or less look around in.

Yes it mentioned sky boxes because I find it more nature and less confusing for the user, otherwise it is mostly meaningless, it is just a little more beautiful that a solid colorā€¦

Note that this may look strange when the ā€œrollā€ angle of the camera changesā€“but since you use a custom camera controller, this might not be a problem. If it is, let me know.

Thank you but I will stick to the previous version, since I find it more suitable. I donā€™t want to completely mimic Meshcat, but actually offer something even better. And I think your sky box is going in the right direction :+1:

Thatā€™s great, and thank you!
The best of luck with your project :slight_smile: !