예제 #1
0
파일: Server.py 프로젝트: bnpr/Malt
    def setup(self, new_buffers, resolution, scene, scene_update,
              renderdoc_capture):
        if self.resolution != resolution:
            self.resolution = resolution
            self.pbos_inactive.extend(self.pbos_active)
            self.pbos_active = []
            assert (new_buffers is not None)
            if self.bit_depth == 8:
                optimal_format = GL_UNSIGNED_BYTE
                if glGetInternalformativ(GL_TEXTURE_2D, GL_RGBA8,
                                         GL_READ_PIXELS, 1) != GL_ZERO:
                    optimal_format = glGetInternalformativ(
                        GL_TEXTURE_2D, GL_RGBA8, GL_TEXTURE_IMAGE_TYPE, 1)
                try:
                    self.final_texture = Texture(resolution,
                                                 GL_RGBA8,
                                                 optimal_format,
                                                 pixel_format=GL_RGBA)
                except:
                    # Fallback to unsigned byte, just in case
                    self.final_texture = Texture(resolution,
                                                 GL_RGBA8,
                                                 GL_UNSIGNED_BYTE,
                                                 pixel_format=GL_RGBA)
                self.final_texture.channel_size = 1
                self.final_target = RenderTarget([self.final_texture])

        if new_buffers:
            self.buffers = new_buffers

        self.sample_index = 0
        self.is_new_frame = True
        self.needs_more_samples = True

        self.renderdoc_capture = renderdoc_capture

        self.stat_time_start = time.perf_counter()

        if scene_update or self.scene is None:
            for key, proxy in scene.proxys.items():
                proxy.resolve()

            for obj in scene.objects:
                obj.matrix = (ctypes.c_float * 16)(*obj.matrix)

            scene.batches = self.pipeline.build_scene_batches(scene.objects)
            self.scene = scene
        else:
            self.scene.camera = scene.camera
            self.scene.time = scene.time
            self.scene.frame = scene.frame
예제 #2
0
 def setup_render_targets(self, resolution, custom_io):
     self.opaque_targets = {}
     self.transparent_targets = {}
     self.color_targets = {}
     
     for io in custom_io:
         if io['io'] == 'out' and io['type'] == 'Texture':#TODO
             self.opaque_targets[io['name']] = Texture(resolution, GL.GL_RGBA16F)
             self.transparent_targets[io['name']] = Texture(resolution, GL.GL_RGBA16F)
             self.color_targets[io['name']] = Texture(resolution, GL.GL_RGBA16F)
     
     self.fbo_opaque = RenderTarget([*self.opaque_targets.values()])
     self.fbo_transparent = RenderTarget([*self.transparent_targets.values()])
     self.fbo_color = RenderTarget([*self.color_targets.values()])
예제 #3
0
    def execute(self, parameters):
        from Malt.GL import GL
        from Malt.GL.Texture import Texture
        from Malt.GL.RenderTarget import RenderTarget

        if self.pipeline.resolution != self.resolution:
            for i in range(4):
                #TODO: Doesn't work with GL_RGBA?
                self.texture_targets[i] = Texture(self.pipeline.resolution, GL.GL_RGBA16F)
            self.render_target = RenderTarget(self.texture_targets)
            self.resolution = self.pipeline.resolution
        
        self.render_target.clear([(0,0,0,0)]*4)

        global _UNPACK_SHADER
        if _UNPACK_SHADER is None:
            _UNPACK_SHADER = self.pipeline.compile_shader_from_source(_UNPACK_SRC)

        _UNPACK_SHADER.textures['IN_PACKED'] = parameters['Packed Texture']
        self.pipeline.draw_screen_pass(_UNPACK_SHADER, self.render_target, blend = False)

        parameters['A'] = self.texture_targets[0]
        parameters['B'] = self.texture_targets[1]
        parameters['C'] = self.texture_targets[2]
        parameters['D'] = self.texture_targets[3]
