def init_internal_manager(self):
        """ Creates the light storage manager and the buffer to store the light data """
        self.internal_mgr = InternalLightManager()
        self.internal_mgr.set_shadow_update_distance(
            self.pipeline.settings["shadows.max_update_distance"])

        # Storage for the Lights
        per_light_vec4s = 4
        self.img_light_data = Image.create_buffer(
            "LightData", self.MAX_LIGHTS * per_light_vec4s, "RGBA16")
        self.img_light_data.set_clear_color(0)
        self.img_light_data.clear_image()

        self.pta_max_light_index = PTAInt.empty_array(1)
        self.pta_max_light_index[0] = 0

        # Storage for the shadow sources
        per_source_vec4s = 5
        self.img_source_data = Image.create_buffer(
            "ShadowSourceData", self.MAX_SOURCES * per_source_vec4s, "RGBA16")
        self.img_light_data.set_clear_color(0)
        self.img_light_data.clear_image()

        # Register the buffer
        inputs = self.pipeline.stage_mgr.inputs
        inputs["AllLightsData"] = self.img_light_data
        inputs["ShadowSourceData"] = self.img_source_data
        inputs["maxLightIndex"] = self.pta_max_light_index
示例#2
0
    def init_internal_manager(self):
        """ Creates the light storage manager and the buffer to store the light data """
        self.internal_mgr = InternalLightManager()
        self.internal_mgr.set_shadow_update_distance(
            self.pipeline.settings["shadows.max_update_distance"])

        # Storage for the Lights
        per_light_vec4s = 4
        self.img_light_data = Image.create_buffer(
            "LightData", self.MAX_LIGHTS * per_light_vec4s, "RGBA16")
        self.img_light_data.clear_image()

        self.pta_max_light_index = PTAInt.empty_array(1)
        self.pta_max_light_index[0] = 0

        # Storage for the shadow sources
        per_source_vec4s = 5

        # IMPORTANT: RGBA32 is really required here. Otherwise artifacts and bad
        # shadow filtering occur due to precision issues
        self.img_source_data = Image.create_buffer(
            "ShadowSourceData", self.MAX_SOURCES * per_source_vec4s, "RGBA32")
        self.img_light_data.clear_image()

        # Register the buffer
        inputs = self.pipeline.stage_mgr.inputs
        inputs["AllLightsData"] = self.img_light_data
        inputs["ShadowSourceData"] = self.img_source_data
        inputs["maxLightIndex"] = self.pta_max_light_index
示例#3
0
    def init_internal_manager(self):
        """ Creates the light storage manager and the buffer to store the light data """
        self.internal_mgr = InternalLightManager()
        self.internal_mgr.set_shadow_update_distance(
            self.pipeline.settings["shadows.max_update_distance"])

        # Storage for the Lights
        per_light_vec4s = 4
        self.img_light_data = Image.create_buffer(
            "LightData", self.MAX_LIGHTS * per_light_vec4s, "RGBA16")
        self.img_light_data.set_clear_color(0)
        self.img_light_data.clear_image()

        self.pta_max_light_index = PTAInt.empty_array(1)
        self.pta_max_light_index[0] = 0

        # Storage for the shadow sources
        per_source_vec4s = 5

        # IMPORTANT: RGBA32 is really required here. Otherwise artifacts and bad
        # shadow filtering occur due to precision issues
        self.img_source_data = Image.create_buffer(
            "ShadowSourceData", self.MAX_SOURCES * per_source_vec4s, "RGBA32")
        self.img_light_data.set_clear_color(0)
        self.img_light_data.clear_image()

        # Register the buffer
        inputs = self.pipeline.stage_mgr.inputs
        inputs["AllLightsData"] = self.img_light_data
        inputs["ShadowSourceData"] = self.img_source_data
        inputs["maxLightIndex"] = self.pta_max_light_index
 def _create_data_storage(self):
     """ Creates the buffer used to transfer commands """
     command_buffer_size = self._commands_per_frame * 32
     self.debug("Allocating command buffer of size", command_buffer_size)
     self._data_texture = Image.create_buffer("CommandQueue",
                                              command_buffer_size, "R32")
     self._data_texture.set_clear_color(0)
    def create(self):

        # Create the target which converts the scene color to a luminance
        self.target_lum = self.create_target("GetLuminance")
        self.target_lum.size = -4
        self.target_lum.add_color_attachment(bits=(16, 0, 0, 0))
        self.target_lum.prepare_buffer()

        self.mip_targets = []

        # Create the storage for the exposure, this stores the current and last
        # frames exposure
        # XXX: We have to use F_r16 instead of F_r32 because of a weird nvidia
        # driver bug! However, 16 bits should be enough for sure.
        self.tex_exposure = Image.create_buffer("ExposureStorage", 1, "R16")
        self.tex_exposure.set_clear_color(Vec4(0.5))
        self.tex_exposure.clear_image()

        # Create the target which extracts the exposure from the average brightness
        self.target_analyze = self.create_target("AnalyzeBrightness")
        self.target_analyze.size = 1, 1
        self.target_analyze.prepare_buffer()

        self.target_analyze.set_shader_input("ExposureStorage", self.tex_exposure)

        # Create the target which applies the generated exposure to the scene
        self.target_apply = self.create_target("ApplyExposure")
        self.target_apply.add_color_attachment(bits=16)
        self.target_apply.prepare_buffer()
        self.target_apply.set_shader_input("Exposure", self.tex_exposure)
