Beispiel #1
0
    def setup(self):
        
        self.spot_t = TextureArray((spot_resolution, spot_resolution), max_spots, GL_DEPTH_COMPONENT32F)
        for i in range(self.spot_t.length):
            self.spot_fbos.append(RenderTarget(depth_stencil=ArrayLayerTarget(self.spot_t, i)))

        self.sun_t = TextureArray((sun_resolution, sun_resolution), max_suns, GL_DEPTH_COMPONENT32F)
        for i in range(self.sun_t.length):
            self.sun_fbos.append(RenderTarget(depth_stencil=ArrayLayerTarget(self.sun_t, i)))

        #self.point = TextureArray(spot_resolution, max_points, GL_DEPTH_COMPONENT32F)

        self.initialized = True
Beispiel #2
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_main_color = Texture(resolution, GL_RGB32F)
        self.t_line_color = Texture(resolution, GL_RGB32F)
        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_color_accumulate = Texture(resolution, GL_RGB32F)
        self.fbo_accumulate = RenderTarget([self.t_color_accumulate])
Beispiel #3
0
    def setup(self):
        self.spot_depth_t = TextureArray(
            (self.spot_resolution, self.spot_resolution), self.max_spots,
            GL_DEPTH_COMPONENT32F)
        if self.draw_ids:
            self.spot_id_t = TextureArray(
                (self.spot_resolution, self.spot_resolution), self.max_spots,
                GL_R32F)
        self.spot_fbos = []
        for i in range(self.spot_depth_t.length):
            targets = [None, ArrayLayerTarget(self.spot_id_t, i)
                       ] if self.draw_ids else [None, None]
            self.spot_fbos.append(
                RenderTarget(targets, ArrayLayerTarget(self.spot_depth_t, i)))

        self.sun_depth_t = TextureArray(
            (self.sun_resolution, self.sun_resolution),
            self.max_suns * self.sun_cascades, GL_DEPTH_COMPONENT32F)
        if self.draw_ids:
            self.sun_id_t = TextureArray(
                (self.sun_resolution, self.sun_resolution),
                self.max_suns * self.sun_cascades, GL_R32F)
        self.sun_fbos = []
        for i in range(self.sun_depth_t.length):
            targets = [None, ArrayLayerTarget(self.sun_id_t, i)
                       ] if self.draw_ids else [None, None]
            self.sun_fbos.append(
                RenderTarget(targets, ArrayLayerTarget(self.sun_depth_t, i)))

        self.point_depth_t = CubeMapArray(
            (self.point_resolution, self.point_resolution), self.max_points,
            GL_DEPTH_COMPONENT32F)
        if self.draw_ids:
            self.point_id_t = CubeMapArray(
                (self.point_resolution, self.point_resolution),
                self.max_points, GL_R32F)
        self.point_fbos = []
        for i in range(self.point_depth_t.length * 6):
            targets = [None, ArrayLayerTarget(self.point_id_t, i)
                       ] if self.draw_ids else [None, None]
            self.point_fbos.append(
                RenderTarget(targets, ArrayLayerTarget(self.point_depth_t, i)))

        self.initialized = True
    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:
            self.shader = pipeline.compile_shader_from_source(_shader_src)

        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
Beispiel #5
0
    def render(self, pipeline, common_buffer, normal_depth_texture, samples,
               radius):
        if self.t is None or self.t.resolution != normal_depth_texture.resolution:
            self.t = Texture(normal_depth_texture.resolution, GL_R32F)
            self.fbo = RenderTarget([self.t])

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

        self.shader.textures['IN_NORMAL_DEPTH'] = normal_depth_texture
        self.shader.uniforms['samples'].set_value(samples)
        self.shader.uniforms['radius'].set_value(radius)
        self.shader.bind()
        common_buffer.bind(self.shader.uniform_blocks['COMMON_UNIFORMS'])
        pipeline.draw_screen_pass(self.shader, self.fbo)
        return self.t