예제 #4
0
파일: ScreenPass.py 프로젝트: bnpr/Malt
    def execute(self, parameters):
        inputs = parameters['IN']
        outputs = parameters['OUT']
        material = parameters['PASS_MATERIAL']
        custom_io = parameters['CUSTOM_IO']

        if self.pipeline.resolution != self.resolution or self.custom_io != custom_io:
            self.texture_targets = {}
            for io in custom_io:
                if io['io'] == 'out':
                    if io['type'] == 'Texture':#TODO
                        self.texture_targets[io['name']] = Texture(self.pipeline.resolution, GL.GL_RGBA16F)
            self.render_target = RenderTarget([*self.texture_targets.values()])
            self.resolution = self.pipeline.resolution
            self.custom_io = custom_io
        
        self.render_target.clear([(0,0,0,0)]*len(self.texture_targets))

        if material and material.shader and 'SHADER' in material.shader:
            shader = material.shader['SHADER']
            for io in custom_io:
                if io['io'] == 'in':
                    if io['type'] == 'Texture':#TODO
                        from Malt.SourceTranspiler import GLSLTranspiler
                        glsl_name = GLSLTranspiler.custom_io_reference('IN', 'SCREEN_SHADER', io['name'])
                        shader.textures[glsl_name] = inputs[io['name']]
            self.pipeline.common_buffer.shader_callback(shader)
            shader.uniforms['RENDER_LAYER_MODE'].set_value(False)
            self.pipeline.draw_screen_pass(shader, self.render_target)
        
        for io in custom_io:
            if io['io'] == 'out':
                if io['type'] == 'Texture':#TODO
                    outputs[io['name']] = self.texture_targets[io['name']]
예제 #5
0
파일: MainPass.py 프로젝트: bnpr/Malt
 def setup_render_targets(self, resolution, t_depth, custom_io):
     self.custom_targets = {}
     for io in custom_io:
         if io['io'] == 'out' and io['type'] == 'Texture':  #TODO
             self.custom_targets[io['name']] = Texture(
                 resolution, GL.GL_RGBA16F)
     self.t_depth = t_depth
     self.fbo = RenderTarget([*self.custom_targets.values()], self.t_depth)
예제 #6
0
파일: NPR_Pipeline.py 프로젝트: bnpr/Malt
    def do_render(self, resolution, scene, is_final_render, is_new_frame):
        #SETUP SAMPLING
        if self.sampling_grid_size != scene.world_parameters['Samples.Grid Size']:
            self.sampling_grid_size = scene.world_parameters['Samples.Grid Size']
            self.samples = None
        
        self.is_new_frame = is_new_frame
        
        sample_offset = self.get_sample(scene.world_parameters['Samples.Width'])

        opaque_batches, transparent_batches = self.get_scene_batches(scene)
        
        self.common_buffer.load(scene, resolution, sample_offset, self.sample_count)
        scene.shader_resources = {
            'COMMON_UNIFORMS' : self.common_buffer
        }
        
        result = {
            'COLOR': None,
            'DEPTH': None,
        }
        graph = scene.world_parameters['Render']
        if graph:
            IN = {'Scene' : scene}
            OUT = {'Color' : None}
            self.graphs['Render'].run_source(self, graph['source'], graph['parameters'], IN, OUT)
            result = OUT
            result['COLOR'] = result['Color']
            result['DEPTH'] = result['Depth']

        #COMPOSITE DEPTH
        if is_final_render and result['DEPTH'] is None:
            if self.sample_count == len(self.samples) - 1:
                normal_depth = Texture(resolution, GL_RGBA32F)
                target = RenderTarget([normal_depth], Texture(resolution, GL_DEPTH_COMPONENT32F))
                target.clear([(0,0,1,1)], 1)
                self.common_buffer.load(scene, resolution)
                self.draw_scene_pass(target, opaque_batches, 'PRE_PASS', self.default_shader, scene.shader_resources)
                result['DEPTH'] = self.composite_depth.render(self, self.common_buffer, normal_depth, depth_channel=3)
        
        return result
