def _internal_set_effect(self, nodepath, effect_src, options=None, sort=30):
        """ Sets an effect to the given object, using the specified options.
        Check out the effect documentation for more information about possible
        options and configurations. The object should be a nodepath, and the
        effect will be applied to that nodepath and all nodepaths below whose
        current effect sort is less than the new effect sort (passed by the
        sort parameter). """
        effect = Effect.load(effect_src, options)
        if effect is None:
            return self.error("Could not apply effect")

        for i, stage in enumerate(("gbuffer", "shadow", "voxelize", "envmap", "forward")):
            if not effect.get_option("render_" + stage):
                nodepath.hide(self.tag_mgr.get_mask(stage))
            else:
                shader = effect.get_shader_obj(stage)
                if stage == "gbuffer":
                    nodepath.set_shader(shader, 25)
                else:
                    self.tag_mgr.apply_state(stage, nodepath, shader, str(effect.effect_id), 25 + 10 * i + sort)
                nodepath.show_through(self.tag_mgr.get_mask(stage))

        if effect.get_option("render_gbuffer") and effect.get_option("render_forward"):
            self.error(
                "You cannot render an object forward and deferred at the "
                "same time! Either use render_gbuffer or use render_forward, "
                "but not both."
            )
 Sets an effect to the given object, using the specified options.
        Check out the effect documentation for more information about possible
        options and configurations. The object should be a nodepath, and the
        effect will be applied to that nodepath and all nodepaths below whose
        current effect sort is less than the new effect sort (passed by the
        sort parameter). 
metadrive/render_pipeline/rpcore/render_pipeline.py