Beispiel #6
0
class PipelineTest(Pipeline):
    def __init__(self):
        super().__init__()

        self.sampling_grid_size = 2

        self.parameters.scene['Preview Samples'] = GLUniform(-1, GL.GL_INT, 4)
        self.parameters.scene['Render Samples'] = GLUniform(-1, GL.GL_INT, 8)
        self.parameters.scene['Line Width Max'] = GLUniform(-1, GL.GL_INT, 10)
        self.parameters.world['Background Color'] = GLUniform(
            -1, GL_FLOAT_VEC4, (0.5, 0.5, 0.5, 1))

        self.default_shader = self.compile_material_from_source(
            '')  #Empty source will force defaults

        self.composite_depth_shader = self.compile_shader_from_source(
            _obj_composite_depth)

        self.common_buffer = Common.CommonBuffer()
        self.lights_buffer = Lighting.LightsBuffer()

        self.line_rendering = Line.LineRendering()

    def compile_material_from_source(self, source, include_paths=[]):
        source = _NPR_Pipeline_Common + source
        return {
            'PRE_PASS':
            self.compile_shader_from_source(source, 'COMMON_VERTEX_SHADER',
                                            'PRE_PASS_PIXEL_SHADER',
                                            include_paths, ['PRE_PASS']),
            'MAIN_PASS':
            self.compile_shader_from_source(source, 'COMMON_VERTEX_SHADER',
                                            'MAIN_PASS_PIXEL_SHADER',
                                            include_paths, ['MAIN_PASS'])
        }

    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_main_color = Texture(resolution, GL_RGB32F)
        self.t_line_color = Texture(resolution, GL_RGB32F)
        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_color_accumulate = Texture(resolution, GL_RGB32F)
        self.fbo_accumulate = RenderTarget([self.t_color_accumulate])

        self.t_composite_depth = Texture(resolution, GL_R32F)
        self.fbo_composite_depth = RenderTarget([self.t_composite_depth],
                                                self.t_depth)

    def get_samples(self):
        return Sampling.get_RGSS_samples(self.sampling_grid_size)

    def do_render(self, resolution, scene, is_final_render, is_new_frame):
        #SETUP SAMPLING
        if is_final_render:
            self.sampling_grid_size = scene.parameters['Render Samples'][0]
        else:
            self.sampling_grid_size = scene.parameters['Preview Samples'][0]

        sample_offset = self.get_samples()[self.sample_count]

        #SETUP UNIFORM BLOCKS
        self.common_buffer.load(scene, resolution, sample_offset,
                                self.sample_count)
        self.lights_buffer.load(scene)
        UBOS = {
            'COMMON_UNIFORMS': self.common_buffer,
            'SCENE_LIGHTS': self.lights_buffer
        }

        #SETUP PER-OBJECT PARAMETERS
        for i, obj in enumerate(scene.objects):
            obj.parameters['MODEL'] = obj.matrix
            obj.parameters['ID'] = i + 1

        #PRE-PASS
        self.fbo_prepass.clear([(0, 0, 1, 1), 0], 1, 0)
        self.draw_scene_pass(self.fbo_prepass, scene.objects, 'PRE_PASS',
                             self.default_shader['PRE_PASS'], UBOS)

        #MAIN-PASS
        textures = {
            'IN_NORMAL_DEPTH': self.t_prepass_normal_depth,
            'IN_ID': self.t_prepass_id,
        }
        self.fbo_main.clear([
            scene.world_parameters['Background Color'], (0, 0, 0, 0),
            (-1, -1, -1, -1)
        ])
        self.draw_scene_pass(self.fbo_main, scene.objects, 'MAIN_PASS',
                             self.default_shader['MAIN_PASS'], UBOS, {},
                             textures)

        composited_line = self.line_rendering.composite_line(
            scene.parameters['Line Width Max'], self, self.common_buffer,
            self.t_main_color, self.t_depth, self.t_prepass_id,
            self.t_line_color, self.t_line_data)

        # TEMPORAL SUPER-SAMPLING ACCUMULATION
        # TODO: Should accumulate in display space ???
        # https://therealmjp.github.io/posts/msaa-overview/#working-with-hdr-and-tone-mapping
        self.blend_texture(composited_line, self.fbo_accumulate,
                           1.0 / (self.sample_count + 1))

        #COMPOSITE DEPTH
        if is_final_render:
            self.fbo_composite_depth.clear((10.0e+32, 1.0, 1.0, 1.0))
            self.draw_scene_pass(self.fbo_composite_depth, scene.objects, None,
                                 self.composite_depth_shader, UBOS)

        return {
            'COLOR': self.t_color_accumulate,
            'DEPTH': self.t_composite_depth,
        }