예제 #7
0
파일: ScreenPass.py 프로젝트: bnpr/Malt
    def execute(self, parameters):
        inputs = parameters['IN']
        outputs = parameters['OUT']
        material = parameters['PASS_MATERIAL']
        custom_io = parameters['CUSTOM_IO']

        deferred_mode = inputs['Layer Only']
        scene = inputs['Scene']
        t_normal_depth = inputs['Normal Depth']
        t_id = inputs['ID']

        shader_resources = {}
        if scene:
            shader_resources = scene.shader_resources.copy()
        if t_normal_depth:
            shader_resources['IN_NORMAL_DEPTH'] = TextureShaderResource('IN_NORMAL_DEPTH', t_normal_depth)
        if t_id:
            shader_resources['IN_ID'] = TextureShaderResource('IN_ID', t_id)

        if self.pipeline.resolution != self.resolution or self.custom_io != custom_io:
            self.texture_targets = {}
            for io in custom_io:
                if io['io'] == 'out':
                    if io['type'] == 'Texture':#TODO
                        self.texture_targets[io['name']] = Texture(self.pipeline.resolution, GL.GL_RGBA16F)
            self.render_target = RenderTarget([*self.texture_targets.values()])
            self.resolution = self.pipeline.resolution
            self.custom_io = custom_io
        
        self.render_target.clear([(0,0,0,0)]*len(self.texture_targets))

        if material and material.shader and 'SHADER' in material.shader:
            shader = material.shader['SHADER']
            for io in custom_io:
                if io['io'] == 'in':
                    if io['type'] == 'Texture':#TODO
                        from Malt.SourceTranspiler import GLSLTranspiler
                        glsl_name = GLSLTranspiler.custom_io_reference('IN', 'SCREEN_SHADER', io['name'])
                        shader.textures[glsl_name] = inputs[io['name']]
            self.pipeline.common_buffer.bind(shader.uniform_blocks['COMMON_UNIFORMS'])
            for resource in shader_resources.values():
                resource.shader_callback(shader)
            shader.uniforms['RENDER_LAYER_MODE'].set_value(True)
            shader.uniforms['DEFERRED_MODE'].set_value(deferred_mode)
            self.pipeline.draw_screen_pass(shader, self.render_target)
        
        for io in custom_io:
            if io['io'] == 'out':
                if io['type'] == 'Texture':#TODO
                    outputs[io['name']] = self.texture_targets[io['name']]
예제 #8
0
 def render(self, pipeline, common_buffer, depth_texture, depth_channel=0):
     if self.t is None or self.t.resolution != depth_texture.resolution:
         self.t = Texture(depth_texture.resolution, GL_R32F)
         self.fbo = RenderTarget([self.t])
     
     if self.shader == None:
         global _SHADER
         if _SHADER is None: _SHADER = pipeline.compile_shader_from_source(_shader_src)
         self.shader = _SHADER
     
     self.shader.textures['DEPTH_TEXTURE'] = depth_texture
     self.shader.uniforms['DEPTH_CHANNEL'].set_value(depth_channel)
     common_buffer.shader_callback(self.shader)
     pipeline.draw_screen_pass(self.shader, self.fbo)
     return self.t
예제 #9
0
    def render(self, pipeline, common_buffer, depth_texture):
        if self.t is None or self.t.resolution != depth_texture.resolution:
            self.t = Texture(depth_texture.resolution, GL_R32F)
            self.fbo = RenderTarget([self.t])

        if self.shader == None:
            global _SHADER
            if _SHADER is None:
                _SHADER = pipeline.compile_shader_from_source(_shader_src)
            self.shader = _SHADER

        self.shader.textures['DEPTH_TEXTURE'] = depth_texture
        self.shader.bind()
        common_buffer.bind(self.shader.uniform_blocks['COMMON_UNIFORMS'])
        pipeline.draw_screen_pass(self.shader, self.fbo)
        return self.t
예제 #10
0
파일: PrePass.py 프로젝트: bnpr/Malt
    def setup_render_targets(self, resolution, custom_io):
        self.t_depth = Texture(resolution, GL_DEPTH_COMPONENT32F)
        
        self.t_normal_depth = Texture(resolution, GL_RGBA32F)
        self.t_id = Texture(resolution, GL_RGBA16UI, min_filter=GL_NEAREST, mag_filter=GL_NEAREST)
        self.custom_targets = {}
        for io in custom_io:
            if io['io'] == 'out' and io['type'] == 'Texture':#TODO
                self.custom_targets[io['name']] = Texture(resolution, GL.GL_RGBA16F)
        self.fbo = RenderTarget([self.t_normal_depth, self.t_id, *self.custom_targets.values()], self.t_depth)
        
        self.t_last_layer_id = Texture(resolution, GL_R16UI, min_filter=GL_NEAREST, mag_filter=GL_NEAREST)
        self.fbo_last_layer_id = RenderTarget([self.t_last_layer_id])

        self.t_opaque_depth = Texture(resolution, GL_DEPTH_COMPONENT32F)
        self.fbo_opaque_depth = RenderTarget([], self.t_opaque_depth)
        self.t_transparent_depth = Texture(resolution, GL_DEPTH_COMPONENT32F)
        self.fbo_transparent_depth = RenderTarget([], self.t_transparent_depth)