示例#6
0
    def _create_components(self):
        """ Internal method to init the widgets components """

        # Create the buffer which stores the last FPS values
        self._storage_buffer = Image.create_buffer("FPSValues", 250, "R16")
        self._storage_buffer.set_clear_color(Vec4(0))
        self._storage_buffer.clear_image()

        self._store_index = PTAInt.empty_array(1)
        self._store_index[0] = 0

        self._current_ftime = PTAFloat.empty_array(1)
        self._current_ftime[0] = 16.0

        self._chart_ms_max = PTAFloat.empty_array(1)
        self._chart_ms_max[0] = 40

        # Create the texture where the gui component is rendered inside
        self._display_tex = Image.create_2d("FPSChartRender", 250, 120, "RGBA8")
        self._display_tex.set_clear_color(Vec4(0))
        self._display_tex.clear_image()
        self._display_img = Sprite(
            image=self._display_tex, parent=self._node, w=250, h=120, x=10, y=10)

        # Defer the further loading
        Globals.base.taskMgr.doMethodLater(0.3, self._late_init, "FPSChartInit")
    def init(self):
        """ Creates the cubemap storage """

        # Storage for the specular components (with mipmaps)
        self.cubemap_storage = Image.create_cube_array("EnvmapStorage",
                                                       self.resolution,
                                                       self.max_probes,
                                                       "RGBA16")
        self.cubemap_storage.set_minfilter(
            SamplerState.FT_linear_mipmap_linear)
        self.cubemap_storage.set_magfilter(SamplerState.FT_linear)
        self.cubemap_storage.set_clear_color(Vec4(1.0, 0.0, 0.1, 1.0))
        self.cubemap_storage.clear_image()

        # Storage for the diffuse component
        self.diffuse_storage = Image.create_cube_array("EnvmapDiffStorage",
                                                       self.diffuse_resolution,
                                                       self.max_probes,
                                                       "RGBA16")
        self.diffuse_storage.set_clear_color(Vec4(1, 0, 0.2, 1.0))
        self.diffuse_storage.clear_image()

        # Data-storage to store all cubemap properties
        self.dataset_storage = Image.create_buffer("EnvmapData",
                                                   self.max_probes * 5,
                                                   "RGBA32")
        self.dataset_storage.set_clear_color(Vec4(0))
        self.dataset_storage.clear_image()