Beispiel #7
0
class PipelineTest(Pipeline):
    def __init__(self):
        super().__init__()

        self.sampling_grid_size = 2

        self.parameters.world['Background Color'] = GLUniform(
            -1, GL_FLOAT_VEC4, (0.5, 0.5, 0.5, 1))
        self.parameters.scene['Line Width Max'] = GLUniform(-1, GL.GL_INT, 10)
        self.parameters.scene['Samples Grid Size Preview'] = GLUniform(
            -1, GL.GL_INT, 4)
        self.parameters.scene['Samples Grid Size Render'] = GLUniform(
            -1, GL.GL_INT, 8)
        self.parameters.scene['Samples Width'] = GLUniform(
            -1, GL.GL_FLOAT, 1.5)
        self.parameters.scene[
            'Shadow Cascades Distribution Exponent'] = GLUniform(
                -1, GL.GL_INT, 21)
        self.parameters.scene['ShadowMaps Spot Resolution'] = GLUniform(
            -1, GL.GL_INT, 2048)
        self.parameters.scene['ShadowMaps Sun Resolution'] = GLUniform(
            -1, GL.GL_INT, 2048)
        self.parameters.scene['ShadowMaps Point Resolution'] = GLUniform(
            -1, GL.GL_INT, 2048)

        self.common_buffer = Common.CommonBuffer()
        self.lights_buffer = Lighting.LightsBuffer()

        self.line_rendering = Line.LineRendering()

        self.composite_depth = DepthToCompositeDepth.CompositeDepth()

    def compile_material_from_source(self, source, include_paths=[]):
        source = _NPR_Pipeline_Common + source
        return {
            'PRE_PASS':
            self.compile_shader_from_source(source, 'COMMON_VERTEX_SHADER',
                                            'PRE_PASS_PIXEL_SHADER',
                                            include_paths, ['PRE_PASS']),
            'MAIN_PASS':
            self.compile_shader_from_source(source, 'COMMON_VERTEX_SHADER',
                                            'MAIN_PASS_PIXEL_SHADER',
                                            include_paths, ['MAIN_PASS'])
        }

    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_main_color = Texture(resolution, GL_RGB32F)
        self.t_line_color = Texture(resolution, GL_RGB32F)
        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_color_accumulate = Texture(resolution, GL_RGB32F)
        self.fbo_accumulate = RenderTarget([self.t_color_accumulate])

    def get_samples(self, width=1.0):
        return Sampling.get_RGSS_samples(self.sampling_grid_size, width)

    def do_render(self, resolution, scene, is_final_render, is_new_frame):
        #SETUP SAMPLING
        if is_final_render:
            self.sampling_grid_size = scene.parameters[
                'Samples Grid Size Render'][0]
        else:
            self.sampling_grid_size = scene.parameters[
                'Samples Grid Size Preview'][0]

        sample_offset = self.get_samples(
            scene.parameters['Samples Width'][0])[self.sample_count]

        #SETUP PER-OBJECT PARAMETERS
        for i, obj in enumerate(scene.objects):
            obj.parameters['MODEL'] = obj.matrix
            obj.parameters['ID'] = i + 1

        #SETUP UNIFORM BLOCKS
        self.common_buffer.load(scene, resolution, sample_offset,
                                self.sample_count)
        self.lights_buffer.load(
            scene, self, 'PRE_PASS',
            scene.parameters['Shadow Cascades Distribution Exponent'][0],
            scene.parameters['ShadowMaps Spot Resolution'][0],
            scene.parameters['ShadowMaps Sun Resolution'][0],
            scene.parameters['ShadowMaps Point Resolution'][0])

        UBOS = {
            'COMMON_UNIFORMS': self.common_buffer,
            'SCENE_LIGHTS': self.lights_buffer
        }

        #PRE-PASS
        self.fbo_prepass.clear([(0, 0, 1, 1), (0, 0, 0, 0)], 1, 0)
        self.draw_scene_pass(self.fbo_prepass, scene.objects, 'PRE_PASS',
                             self.default_shader['PRE_PASS'], UBOS)

        #MAIN-PASS
        textures = {
            'IN_NORMAL_DEPTH': self.t_prepass_normal_depth,
            'IN_ID': self.t_prepass_id,
        }
        callbacks = [lambda shader: self.lights_buffer.shader_callback(shader)]
        self.fbo_main.clear([
            scene.world_parameters['Background Color'], (0, 0, 0, 0),
            (-1, -1, -1, -1)
        ])
        self.draw_scene_pass(self.fbo_main, scene.objects, 'MAIN_PASS',
                             self.default_shader['MAIN_PASS'], UBOS, {},
                             textures, callbacks)

        #COMPOSITE LINE
        composited_line = self.line_rendering.composite_line(
            scene.parameters['Line Width Max'], self, self.common_buffer,
            self.t_main_color, self.t_depth, self.t_prepass_id,
            self.t_line_color, self.t_line_data)

        # TEMPORAL SUPER-SAMPLING ACCUMULATION
        self.blend_texture(composited_line, self.fbo_accumulate,
                           1.0 / (self.sample_count + 1))

        #COMPOSITE DEPTH
        composite_depth = None
        if is_final_render:
            composite_depth = self.composite_depth.render(
                self, self.common_buffer, self.t_depth)

        return {
            'COLOR': self.t_color_accumulate,
            'DEPTH': composite_depth,
        }
Beispiel #8
0
    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])
            self.t_composite = Texture(color.resolution, GL_RGBA32F)
            self.fbo_composite = RenderTarget([self.t_composite])

        if self.shader == None:
            self.shader = pipeline.compile_shader_from_source(_shader_src)
            self.cleanup_shader = pipeline.compile_shader_from_source(
                _line_cleanup_src)
            self.composite_shader = pipeline.compile_shader_from_source(
                _line_composite_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
        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)

        #LINE COMPOSITE
        self.fbo_composite.clear((0, 0, 0, 0))
        self.composite_shader.uniforms['brute_force_range'].set_value(
            math.ceil(max_width[0] / 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