예제 #11
0
    def setup_render_targets(self, resolution):
        self.t_depth = Texture(resolution, GL_DEPTH_COMPONENT32F)

        self.t_prepass_normal_depth = Texture(resolution, GL_RGBA32F)
        self.t_prepass_id = Texture(resolution, GL_R32F)
        self.fbo_prepass = RenderTarget(
            [self.t_prepass_normal_depth, self.t_prepass_id], self.t_depth)

        self.t_last_layer_id = Texture(resolution, GL_R32F)
        self.fbo_last_layer_id = RenderTarget([self.t_last_layer_id])

        self.t_main_color = Texture(resolution, GL_RGBA32F)
        self.t_line_color = Texture(resolution, GL_RGBA32F)
        self.t_line_data = Texture(resolution, GL_RGB32F)
        self.fbo_main = RenderTarget(
            [self.t_main_color, self.t_line_color, self.t_line_data],
            self.t_depth)

        self.t_opaque_color = Texture(resolution, GL_RGB32F)
        self.t_opaque_depth = Texture(resolution, GL_DEPTH_COMPONENT32F)
        self.fbo_opaque = RenderTarget([self.t_opaque_color],
                                       self.t_opaque_depth)

        self.t_transparent_color = Texture(resolution, GL_RGBA32F)
        self.t_transparent_depth = Texture(resolution, GL_DEPTH_COMPONENT32F)
        self.fbo_transparent = RenderTarget([self.t_transparent_color],
                                            self.t_transparent_depth)

        self.t_color = Texture(resolution, GL_RGBA32F)
        self.fbo_color = RenderTarget([self.t_color])

        self.t_color_accumulate = Texture(resolution, GL_RGB32F)
        self.fbo_accumulate = RenderTarget([self.t_color_accumulate])
예제 #12
0
 def setup_render_targets(self, resolution):
     self.t_color = Texture(resolution, GL_RGBA16F)
     self.fbo = RenderTarget([self.t_color])