示例#8
0
    def _create_components(self):
        """ Internal method to init the widgets components """

        # Create the buffer which stores the last FPS values
        self._storage_buffer = Image.create_buffer("FPSValues", 250, "R16")
        self._storage_buffer.set_clear_color(Vec4(0))
        self._storage_buffer.clear_image()

        self._store_index = PTAInt.empty_array(1)
        self._store_index[0] = 0

        self._current_ftime = PTAFloat.empty_array(1)
        self._current_ftime[0] = 16.0

        self._chart_ms_max = PTAFloat.empty_array(1)
        self._chart_ms_max[0] = 40

        # Create the texture where the gui component is rendered inside
        self._display_tex = Image.create_2d("FPSChartRender", 250, 120,
                                            "RGBA8")
        self._display_tex.set_clear_color(Vec4(0))
        self._display_tex.clear_image()
        self._display_img = Sprite(image=self._display_tex,
                                   parent=self._node,
                                   w=250,
                                   h=120,
                                   x=10,
                                   y=10)

        # Defer the further loading
        Globals.base.taskMgr.doMethodLater(0.3, self._late_init,
                                           "FPSChartInit")
    def create(self):

        # Create the target which converts the scene color to a luminance
        self.target_lum = self.create_target("GetLuminance")
        self.target_lum.size = -4
        self.target_lum.add_color_attachment(bits=(16, 0, 0, 0))
        self.target_lum.prepare_buffer()

        self.mip_targets = []

        # Create the storage for the exposure, this stores the current and last
        # frames exposure
        # XXX: We have to use F_r16 instead of F_r32 because of a weird nvidia
        # driver bug! However, 16 bits should be enough for sure.
        self.tex_exposure = Image.create_buffer("ExposureStorage", 1, "R16")
        self.tex_exposure.set_clear_color(Vec4(0.5))
        self.tex_exposure.clear_image()

        # Create the target which extracts the exposure from the average brightness
        self.target_analyze = self.create_target("AnalyzeBrightness")
        self.target_analyze.size = 1, 1
        self.target_analyze.prepare_buffer()

        self.target_analyze.set_shader_input("ExposureStorage", self.tex_exposure)

        # Create the target which applies the generated exposure to the scene
        self.target_apply = self.create_target("ApplyExposure")
        self.target_apply.add_color_attachment(bits=16, alpha=True)
        self.target_apply.prepare_buffer()
        self.target_apply.set_shader_input("Exposure", self.tex_exposure)
示例#10
0
    def create(self):
        self.target_visible = self.create_target("GetVisibleLights")
        self.target_visible.size = 16, 16
        self.target_visible.prepare_buffer()

        # TODO: Use no oversized triangle in this stage
        self.target_cull = self.create_target("CullLights")
        self.target_cull.size = 0, 0
        self.target_cull.prepare_buffer()

        # TODO: Use no oversized triangle in this stage
        self.target_group = self.create_target("GroupLightsByClass")
        self.target_group.size = 0, 0
        self.target_group.prepare_buffer()

        self.frustum_lights_ctr = Image.create_counter("VisibleLightCount")
        self.frustum_lights = Image.create_buffer(
            "FrustumLights", self._pipeline.light_mgr.MAX_LIGHTS, "R16UI")
        self.per_cell_lights = Image.create_buffer("PerCellLights", 0, "R16UI")
        self.per_cell_light_counts = Image.create_buffer(
            "PerCellLightCounts", 0, "R32I")
        self.grouped_cell_lights = Image.create_buffer("GroupedPerCellLights",
                                                       0, "R16UI")

        self.target_visible.set_shader_input("FrustumLights",
                                             self.frustum_lights)
        self.target_visible.set_shader_input("FrustumLightsCount",
                                             self.frustum_lights_ctr)
        self.target_cull.set_shader_input("PerCellLightsBuffer",
                                          self.per_cell_lights)
        self.target_cull.set_shader_input("PerCellLightCountsBuffer",
                                          self.per_cell_light_counts)
        self.target_cull.set_shader_input("FrustumLights", self.frustum_lights)
        self.target_cull.set_shader_input("FrustumLightsCount",
                                          self.frustum_lights_ctr)
        self.target_group.set_shader_input("PerCellLightsBuffer",
                                           self.per_cell_lights)
        self.target_group.set_shader_input("PerCellLightCountsBuffer",
                                           self.per_cell_light_counts)
        self.target_group.set_shader_input("GroupedCellLightsBuffer",
                                           self.grouped_cell_lights)

        self.target_cull.set_shader_input("threadCount", self.cull_threads)
        self.target_group.set_shader_input("threadCount", 1)
