class Demo(ShowBase): def __init__(self): from rpcore import RenderPipeline, PointLight from rpcore.util.movement_controller import MovementController self.render_pipeline = RenderPipeline() self.render_pipeline.create(self) self.render_pipeline.daytime_mgr.time = '08:00' self.point_light = PointLight() self.point_light.set_color(1, 1, 0.9) self.point_light.set_energy(10) self.point_light.set_pos(0, 5, 2) self.point_light.set_radius(20) self.render_pipeline.add_light(self.point_light) self.ruby = Actor('ruby_mesh.gltf', {'idle': 'ruby_anim.egg'}) self.ruby.reparent_to(self.render) self.ruby.set_h(180) self.ruby.loop('idle') self.render_pipeline.set_effect(self.ruby, 'hardware_skinning.yaml', options={}, sort=25) sattrib = self.ruby.get_attrib(ShaderAttrib) sattrib = sattrib.set_flag(ShaderAttrib.F_hardware_skinning, True) self.ruby.set_attrib(sattrib) self.controller = MovementController(self) self.controller.set_initial_position_hpr( Vec3(0, 5, 1.75), # position Vec3(180, -10, 0)) # hpr self.controller.setup()
class Application(ShowBase): def __init__(self): # Setup window size, title and so on load_prc_file_data("", """ win-size 1600 900 window-title Render Pipeline - Material Sample """) self.render_pipeline = RenderPipeline() self.render_pipeline.create(self) # Set time of day self.render_pipeline.daytime_mgr.time = "19:17" # Load the scene model = loader.load_model("scene/TestScene.bam") model.reparent_to(render) self.render_pipeline.prepare_scene(model) # Enable parallax mapping on the floor self.render_pipeline.set_effect(model.find("**/FloorPlane"), "effects/default.yaml", {"parallax_mapping": True}, 100) # Initialize movement controller self.controller = MovementController(self) self.controller.set_initial_position_hpr( Vec3(-17.2912578583, -13.290019989, 6.88211250305), Vec3(-39.7285499573, -14.6770210266, 0.0)) self.controller.setup()
class Application(ShowBase): """ Main Testing Showbase """ def __init__(self): # Setup window size, title and so on load_prc_file_data( "", """ win-size 1600 900 window-title Render Pipeline - Material blending example """) # ------ Begin of render pipeline code ------ # Insert the pipeline path to the system path, this is required to be # able to import the pipeline classes pipeline_path = "../../" # Just a special case for my development setup, so I don't accidentally # commit a wrong path. You can remove this in your own programs. if not os.path.isfile(os.path.join(pipeline_path, "setup.py")): pipeline_path = "../../RenderPipeline/" sys.path.insert(0, pipeline_path) from rpcore import RenderPipeline, SpotLight self.render_pipeline = RenderPipeline() self.render_pipeline.create(self) # This is a helper class for better camera movement - its not really # a rendering element, but it included for convenience from rpcore.util.movement_controller import MovementController # ------ End of render pipeline code, thats it! ------ # Set time of day self.render_pipeline.daytime_mgr.time = "6:43" # Load the scene model = loader.loadModel("scene/Scene.bam") model.reparent_to(render) # Set the material blending effect on the terrain terrain = model.find("**/Terrain") self.render_pipeline.set_effect( terrain, "effects/material_blend4.yaml", { "parallax_mapping": False, # Not supported "alpha_testing": False, "normal_mapping": False, # The effect does its own normal mapping }, 100) # Configure the effect terrain.set_shader_input("detail_scale_factor", 4.0) # Detailmap blending factors. # Blending is calculated as (detailmap + <add>) ^ <pow> # The base map has no blending since it is used as a filling material # and blending the base map would cause spots with no material at all. terrain.set_shader_input("material_0_pow", 10.0) terrain.set_shader_input("material_0_add", 0.5) terrain.set_shader_input("material_1_pow", 10.0) terrain.set_shader_input("material_1_add", 0.5) terrain.set_shader_input("material_2_pow", 10.0) terrain.set_shader_input("material_2_add", 0.5) # Init movement controller self.controller = MovementController(self) self.controller.set_initial_position(Vec3(-15.2, -9.0, 11.8), Vec3(-12.3, -7.0, 9.7)) self.controller.setup()
class Application(ShowBase): """ Main Testing Showbase """ def __init__(self): # Setup window size, title and so on load_prc_file_data("", """ win-size 1600 900 window-title Render Pipeline - Material blending example """) # ------ Begin of render pipeline code ------ # Insert the pipeline path to the system path, this is required to be # able to import the pipeline classes pipeline_path = "../../" # Just a special case for my development setup, so I don't accidentally # commit a wrong path. You can remove this in your own programs. if not os.path.isfile(os.path.join(pipeline_path, "setup.py")): pipeline_path = "../../RenderPipeline/" sys.path.insert(0, pipeline_path) from rpcore import RenderPipeline, SpotLight self.render_pipeline = RenderPipeline() self.render_pipeline.create(self) # This is a helper class for better camera movement - its not really # a rendering element, but it included for convenience from rpcore.util.movement_controller import MovementController # ------ End of render pipeline code, thats it! ------ # Set time of day self.render_pipeline.daytime_mgr.time = "6:43" # Load the scene model = loader.loadModel("scene/Scene.bam") model.reparent_to(render) # Set the material blending effect on the terrain terrain = model.find("**/Terrain") self.render_pipeline.set_effect(terrain, "effects/material_blend4.yaml", { "parallax_mapping": False, # Not supported "alpha_testing": False, "normal_mapping": False, # The effect does its own normal mapping }, 100) # Configure the effect terrain.set_shader_input("detail_scale_factor", 4.0) # Detailmap blending factors. # Blending is calculated as (detailmap + <add>) ^ <pow> # The base map has no blending since it is used as a filling material # and blending the base map would cause spots with no material at all. terrain.set_shader_input("material_0_pow", 10.0) terrain.set_shader_input("material_0_add", 0.5) terrain.set_shader_input("material_1_pow", 10.0) terrain.set_shader_input("material_1_add", 0.5) terrain.set_shader_input("material_2_pow", 10.0) terrain.set_shader_input("material_2_add", 0.5) # Init movement controller self.controller = MovementController(self) self.controller.set_initial_position(Vec3(-15.2, -9.0, 11.8), Vec3(-12.3, -7.0, 9.7)) self.controller.setup()
class World(ShowBase): def __init__(self): # Setup window size, title and so on load_prc_file_data("", """ win-size 1600 900 window-title Render Pipeline - Roaming Ralph Demo """) # ------ Begin of render pipeline code ------ # Insert the pipeline path to the system path, this is required to be # able to import the pipeline classes pipeline_path = "../../" # Just a special case for my development setup, so I don't accidentally # commit a wrong path. You can remove this in your own programs. if not os.path.isfile(os.path.join(pipeline_path, "setup.py")): pipeline_path = "../../RenderPipeline/" sys.path.insert(0, pipeline_path) from rpcore import RenderPipeline, SpotLight self.render_pipeline = RenderPipeline() self.render_pipeline.create(self) # ------ End of render pipeline code, thats it! ------ # Set time of day self.render_pipeline.daytime_mgr.time = "7:40" # Use a special effect for rendering the scene, this is because the # roaming ralph model has no normals or valid materials self.render_pipeline.set_effect(render, "scene-effect.yaml", {}, sort=250) self.keyMap = {"left":0, "right":0, "forward":0, "backward":0, "cam-left":0, "cam-right":0} self.speed = 1.0 base.win.setClearColor(Vec4(0,0,0,1)) # Post the instructions self.inst1 = addInstructions(0.95, "[ESC] Quit") self.inst4 = addInstructions(0.90, "[W] Run Ralph Forward") self.inst4 = addInstructions(0.85, "[S] Run Ralph Backward") self.inst2 = addInstructions(0.80, "[A] Rotate Ralph Left") self.inst3 = addInstructions(0.75, "[D] Rotate Ralph Right") self.inst6 = addInstructions(0.70, "[Left Arrow] Rotate Camera Left") self.inst7 = addInstructions(0.65, "[Right Arrow] Rotate Camera Right") # Set up the environment # # This environment model contains collision meshes. If you look # in the egg file, you will see the following: # # <Collide> { Polyset keep descend } # # This tag causes the following mesh to be converted to a collision # mesh -- a mesh which is optimized for collision, not rendering. # It also keeps the original mesh, so there are now two copies --- # one optimized for rendering, one for collisions. self.environ = loader.loadModel("resources/world") self.environ.reparentTo(render) self.environ.setPos(0,0,0) # Remove wall nodes self.environ.find("**/wall").remove_node() # Create the main character, Ralph self.ralph = Actor("resources/ralph", {"run":"resources/ralph-run", "walk":"resources/ralph-walk"}) self.ralph.reparentTo(render) self.ralph.setScale(.2) self.ralph.setPos(Vec3(-110.9, 29.4, 1.8)) # Create a floater object. We use the "floater" as a temporary # variable in a variety of calculations. self.floater = NodePath(PandaNode("floater")) self.floater.reparentTo(render) # Accept the control keys for movement and rotation self.accept("escape", sys.exit) self.accept("a", self.setKey, ["left",1]) self.accept("d", self.setKey, ["right",1]) self.accept("w", self.setKey, ["forward",1]) self.accept("s", self.setKey, ["backward",1]) self.accept("arrow_left", self.setKey, ["cam-left",1]) self.accept("arrow_right", self.setKey, ["cam-right",1]) self.accept("a-up", self.setKey, ["left",0]) self.accept("d-up", self.setKey, ["right",0]) self.accept("w-up", self.setKey, ["forward",0]) self.accept("s-up", self.setKey, ["backward",0]) self.accept("arrow_left-up", self.setKey, ["cam-left",0]) self.accept("arrow_right-up", self.setKey, ["cam-right",0]) self.accept("=", self.adjustSpeed, [0.25]) self.accept("+", self.adjustSpeed, [0.25]) self.accept("-", self.adjustSpeed, [-0.25]) taskMgr.add(self.move,"moveTask") # Game state variables self.isMoving = False # Set up the camera base.disableMouse() base.camera.setPos(self.ralph.getX() + 10,self.ralph.getY() + 10, 2) base.camLens.setFov(80) # We will detect the height of the terrain by creating a collision # ray and casting it downward toward the terrain. One ray will # start above ralph's head, and the other will start above the camera. # A ray may hit the terrain, or it may hit a rock or a tree. If it # hits the terrain, we can detect the height. If it hits anything # else, we rule that the move is illegal. self.cTrav = CollisionTraverser() self.ralphGroundRay = CollisionRay() self.ralphGroundRay.setOrigin(0,0,1000) self.ralphGroundRay.setDirection(0,0,-1) self.ralphGroundCol = CollisionNode('ralphRay') self.ralphGroundCol.addSolid(self.ralphGroundRay) self.ralphGroundCol.setFromCollideMask(BitMask32.bit(0)) self.ralphGroundCol.setIntoCollideMask(BitMask32.allOff()) self.ralphGroundColNp = self.ralph.attachNewNode(self.ralphGroundCol) self.ralphGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.ralphGroundColNp, self.ralphGroundHandler) self.camGroundRay = CollisionRay() self.camGroundRay.setOrigin(0,0,1000) self.camGroundRay.setDirection(0,0,-1) self.camGroundCol = CollisionNode('camRay') self.camGroundCol.addSolid(self.camGroundRay) self.camGroundCol.setFromCollideMask(BitMask32.bit(0)) self.camGroundCol.setIntoCollideMask(BitMask32.allOff()) self.camGroundColNp = base.camera.attachNewNode(self.camGroundCol) self.camGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler) # Uncomment this line to see the collision rays #self.ralphGroundColNp.show() #self.camGroundColNp.show() # Uncomment this line to show a visual representation of the # collisions occuring #self.cTrav.showCollisions(render) # Create some lighting ambientLight = AmbientLight("ambientLight") ambientLight.setColor(Vec4(.3, .3, .3, 1)) directionalLight = DirectionalLight("directionalLight") directionalLight.setDirection(Vec3(-5, -5, -5)) directionalLight.setColor(Vec4(1, 1, 1, 1)) directionalLight.setSpecularColor(Vec4(1, 1, 1, 1)) render.setLight(render.attachNewNode(ambientLight)) render.setLight(render.attachNewNode(directionalLight)) #Records the state of the arrow keys def setKey(self, key, value): self.keyMap[key] = value # Adjust movement speed def adjustSpeed(self, delta): newSpeed = self.speed + delta if 0 <= newSpeed <= 3: self.speed = newSpeed # Accepts arrow keys to move either the player or the menu cursor, # Also deals with grid checking and collision detection def move(self, task): # If the camera-left key is pressed, move camera left. # If the camera-right key is pressed, move camera right. base.camera.lookAt(self.ralph) if (self.keyMap["cam-left"]!=0): base.camera.setX(base.camera, +20 * globalClock.getDt()) if (self.keyMap["cam-right"]!=0): base.camera.setX(base.camera, -20 * globalClock.getDt()) # save ralph's initial position so that we can restore it, # in case he falls off the map or runs into something. startpos = self.ralph.getPos() # If a move-key is pressed, move ralph in the specified direction. if (self.keyMap["left"]!=0): self.ralph.setH(self.ralph.getH() + 300 * globalClock.getDt()) elif (self.keyMap["right"]!=0): self.ralph.setH(self.ralph.getH() - 300 * globalClock.getDt()) if (self.keyMap["forward"]!=0): self.ralph.setY(self.ralph, -25 * self.speed * globalClock.getDt()) elif (self.keyMap["backward"]!=0): self.ralph.setY(self.ralph, 25 * self.speed * globalClock.getDt()) # If ralph is moving, loop the run animation. # If he is standing still, stop the animation. if (self.keyMap["forward"]!=0) or (self.keyMap["backward"]!=0) or \ (self.keyMap["left"]!=0) or (self.keyMap["right"]!=0): if self.isMoving is False: self.ralph.loop("run") self.isMoving = True else: if self.isMoving: self.ralph.stop() self.ralph.pose("walk",5) self.isMoving = False # If the camera is too far from ralph, move it closer. # If the camera is too close to ralph, move it farther. camvec = self.ralph.getPos() - base.camera.getPos() camvec.setZ(0) camdist = camvec.length() camvec.normalize() if (camdist > 10.0): base.camera.setPos(base.camera.getPos() + camvec*(camdist-10)) camdist = 10.0 if (camdist < 5.0): base.camera.setPos(base.camera.getPos() - camvec*(5-camdist)) camdist = 5.0 # Now check for collisions. self.cTrav.traverse(render) # Adjust ralph's Z coordinate. If ralph's ray hit terrain, # update his Z. If it hit anything else, or didn't hit anything, put # him back where he was last frame. entries = [] for i in range(self.ralphGroundHandler.getNumEntries()): entry = self.ralphGroundHandler.getEntry(i) entries.append(entry) if (len(entries)>0) and (entries[0].getIntoNode().getName() == "terrain"): self.ralph.setZ(entries[0].getSurfacePoint(render).getZ()) else: self.ralph.setPos(startpos) # Keep the camera at one foot above the terrain, # or two feet above ralph, whichever is greater. entries = [] for i in range(self.camGroundHandler.getNumEntries()): entry = self.camGroundHandler.getEntry(i) entries.append(entry) if (len(entries)>0) and (entries[0].getIntoNode().getName() == "terrain"): base.camera.setZ(entries[0].getSurfacePoint(render).getZ()+1.0) if (base.camera.getZ() < self.ralph.getZ() + 2.0): base.camera.setZ(self.ralph.getZ() + 2.0) # The camera should look in ralph's direction, # but it should also try to stay horizontal, so look at # a floater which hovers above ralph's head. self.floater.setPos(self.ralph.getPos()) self.floater.setZ(self.ralph.getZ() + 2.0) base.camera.lookAt(self.floater) return task.cont
class Application(ShowBase): def __init__(self): # Setup window size, title and so on load_prc_file_data("", """ win-size 1600 900 window-title Render Pipeline by tobspr stm-max-chunk-count 2048 gl-coordinate-system default stm-max-views 20 notify-level-linmath error """) self.render_pipeline = RenderPipeline() self.render_pipeline.create(self) # Set time of day self.render_pipeline.daytime_mgr.time = "04:25" # Add some environment probe to provide better reflections probe = self.render_pipeline.add_environment_probe() probe.set_pos(0, 0, 600) probe.set_scale(8192 * 2, 8192 * 2, 1000) self.terrain_np = render.attach_new_node("terrain") heightfield = loader.loadTexture("resources/heightfield.png") for x in range(3): for y in range(3): terrain_node = ShaderTerrainMesh() terrain_node.heightfield = heightfield terrain_node.target_triangle_width = 6.0 terrain_node.generate() terrain_n = self.terrain_np.attach_new_node(terrain_node) terrain_n.set_scale(8192, 8192, 600) terrain_n.set_pos(-4096 + (x - 1) * 8192, -4096 + (y - 1) * 8192, 0) # Init movement controller self.controller = MovementController(self) self.controller.set_initial_position(Vec3(-12568, -11736, 697), Vec3(-12328, -11357, 679)) self.controller.setup() self.accept("r", self.reload_shaders) self.reload_shaders() def reload_shaders(self): self.render_pipeline.reload_shaders() # Set the terrain effect self.render_pipeline.set_effect(self.terrain_np, "effects/terrain-effect.yaml", {}, 100) base.accept("l", self.tour) def tour(self): control_points = ( (Vec3(2755.62084961, 6983.76708984, 506.219055176), Vec3(-179.09147644, 4.30751991272, 0.0)), (Vec3(3153.70068359, 5865.30859375, 560.780822754), Vec3(-225.239028931, 3.43641376495, 0.0)), (Vec3(2140.57080078, 5625.22753906, 598.345031738), Vec3(-196.022613525, 1.91196918488, 0.0)), (Vec3(2598.85961914, 3820.56958008, 627.692993164), Vec3(-272.410125732, 3.32752752304, 0.0)), (Vec3(1894.64526367, 3597.39257812, 647.455078125), Vec3(-198.227630615, 0.605303645134, 0.0)), (Vec3(1998.48425293, 1870.05358887, 639.38458252), Vec3(-121.682502747, 0.169744253159, 0.0)), (Vec3(3910.55297852, 2370.70922852, 518.356567383), Vec3(-130.42376709, 3.65418696404, -0.000583928485867)), (Vec3(4830.80761719, 1542.30749512, 501.019073486), Vec3(21.7212314606, 8.00974178314, 0.0)), (Vec3(4324.81982422, 2259.2409668, 713.095458984), Vec3(-19.1500263214, -1.68137300014, 0.0)), (Vec3(4584.38720703, 3417.75073242, 612.79510498), Vec3(-39.4675331116, -4.94804239273, 0.0)), (Vec3(4569.68261719, 4840.80908203, 540.924926758), Vec3(-83.4887771606, 4.08973407745, 0.0)), (Vec3(5061.6484375, 5490.93896484, 694.142578125), Vec3(-135.778717041, 0.605291008949, 0.0)), (Vec3(6273.03222656, 6343.10546875, 769.735290527), Vec3(-200.826278687, -1.35470712185, 0.0)), (Vec3(7355.02832031, 6314.39892578, 1164.65527344), Vec3(-262.645324707, -12.2435855865, 0.0)), (Vec3(6321.42431641, 4453.68310547, 898.895202637), Vec3(-322.574157715, -2.22581481934, 0.0)), (Vec3(4820.63916016, 4637.07128906, 793.165222168), Vec3(-330.291748047, 0.931967377663, 0.0)), (Vec3(2621.3125, 4790.99072266, 691.223144531), Vec3(-423.059020996, 3.10974740982, 0.0)), (Vec3(2166.64697266, 5683.75195312, 685.415039062), Vec3(-497.871612549, -1.57248008251, 0.0)), (Vec3(2426.64135742, 7216.48974609, 993.247558594), Vec3(-524.17388916, -6.69025611877, 0.0)), (Vec3(5014.83398438, 6712.60253906, 963.192810059), Vec3(-596.072387695, -3.31469583511, 0.00446693599224)), (Vec3(6107.69970703, 5460.03662109, 820.63104248), Vec3(-650.567199707, 1.04085958004, 0.0)), ) self.controller.play_motion_path(control_points, 3.0)
class Application(ShowBase): def __init__(self): # Setup window size and title load_prc_file_data( "", """ # win-size 1600 900 window-title Render Pipeline - Instancing Example """, ) # Construct the render pipeline self.render_pipeline = RenderPipeline() self.render_pipeline.create(self) self.render_pipeline.daytime_mgr.time = "19:17" # self.render_pipeline.daytime_mgr.time = "12:00" # Load the scene model = self.loader.load_model("scene/Scene.bam") model.reparent_to(self.render) # Find the prefab object, we are going to in instance this object # multiple times prefab = model.find("**/InstancedObjectPrefab") # Collect all instances matrices = [] for elem in model.find_all_matches("**/PREFAB*"): matrices.append(elem.get_mat(self.render)) elem.remove_node() print("Loaded", len(matrices), "instances!") # Allocate storage for the matrices, each matrix has 16 elements, # but because one pixel has four components, we need amount * 4 pixels. buffer_texture = Texture() buffer_texture.setup_buffer_texture(len(matrices) * 4, Texture.T_float, Texture.F_rgba32, GeomEnums.UH_static) float_size = len(struct.pack("f", 0.0)) floats = [] # Serialize matrices to floats ram_image = buffer_texture.modify_ram_image() for idx, mat in enumerate(matrices): for i in range(4): for j in range(4): floats.append(mat.get_cell(i, j)) # Write the floats to the texture data = struct.pack("f" * len(floats), *floats) ram_image.set_subdata(0, len(data), data) # Load the effect self.render_pipeline.set_effect(prefab, "effects/basic_instancing.yaml", {}) prefab.set_shader_input("InstancingData", buffer_texture) prefab.set_instance_count(len(matrices)) # We have do disable culling, so that all instances stay visible prefab.node().set_bounds(OmniBoundingVolume()) prefab.node().set_final(True) # Initialize movement controller, this is a convenience class # to provide an improved camera control compared to Panda3Ds default # mouse controller. self.controller = MovementController(self) self.controller.set_initial_position_hpr(Vec3(-23.2, -32.5, 5.3), Vec3(-33.8, -8.3, 0.0)) self.controller.setup()
class App(ShowBase): def __init__(self): """ Inits the showbase """ # Load options load_prc_file_data("", """ model-cache-dir fullscreen #f win-size 1920 1080 window-title Render Pipeline by tobspr icon-filename dataGUI/icon.ico """) # Load render pipeline self.render_pipeline = RenderPipeline(self) self.render_pipeline.create() # Init movement controller self.controller = MovementController(self) self.controller.set_initial_position_hpr( Vec3(-987.129, -2763.58, 211.47), Vec3(5.21728, 7.84863, 0)) self.controller.setup() # Hotkeys self.accept("r", self._reload_shader) self.addTask(self.update, "update") self.scene_wireframe = False self._init_terrain() self._reload_shader() def update(self, task): """ Main update task """ self.terrain.update() self.terrain_shadow.update() return task.cont def _reload_shader(self): """ Reloads all terrain shaders """ self.render_pipeline.reload_shaders() self.render_pipeline.set_effect(self.terrain.get_node(), "effects/terrain.yaml", { "render_gbuffer": True, "render_shadows": False, }) self.render_pipeline.set_effect(self.terrain_shadow.get_node(), "effects/terrain_shadow.yaml", { "render_gbuffer": False, "render_shadows": True, }, 5000) def _init_terrain(self): """ Inits the terrain """ layout = "Layout0" hmap = "data/terrain/" + layout + "/heightmap.png" bounds_file = "data/terrain/" + layout + "bounds.bin" if not isfile(bounds_file): print("Generating terrain bounds ..") TerrainMeshRenderer.generate_bounds(hmap, "data/Terrain/" + layout + "bounds.bin") terrainOffset = Vec3(-4096, -4096, 70.0) terrainScale = Vec3(1.0, 1.0, 700.0) self.terrain = TerrainMeshRenderer() self.terrain.set_heightfield_size(8192) self.terrain.set_culling_enabled(False) self.terrain.load_chunk_mesh("core/resources/Chunk32.bam") self.terrain.set_focus(base.cam, base.camLens) self.terrain.load_bounds(bounds_file) self.terrain.set_target_triangle_width(7.0) self.terrain.set_pos(terrainOffset) self.terrain.set_scale(terrainScale) self.terrain.create() node = self.terrain.get_node() node.reparentTo(render) self.terrain_shadow = TerrainMeshRenderer() self.terrain_shadow.set_heightfield_size(8192) self.terrain_shadow.load_chunk_mesh("core/resources/Chunk32.bam") self.terrain_shadow.set_focus(base.cam, base.camLens) self.terrain_shadow.set_target_triangle_width(7.0) self.terrain_shadow.load_bounds(bounds_file) self.terrain_shadow.set_pos(terrainOffset) self.terrain_shadow.set_scale(terrainScale) self.terrain_shadow.set_culling_enabled(False) self.terrain_shadow.create() nodeShadow = self.terrain_shadow.get_node() nodeShadow.reparentTo(render) hmap = loader.loadTexture("data/terrain/" + layout + "/heightmap.png") hmap.set_wrap_u(Texture.WM_clamp) hmap.set_wrap_v(Texture.WM_clamp) hmap.set_format(Texture.F_r16) node.set_shader_input("heightmap", hmap) nodeShadow.set_shader_input("heightmap", hmap) fmap = loader.loadTexture("data/terrain/" + layout + "/flowmap.png") fmap.set_wrap_u(Texture.WMClamp) fmap.set_wrap_v(Texture.WMClamp) node.set_shader_input("flowmap", fmap) for material in ['rock', 'grass', 'gravel', 'snow', 'moss']: for i in xrange(2): tex = loader.loadTexture("data/terrain/Materials/" + material + "_" + str(i+1) + ".png") tex.set_wrap_u(Texture.WM_repeat) tex.set_wrap_v(Texture.WM_repeat) tex.set_format(Texture.F_srgb_alpha) tex.set_minfilter(Texture.FT_linear_mipmap_linear) tex.set_magfilter(Texture.FT_linear) tex.set_anisotropic_degree(16) node.set_shader_input(material + ("Diffuse" if i == 0 else "Normal"), tex)