예제 #13
0
    def view_draw(self, context, depsgraph):
        if self.bridge is not MaltPipeline.get_bridge():
            #The Bridge has been reset
            self.bridge = MaltPipeline.get_bridge()
            self.bridge_id = self.bridge.get_viewport_id()
            self.request_new_frame = True
            self.request_scene_update = True

        global CAPTURE
        if CAPTURE:
            self.request_new_frame = True

        overrides = []
        if context.space_data.shading.type == 'MATERIAL':
            overrides.append('Preview')

        scene = self.get_scene(context, depsgraph, self.request_scene_update,
                               overrides)
        viewport_resolution = context.region.width, context.region.height
        resolution = viewport_resolution

        resolution_scale = scene.world_parameters['Viewport.Resolution Scale']
        mag_filter = GL.GL_LINEAR
        if resolution_scale != 1.0:
            w, h = resolution
            resolution = round(w * resolution_scale), round(h *
                                                            resolution_scale)
            smooth_interpolation = scene.world_parameters[
                'Viewport.Smooth Interpolation']
            mag_filter = GL.GL_LINEAR if smooth_interpolation else GL.GL_NEAREST

        if self.request_new_frame:
            self.bridge.render(self.bridge_id, resolution, scene,
                               self.request_scene_update, CAPTURE)
            CAPTURE = False
            self.request_new_frame = False
            self.request_scene_update = False

        target_fps = context.preferences.addons[
            'BlenderMalt'].preferences.render_fps_cap
        if target_fps > 0:
            delta_time = time.perf_counter() - self.last_frame_time
            target_delta = 1.0 / target_fps
            if delta_time < target_delta:
                high_res_sleep(target_delta - delta_time)

        self.last_frame_time = time.perf_counter()

        buffers, finished, read_resolution = self.bridge.render_result(
            self.bridge_id)
        pixels = buffers['COLOR']

        if not finished:
            self.tag_redraw()
        if pixels is None or resolution != read_resolution:
            # Only render if resolution is the same as read_resolution.
            # This avoids visual glitches when the viewport is resizing.
            # The alternative would be locking when writing/reading the pixel buffer.
            return

        for region in context.area.regions:
            if region.type == 'UI':
                region.tag_redraw()

        fbo = GL.gl_buffer(GL.GL_INT, 1)
        GL.glGetIntegerv(GL.GL_FRAMEBUFFER_BINDING, fbo)

        data_format = GL.GL_FLOAT
        texture_format = GL.GL_RGBA32F
        if self.bridge.viewport_bit_depth == 8:
            data_format = GL.GL_UNSIGNED_BYTE
            texture_format = GL.GL_RGBA8
            if GL.glGetInternalformativ(GL.GL_TEXTURE_2D, texture_format,
                                        GL.GL_READ_PIXELS, 1) != GL.GL_ZERO:
                data_format = GL.glGetInternalformativ(
                    GL.GL_TEXTURE_2D, texture_format, GL.GL_TEXTURE_IMAGE_TYPE,
                    1)

        render_texture = Texture(resolution,
                                 texture_format,
                                 data_format,
                                 pixels.buffer(),
                                 mag_filter=mag_filter)

        self.bind_display_space_shader(depsgraph.scene_eval)
        if self.display_draw is None or self.display_draw.resolution != viewport_resolution:
            if self.display_draw:
                self.display_draw.gl_delete()
            self.display_draw = DisplayDraw(viewport_resolution)
        self.display_draw.draw(fbo, render_texture)
        self.unbind_display_space_shader()
예제 #14
0
    def view_draw(self, context, depsgraph):
        profiler = cProfile.Profile()
        global PROFILE
        if PROFILE:
            profiler.enable()
            if self.request_new_frame:
                self.profiling_data = io.StringIO()
        
        if self.bridge is not MaltPipeline.get_bridge():
            #The Bridge has been reset
            self.bridge.free_viewport_id(self.bridge_id)
            self.bridge = MaltPipeline.get_bridge()
            self.bridge_id = self.bridge.get_viewport_id()
            self.request_new_frame = True
            self.request_scene_update = True
        
        overrides = []
        if context.space_data.shading.type == 'MATERIAL':
            overrides.append('Preview')

        scene = self.get_scene(context, depsgraph, self.request_scene_update, overrides)
        resolution = context.region.width, context.region.height

        if self.request_new_frame:
            self.bridge.render(self.bridge_id, resolution, scene, self.request_scene_update)
            self.request_new_frame = False
            self.request_scene_update = False

        buffers, finished, read_resolution = self.bridge.render_result(self.bridge_id)
        pixels = buffers['COLOR']

        if not finished:
            self.tag_redraw()
        if pixels is None or resolution != read_resolution:
            # Only render if resolution is the same as read_resolution.
            # This avoids visual glitches when the viewport is resizing.
            # The alternative would be locking when writing/reading the pixel buffer.
            return

        fbo = GL.gl_buffer(GL.GL_INT, 1)
        GL.glGetIntegerv(GL.GL_FRAMEBUFFER_BINDING, fbo)
        
        render_texture = Texture(resolution, GL.GL_RGBA32F, GL.GL_FLOAT, pixels)
        
        self.bind_display_space_shader(depsgraph.scene_eval)
        if self.display_draw is None or self.display_draw.resolution != resolution:
            if self.display_draw:
                self.display_draw.gl_delete()
            self.display_draw = DisplayDraw(resolution)
        self.display_draw.draw(fbo, render_texture)
        self.unbind_display_space_shader()

        if PROFILE:
            profiler.disable()
            stats = pstats.Stats(profiler, stream=self.profiling_data)
            stats.strip_dirs()
            stats.sort_stats(pstats.SortKey.CUMULATIVE)
            stats.print_stats()
            print('PROFILE BEGIN--------------------------------------')
            print(self.profiling_data.getvalue())
            print('PROFILE END--------------------------------------')