示例#11
0
    def create(self):
        self.target_visible = self.create_target("GetVisibleLights")
        self.target_visible.size = 16, 16
        self.target_visible.prepare_buffer()

        # TODO: Use no oversized triangle in this stage
        self.target_cull = self.create_target("CullLights")
        self.target_cull.size = 0, 0
        self.target_cull.prepare_buffer()

        # TODO: Use no oversized triangle in this stage
        self.target_group = self.create_target("GroupLightsByClass")
        self.target_group.size = 0, 0
        self.target_group.prepare_buffer()

        self.frustum_lights_ctr = Image.create_counter("VisibleLightCount")
        self.frustum_lights = Image.create_buffer(
            "FrustumLights", self._pipeline.light_mgr.MAX_LIGHTS, "R16UI")
        self.per_cell_lights = Image.create_buffer(
            "PerCellLights", 0, "R16UI")
        self.per_cell_light_counts = Image.create_buffer(
            "PerCellLightCounts", 0, "R32I") # Needs to be R32 for atomic add in cull stage
        self.grouped_cell_lights = Image.create_buffer(
            "GroupedPerCellLights", 0, "R16UI")
        self.grouped_cell_lights_counts = Image.create_buffer(
            "GroupedPerCellLightsCount", 0, "R16UI")

        self.target_visible.set_shader_inputs(
            FrustumLights=self.frustum_lights,
            FrustumLightsCount=self.frustum_lights_ctr)

        self.target_cull.set_shader_inputs(
            PerCellLightsBuffer=self.per_cell_lights,
            PerCellLightCountsBuffer=self.per_cell_light_counts,
            FrustumLights=self.frustum_lights,
            FrustumLightsCount=self.frustum_lights_ctr,
            threadCount=self.cull_threads)

        self.target_group.set_shader_inputs(
            PerCellLightsBuffer=self.per_cell_lights,
            PerCellLightCountsBuffer=self.per_cell_light_counts,
            GroupedCellLightsBuffer=self.grouped_cell_lights,
            GroupedPerCellLightsCountBuffer=self.grouped_cell_lights_counts,
            threadCount=1)
    def create(self):
        # TODO: Use no oversized triangle in this stage
        self.target = self.create_target("CullProbes")
        self.target.size = 0, 0
        self.target.prepare_buffer()

        self.per_cell_probes = Image.create_buffer("PerCellProbes", 0, "R32I")
        self.per_cell_probes.clear_image()
        self.target.set_shader_input("PerCellProbes", self.per_cell_probes)
        self.target.set_shader_input("threadCount", 1)
示例#13
0
    def create(self):
        # TODO: Use no oversized triangle in this stage
        self.target = self.create_target("CullProbes")
        self.target.size = 0, 0
        self.target.prepare_buffer()

        self.per_cell_probes = Image.create_buffer("PerCellProbes", 0, "R32I")
        self.per_cell_probes.clear_image()
        self.target.set_shader_input("PerCellProbes", self.per_cell_probes)
        self.target.set_shader_input("threadCount", 1)
示例#14
0
    def create(self):
        self.target = self.create_target("CollectUsedCells")
        self.target.size = 0, 0
        self.target.prepare_buffer()

        self.cell_list_buffer = Image.create_buffer("CellList", 0, "R32I")
        self.cell_index_buffer = Image.create_2d_array("CellIndices", 0, 0, 0, "R32I")

        self.target.set_shader_inputs(
            CellListBuffer=self.cell_list_buffer,
            CellListIndices=self.cell_index_buffer)
