def _set_terrain_shader(self, engine, attribute_tex):
        """
        Set a shader on the terrain. The ShaderTerrainMesh only works with an applied shader. You can use the shaders
        used here in your own application.

        Note: you have to make sure you modified the terrain_effect.yaml and vert.glsl/frag.glsl together, as they are
        made for different render pipeline. We expect the same terrain generated from different pipelines.
        """
        if not self._terrain_shader_set:
            if engine.use_render_pipeline:
                engine.render_pipeline.reload_shaders()
                terrain_effect = AssetLoader.file_path("../shaders", "terrain_effect.yaml")
                engine.render_pipeline.set_effect(self._mesh_terrain, terrain_effect, {}, 100)

            # # height
            self._mesh_terrain.set_shader_input("camera", self.engine.camera)
            self._mesh_terrain.set_shader_input("height_scale", self._height_scale)

            # grass
            self._mesh_terrain.set_shader_input("grass_tex", self.grass_tex)
            self._mesh_terrain.set_shader_input("grass_normal", self.grass_normal)
            self._mesh_terrain.set_shader_input("grass_rough", self.grass_rough)
            self._mesh_terrain.set_shader_input("grass_tex_ratio", self.grass_tex_ratio)
            #
            # # side
            # self._mesh_terrain.set_shader_input("side_tex", self.side_tex)
            # self._mesh_terrain.set_shader_input("side_normal", self.side_normal)

            # rock
            self._mesh_terrain.set_shader_input("rock_tex", self.rock_tex)
            self._mesh_terrain.set_shader_input("rock_normal", self.rock_normal)
            self._mesh_terrain.set_shader_input("rock_rough", self.rock_rough)
            self._mesh_terrain.set_shader_input("rock_tex_ratio", self.rock_tex_ratio)

            # rock 2
            self._mesh_terrain.set_shader_input("rock_tex_2", self.rock_tex_2)
            self._mesh_terrain.set_shader_input("rock_normal_2", self.rock_normal_2)
            self._mesh_terrain.set_shader_input("rock_rough_2", self.rock_rough_2)
            self._mesh_terrain.set_shader_input("rock_tex_ratio_2", self.rock_tex_ratio_2)

            # road
            self._mesh_terrain.set_shader_input("road_tex", self.road_texture)
            self._mesh_terrain.set_shader_input("road_tex_ratio", self.road_tex_ratio)
            self._mesh_terrain.set_shader_input("road_normal", self.road_texture_normal)
            self._mesh_terrain.set_shader_input("road_rough", self.road_texture_rough)

            # crosswalk
            self._mesh_terrain.set_shader_input("crosswalk_tex", self.crosswalk_tex)
            self._terrain_shader_set = True

            # semantic color input
            def to_float(color):
                return Vec3(*[i / 255 for i in color])

            self._mesh_terrain.set_shader_inputs(
                crosswalk_semantics=to_float(Semantics.CROSSWALK.color),
                lane_line_semantics=to_float(Semantics.LANE_LINE.color),
                road_semantics=to_float(Semantics.ROAD.color),
                ground_semantics=to_float(Semantics.TERRAIN.color)
            )
        self._mesh_terrain.set_shader_input("attribute_tex", attribute_tex)

        Set a shader on the terrain. The ShaderTerrainMesh only works with an applied shader. You can use the shaders
        used here in your own application.

        Note: you have to make sure you modified the terrain_effect.yaml and vert.glsl/frag.glsl together, as they are
        made for different render pipeline. We expect the same terrain generated from different pipelines.
        
metadrive/engine/core/terrain.py