예제 #15
0
파일: MiniPipeline.py 프로젝트: bnpr/Malt
 def setup_render_targets(self, resolution):
     self.t_depth = Texture(resolution, GL_DEPTH_COMPONENT32F)
     self.t_main_color = Texture(resolution, GL_RGBA32F)
     self.fbo_main = RenderTarget([self.t_main_color], self.t_depth)
예제 #16
0
 def setup_render_targets(self, resolution):
     super().setup_render_targets(resolution)
     
     self.t_postpro = Texture(resolution, GL_RGBA32F)
     self.fbo_postpro = RenderTarget([self.t_postpro])
예제 #17
0
파일: Line.py 프로젝트: ternence-li/BEER
    def composite_line(self, max_width, pipeline, common_buffer, color, depth,
                       id_texture, line_color, line_data):
        '''
        if self.t_a is None or self.t_a.resolution != color.resolution:
            self.t_a = Texture(color.resolution, GL_RGBA32F)
            self.fbo_a = RenderTarget([self.t_a])
            self.t_b = Texture(color.resolution, GL_RGBA32F)
            self.fbo_b = RenderTarget([self.t_b])
        if self.shader is None:
            self.shader = pipeline.compile_shader_from_source(_shader_src)
            self.cleanup_shader = pipeline.compile_shader_from_source(_line_cleanup_src)
        
        #CLEANUP LINE
        #(Try to workaround numerical stability issues, disabled for now)
        cleanup = False
        if cleanup:
            self.fbo_composite.clear([(0,0,0,0)])
            self.cleanup_shader.textures['line_data_texture'] = line_data
            self.cleanup_shader.bind()
            common_buffer.bind(self.cleanup_shader.uniform_blocks['COMMON_UNIFORMS'])
            pipeline.draw_screen_pass(self.cleanup_shader, self.fbo_composite)
            line_data = self.fbo_composite.targets[0]
        
        #JUMP FLOOD
        #Disabled since we moved back to brute-force line rendering
        jump_flood = False
        if jump_flood:
            jump_flood_max_width = max(line_data.resolution[0], line_data.resolution[1])
            
            steps = []
            width = 1
            while width < jump_flood_max_width:
                steps.append(width)
                width*=2
            
            steps.reverse()
            
            self.fbo_a.clear([(-1,-1,-1,-1)])
            self.fbo_b.clear([(-1,-1,-1,-1)])
            read = line_data
            write = self.fbo_b

            for i, step in enumerate(steps):
                if i > 0:
                    if i % 2 == 0:
                        read = self.t_a
                        write = self.fbo_b
                    else:
                        read = self.t_b
                        write = self.fbo_a
                
                self.shader.textures['input_texture'] = read
                self.shader.uniforms['width'].set_value(step)
                self.shader.bind()
                common_buffer.bind(self.shader.uniform_blocks['COMMON_UNIFORMS'])
                pipeline.draw_screen_pass(self.shader, write)
        '''

        if self.t_composite is None or self.t_composite.resolution != color.resolution:
            self.t_composite = Texture(color.resolution, GL_RGBA32F)
            self.fbo_composite = RenderTarget([self.t_composite])

        if self.composite_shader is None:
            global _LINE_COMPOSITE_SHADER
            if _LINE_COMPOSITE_SHADER is None:
                _LINE_COMPOSITE_SHADER = pipeline.compile_shader_from_source(
                    _line_composite_src)
            self.composite_shader = _LINE_COMPOSITE_SHADER

        #LINE COMPOSITE
        self.fbo_composite.clear([(0, 0, 0, 0)])
        self.composite_shader.uniforms['brute_force_range'].set_value(
            math.ceil(max_width / 2))
        self.composite_shader.textures['color_texture'] = color
        self.composite_shader.textures['depth_texture'] = depth
        self.composite_shader.textures['id_texture'] = id_texture
        self.composite_shader.textures['line_color_texture'] = line_color
        self.composite_shader.textures['line_data_texture'] = line_data
        #self.composite_shader.textures['line_distance_field_texture'] = write.targets[0]
        self.composite_shader.bind()
        common_buffer.bind(
            self.composite_shader.uniform_blocks['COMMON_UNIFORMS'])
        pipeline.draw_screen_pass(self.composite_shader, self.fbo_composite)

        return self.t_composite