示例#15
0
    def create(self):
        max_cells = self._pipeline.light_mgr.total_tiles

        self.num_rows = int(math.ceil(max_cells / float(self.slice_width)))
        self.target = self.create_target("CullProbes")
        # TODO: Use no oversized triangle in this stage
        self.target.size = self.slice_width, self.num_rows
        self.target.prepare_buffer()

        self.per_cell_probes = Image.create_buffer(
            "PerCellProbes", max_cells * self.max_probes_per_cell, "R32I")
        self.per_cell_probes.set_clear_color(0)
        self.per_cell_probes.clear_image()
        self.target.set_shader_input("PerCellProbes", self.per_cell_probes)
    def create(self):

        # Create the target which converts the scene color to a luminance
        self.target_lum = self.create_target("GetLuminance")
        self.target_lum.size = -4
        self.target_lum.add_color_attachment(bits=(16, 0, 0, 0))
        self.target_lum.prepare_buffer()

        # Get the current quarter-window size
        wsize_x = (Globals.resolution.x + 3) // 4
        wsize_y = (Globals.resolution.y + 3) // 4

        # Create the targets which downscale the luminance mipmaps
        self.mip_targets = []
        last_tex = self.target_lum.color_tex
        while wsize_x >= 4 or wsize_y >= 4:
            wsize_x = (wsize_x+3) // 4
            wsize_y = (wsize_y+3) // 4

            mip_target = self.create_target("DScaleLum:S" + str(wsize_x))
            mip_target.add_color_attachment(bits=(16, 0, 0, 0))
            mip_target.size = wsize_x, wsize_y
            mip_target.prepare_buffer()
            mip_target.set_shader_input("SourceTex", last_tex)
            self.mip_targets.append(mip_target)
            last_tex = mip_target.color_tex

        # Create the storage for the exposure, this stores the current and last
        # frames exposure

        # XXX: We have to use F_r16 instead of F_r32 because of a weird nvidia
        # driver bug! However, 16 bits should be enough for sure.
        self.tex_exposure = Image.create_buffer("ExposureStorage", 1, "R16")
        self.tex_exposure.set_clear_color(Vec4(0.5))
        self.tex_exposure.clear_image()

        # Create the target which extracts the exposure from the average brightness
        self.target_analyze = self.create_target("AnalyzeBrightness")
        self.target_analyze.size = 1, 1
        self.target_analyze.prepare_buffer()

        self.target_analyze.set_shader_input(
            "ExposureStorage", self.tex_exposure)
        self.target_analyze.set_shader_input("DownscaledTex", last_tex)

        # Create the target which applies the generated exposure to the scene
        self.target_apply = self.create_target("ApplyExposure")
        self.target_apply.add_color_attachment(bits=16)
        self.target_apply.prepare_buffer()
        self.target_apply.set_shader_input("Exposure", self.tex_exposure)
    def create(self):
        max_cells = self._pipeline.light_mgr.total_tiles

        self.num_rows = int(math.ceil(max_cells / float(self.slice_width)))
        self.target = self.create_target("CullProbes")
        # TODO: Use no oversized triangle in this stage
        self.target.size = self.slice_width, self.num_rows
        self.target.prepare_buffer()

        self.per_cell_probes = Image.create_buffer(
            "PerCellProbes", max_cells * self.max_probes_per_cell, "R32I")
        self.per_cell_probes.set_clear_color(0)
        self.per_cell_probes.clear_image()
        self.target.set_shader_input("PerCellProbes", self.per_cell_probes)
