Need help with shader generator

Hello, I’m having some problem using the shader generator. The fact is that I simply can’t get it working.

Here is my code:

from direct.showbase.ShowBase import ShowBase
from direct.filter.CommonFilters import CommonFilters
from panda3d.core import PointLight, Shader, CollisionNode, LVecBase4, NodePath, PandaNode, DirectionalLight, AmbientLight, Vec3, BoundingVolume



class Test(ShowBase):
    def __init__(self):


        ShowBase.__init__(self)

        render.setShaderAuto()

        self.model = loader.loadModel('resources/scenes/desert.bam')
        #HIDE THE COLLIDER
        for coll in self.model.findAllMatches('**/gnd_coll'):
            if isinstance(coll.node(),CollisionNode):
                coll.hide();

        
        
        #LOAD MODEL
        self.model.find('**/gnd').setShaderInput('modelColor',Vec3(0.46,0.39,0.34))
        self.model.reparentTo(render)


        #SUN
        self.dlight = DirectionalLight('s')
        self.dlight.setColorTemperature(6000)
        self.dlight.setColor((1,1,1,1))
        self.dlight.set_active(True)
        self.dlight.get_lens().setNearFar(1,1000)
        self.dlight.get_lens().set_film_size(1000,1000)
        self.dlight.show_frustum()
        self.dlight.setShadowCaster(True,4096,4096)
        self.dlnp = render.attachNewNode(self.dlight)
        self.dlnp.setPos(10,10,10)
        self.dlnp.lookAt(0,0,0)
        render.setLight(self.dlnp)

        #AMBIENT LIGHT
        self.alight = AmbientLight('self.alight')
        acol = .15
        self.alight.setColor((acol,acol,acol * 1.2,acol))
        self.alnp = render.attachNewNode(self.alight)
        render.setLight(self.alnp)


        #INK
        filters = CommonFilters(base.win,base.cam)
        filters.setCartoonInk()


        #DYNAMIC FRUSTUM ADJUSTMENT
        #took from here: https://discourse.panda3d.org/t/sample-using-directional-lights-shadows-effectively/24424
        base.taskMgr.add(self.adjust_frustum,'adjust_frustum')

        
    def adjust_frustum(self,task):
        # This method is much faster, but not nearly as tightly fitting.  May (or
        # may not) work better with "bounds-type best" in Config.prc.
        #
        # It will automatically try to reduce the shadow frustum size in order not
        # to shadow objects that are out of view.  Additionally, it will disable
        # the shadow camera if the scene bounds are completely out of view of the
        # shadow camera.

        # Get Panda's precomputed scene bounds.
        scene_bounds = self.model.get_bounds()
        scene_bounds.xform(self.model.get_mat(self.dlnp))

        # Also transform the bounding volume of the camera frustum to light space.
        lens_bounds = base.camLens.make_bounds()
        lens_bounds.xform(base.camera.get_mat(self.dlnp))

        # Does the lens bounds contain the scene bounds?
        intersection = lens_bounds.contains(scene_bounds)

        sun = self.dlnp.node()

        if not intersection:
            # No; deactivate the shadow camera.
            sun.set_active(False)
            return

        sun.set_active(True)
        bmin = scene_bounds.get_min()
        bmax = scene_bounds.get_max()

        if intersection & BoundingVolume.IF_all:
            # Completely contains the world volume; no adjustment necessary.
            pass
        else:
            # Adjust all dimensions to tighten around the view frustum bounds,
            # except for the near distance, because objects that are out of view
            # in that direction may still cast shadows.
            lmin = lens_bounds.get_min()
            lmax = lens_bounds.get_max()

            bmin[0] = min(max(bmin[0], lmin[0]), lmax[0])
            bmin[1] = min(bmin[1], lmax[1])
            bmin[2] = min(max(bmin[2], lmin[2]), lmax[2])

        lens = sun.get_lens()
        lens.set_film_offset((bmin.xz + bmax.xz) * 0.5)
        lens.set_film_size(bmax.xz - bmin.xz)
        lens.set_near_far(bmin.y, bmax.y)

        return task.cont

test = Test()
test.run()

where the model ‘desert.bam’ is compiled with this command(Note: blender version is 3.5.1)

blend2bam --invisible-collisions-collection COLLIDERS --textures embed SOURCES/MODELS/BLENDER35_MODELS/desert.blend resources/scenes/desert.bam

here is a screenshot of the result: as you can see, it seems that only the ambient light is used.
I would like to have also the directional light working + shadows:

just for completeness, here is a screenshot of the shader in blender:

Any help would be greatly appreciated. Thank you :slight_smile:

The problem is that the standard shader generator does not use material for PBR lighting.

Hello, thanks for your reply. So, how do you suggest to proceed? I have already tried to load the texture in panda and apply it: it is displayed but not lighted with the directional light…

I think first you need to export a test model for the community to study. Only then can something purposeful be done.

OK, right away! Thanks for your support!

Here is the model:

I don’t see any problems with the lighting because you are incorrectly frustum adjustment for the light source.

from panda3d.core import DirectionalLight, NodePath, loadPrcFileData
from direct.showbase.ShowBase import ShowBase

class MyApp(ShowBase):

    def __init__(self):
        ShowBase.__init__(self)

        dlight = DirectionalLight('dlight')
        dlight.set_shadow_caster(True, 4096, 4096)
        dlight.show_frustum()
        lens = dlight.get_lens()
        lens.set_film_size(128, 128)

        dlnp = NodePath(dlight)
        dlnp.reparent_to(render)
        dlnp.set_pos(-100, -350, 150)
        dlnp.set_hpr(0, -30, 0)
        render.set_light(dlnp)

        test = loader.load_model("desert.bam")
        test.reparent_to(render)

        render.set_shader_auto()

app = MyApp()
app.run()

Have your tried to assign a texture to the ground?

you can get it using model.find(‘**/gnd’)

from panda3d.core import DirectionalLight, NodePath, loadPrcFileData
from direct.showbase.ShowBase import ShowBase

class MyApp(ShowBase):

    def __init__(self):
        ShowBase.__init__(self)

        dlight = DirectionalLight('dlight')
        dlight.set_shadow_caster(True, 4096, 4096)
        dlight.show_frustum()
        lens = dlight.get_lens()
        lens.set_film_size(128, 128)

        dlnp = NodePath(dlight)
        dlnp.reparent_to(render)
        dlnp.set_pos(-100, -350, 150)
        dlnp.set_hpr(0, -30, 0)
        render.set_light(dlnp)

        test = loader.load_model("desert.bam")
        test.reparent_to(render)

        tex = loader.loadTexture('grass.png')

        ground = test.find('**/gnd')
        ground.set_texture(tex, 1)

        render.set_shader_auto()

app = MyApp()
app.run()

There are no problems, except for the absence of UV coordinates in the model. Have you created texture coordinates in blender for the model? Have you completed unwrap with the required scaling?

Hmm, I decided to check your code and found that it is functional, the truncation adjustment is configured. Shadows are present, lighting too. This is what your scene looks like on my PC.

Hello, thanks again for your help. The fact is that I’m still getting issues with textures :-/

Have you eliminated the lack of UV mapping?