示例#18
0
    def create(self):

        # Create the target which converts the scene color to a luminance
        self.target_lum = self.create_target("GetLuminance")
        self.target_lum.size = -4
        self.target_lum.add_color_attachment(bits=(16, 0, 0, 0))
        self.target_lum.prepare_buffer()

        # Get the current quarter-window size
        wsize_x = (Globals.resolution.x + 3) // 4
        wsize_y = (Globals.resolution.y + 3) // 4

        # Create the targets which downscale the luminance mipmaps
        self.mip_targets = []
        last_tex = self.target_lum.color_tex
        while wsize_x >= 4 or wsize_y >= 4:
            wsize_x = (wsize_x+3) // 4
            wsize_y = (wsize_y+3) // 4

            mip_target = self.create_target("DScaleLum:S" + str(wsize_x))
            mip_target.add_color_attachment(bits=(16, 0, 0, 0))
            mip_target.size = wsize_x, wsize_y
            mip_target.prepare_buffer()
            mip_target.set_shader_input("SourceTex", last_tex)
            self.mip_targets.append(mip_target)
            last_tex = mip_target.color_tex

        # Create the storage for the exposure, this stores the current and last
        # frames exposure

        # XXX: We have to use F_r16 instead of F_r32 because of a weird nvidia
        # driver bug! However, 16 bits should be enough for sure.
        self.tex_exposure = Image.create_buffer("ExposureStorage", 1, "R16")
        self.tex_exposure.set_clear_color(Vec4(0.5))
        self.tex_exposure.clear_image()

        # Create the target which extracts the exposure from the average brightness
        self.target_analyze = self.create_target("AnalyzeBrightness")
        self.target_analyze.size = 1, 1
        self.target_analyze.prepare_buffer()

        self.target_analyze.set_shader_input(
            "ExposureStorage", self.tex_exposure)
        self.target_analyze.set_shader_input("DownscaledTex", last_tex)

        # Create the target which applies the generated exposure to the scene
        self.target_apply = self.create_target("ApplyExposure")
        self.target_apply.add_color_attachment(bits=16)
        self.target_apply.prepare_buffer()
        self.target_apply.set_shader_input("Exposure", self.tex_exposure)
    def create(self):
        max_cells = self._pipeline.light_mgr.total_tiles
        self.num_rows = int(math.ceil(max_cells / float(self.slice_width)))
        self.target = self.create_target("CullLights")

        # TODO: Use no oversized triangle in this stage
        self.target.size = self.slice_width, self.num_rows
        self.target.prepare_buffer()

        self.per_cell_lights = Image.create_buffer(
            "PerCellLights", max_cells * (self.max_lights_per_cell + self.num_light_classes),
            "R32I")
        self.per_cell_lights.set_clear_color(0)
        self.target.set_shader_input("PerCellLightsBuffer", self.per_cell_lights)

        self.debug("Using", self.num_rows, "culling lines")
    def create(self):
        tile_amount = self._pipeline.light_mgr.num_tiles

        self.target = self.create_target("CollectUsedCells")
        self.target.size = tile_amount.x, tile_amount.y
        self.target.prepare_buffer()

        num_slices = self._pipeline.settings["lighting.culling_grid_slices"]
        max_cells = tile_amount.x * tile_amount.y * num_slices

        self.debug("Allocating", max_cells, "cells")
        self._cell_list_buffer = Image.create_buffer("CellList", 1 + max_cells, "R32I")
        self._cell_list_buffer.set_clear_color(0)
        self._cell_index_buffer = Image.create_2d_array(
            "CellIndices", tile_amount.x, tile_amount.y, num_slices, "R32I")
        self._cell_index_buffer.set_clear_color(0)

        self.target.set_shader_input("CellListBuffer", self._cell_list_buffer)
        self.target.set_shader_input("CellListIndices", self._cell_index_buffer)
    def create(self):
        tile_amount = self._pipeline.light_mgr.num_tiles

        self.target = self.create_target("CollectUsedCells")
        self.target.size = tile_amount.x, tile_amount.y
        self.target.prepare_buffer()

        num_slices = self._pipeline.settings["lighting.culling_grid_slices"]
        max_cells = tile_amount.x * tile_amount.y * num_slices

        self.debug("Allocating", max_cells, "cells")
        self._cell_list_buffer = Image.create_buffer("CellList", 1 + max_cells,
                                                     "R32I")
        self._cell_list_buffer.set_clear_color(0)
        self._cell_index_buffer = Image.create_2d_array(
            "CellIndices", tile_amount.x, tile_amount.y, num_slices, "R32I")
        self._cell_index_buffer.set_clear_color(0)

        self.target.set_shader_input("CellListBuffer", self._cell_list_buffer)
        self.target.set_shader_input("CellListIndices",
                                     self._cell_index_buffer)
示例#22
0
    def init(self):
        """ Creates the cubemap storage """

        # Storage for the specular components (with mipmaps)
        self.cubemap_storage = Image.create_cube_array(
            "EnvmapStorage", self.resolution, self.max_probes, "RGBA16")
        self.cubemap_storage.set_minfilter(SamplerState.FT_linear_mipmap_linear)
        self.cubemap_storage.set_magfilter(SamplerState.FT_linear)
        self.cubemap_storage.set_clear_color(Vec4(1.0, 0.0, 0.1, 1.0))
        self.cubemap_storage.clear_image()

        # Storage for the diffuse component
        self.diffuse_storage = Image.create_cube_array(
            "EnvmapDiffStorage", self.diffuse_resolution, self.max_probes, "RGBA16")
        self.diffuse_storage.set_clear_color(Vec4(1, 0, 0.2, 1.0))
        self.diffuse_storage.clear_image()

        # Data-storage to store all cubemap properties
        self.dataset_storage = Image.create_buffer(
            "EnvmapData", self.max_probes * 5, "RGBA32")
        self.dataset_storage.set_clear_color(Vec4(0))
        self.dataset_storage.clear_image()
 def _create_data_storage(self):
     """ Creates the buffer used to transfer commands """
     command_buffer_size = self._commands_per_frame * 32
     self.debug("Allocating command buffer of size", command_buffer_size)
     self._data_texture = Image.create_buffer("CommandQueue", command_buffer_size, "R32")
     self._data_texture.set_clear_color(0)