Ejemplo n.º 1
0
Archivo: Common.py Proyecto: bnpr/Malt
class CommonBuffer():
    def __init__(self):
        self.data = C_CommonBuffer()
        self.UBO = UBO()

    def load(self,
             scene,
             resolution,
             sample_offset=(0, 0),
             sample_count=0,
             camera=None,
             projection=None):
        self.data.CAMERA = tuple(
            camera if camera else scene.camera.camera_matrix)
        self.data.PROJECTION = tuple(
            projection if projection else scene.camera.projection_matrix)
        self.data.RESOLUTION = resolution
        self.data.SAMPLE_OFFSET = sample_offset
        self.data.SAMPLE_COUNT = sample_count
        self.data.FRAME = scene.frame
        self.data.TIME = scene.time

        self.UBO.load_data(self.data)

    def bind(self, block):
        self.UBO.bind(block)

    def shader_callback(self, shader):
        if 'COMMON_UNIFORMS' in shader.uniform_blocks:
            self.bind(shader.uniform_blocks['COMMON_UNIFORMS'])
Ejemplo n.º 2
0
class NPR_LightShaders():
    def __init__(self):
        class C_NPR_LightShadersBuffer(ctypes.Structure):
            _fields_ = [
                ('custom_shading_index', ctypes.c_int * Lighting.MAX_LIGHTS),
            ]

        self.data = C_NPR_LightShadersBuffer()
        self.custom_shading_count = 0
        self.UBO = UBO()

        self.texture = None
        self.fbos = None

    def load(self, pipeline, depth_texture, scene):
        self.custom_shading_count = 0
        for i, light in enumerate(scene.lights):
            custom_shading_index = -1
            if light.parameters['Shader'] is not None:
                custom_shading_index = self.custom_shading_count
                self.custom_shading_count += 1
            self.data.custom_shading_index[i] = custom_shading_index

        self.UBO.load_data(self.data)

        if self.custom_shading_count == 0:
            return

        lights = [
            l for l in scene.lights if l.parameters['Shader'] is not None
        ]
        tex = self.texture
        if tex is None or tex.resolution != depth_texture.resolution or tex.length < len(
                lights):
            self.texture = TextureArray(depth_texture.resolution, len(lights),
                                        GL_RGB32F)
            self.fbos = []
            for i in range(len(lights)):
                self.fbos.append(
                    RenderTarget([ArrayLayerTarget(self.texture, i)]))

        for i, light in enumerate(lights):
            material = light.parameters['Shader']
            if material.shader and 'SHADER' in material.shader.keys():
                shader = material.shader['SHADER']
                for resource in scene.shader_resources:
                    resource.shader_callback(shader)
                shader.textures['IN_DEPTH'] = depth_texture
                if 'LIGHT_INDEX' in shader.uniforms:
                    light_index = scene.lights.index(light)
                    shader.uniforms['LIGHT_INDEX'].set_value(light_index)
                pipeline.draw_screen_pass(shader, self.fbos[i])

    def shader_callback(self, shader):
        if 'LIGHTS_CUSTOM_SHADING' in shader.uniform_blocks:
            self.UBO.bind(shader.uniform_blocks['LIGHTS_CUSTOM_SHADING'])
        shader.textures['IN_LIGHT_CUSTOM_SHADING'] = self.texture
Ejemplo n.º 3
0
class NPR_LightShaders(object):
    def __init__(self):
        self.data = C_NPR_LightShadersBuffer()
        self.custom_shading_count = 0
        self.UBO = UBO()

        self.texture = None
        self.fbos = None

    def load(self, pipeline, depth_texture, scene):
        self.custom_shading_count = 0
        for i, light in enumerate(scene.lights):
            custom_shading_index = -1
            if light.parameters['Shader'] is not None:
                custom_shading_index = self.custom_shading_count
                self.custom_shading_count += 1
            self.data.custom_shading_index[i] = custom_shading_index

        self.UBO.load_data(self.data)

        if self.custom_shading_count == 0:
            return

        lights = [
            l for l in scene.lights if l.parameters['Shader'] is not None
        ]
        tex = self.texture
        if tex is None or tex.resolution != depth_texture.resolution or tex.length < len(
                lights):
            self.texture = TextureArray(depth_texture.resolution, len(lights),
                                        GL_RGB32F)
            self.fbos = []
            for i in range(len(lights)):
                self.fbos.append(
                    RenderTarget([ArrayLayerTarget(self.texture, i)]))

        for i, light in enumerate(lights):
            shader = light.parameters['Shader']['SHADER']
            pipeline.common_buffer.bind(
                shader.uniform_blocks['COMMON_UNIFORMS'])
            pipeline.lights_buffer.bind(shader.uniform_blocks['SCENE_LIGHTS'])
            shader.textures['IN_DEPTH'] = depth_texture
            if 'LIGHT_INDEX' in shader.uniforms:
                shader.uniforms['LIGHT_INDEX'].set_value(i)
            pipeline.draw_screen_pass(shader, self.fbos[i])

    def shader_callback(self, shader):
        if 'LIGHTS_CUSTOM_SHADING' in shader.uniform_blocks:
            self.UBO.bind(shader.uniform_blocks['LIGHTS_CUSTOM_SHADING'])
        shader.textures['IN_LIGHT_CUSTOM_SHADING'] = self.texture
Ejemplo n.º 4
0
class CommonBuffer(object):
    
    def __init__(self):
        self.data = C_CommonBuffer()
        self.UBO = UBO()
    
    def load(self, scene, resolution, sample_offset=(0,0), sample_count=0, camera=None, projection = None):
        self.data.CAMERA = tuple(camera if camera else scene.camera.camera_matrix)
        self.data.PROJECTION = tuple(projection if projection else scene.camera.projection_matrix)
        self.data.RESOLUTION = resolution
        self.data.SAMPLE_OFFSET = sample_offset
        self.data.SAMPLE_COUNT = sample_count
        self.data.FRAME = scene.frame
        self.data.TIME = scene.time

        self.UBO.load_data(self.data)
    
    def bind(self, location):
        self.UBO.bind(location)
Ejemplo n.º 5
0
class NPR_LightsGroupsBuffer(object):
    def __init__(self):
        self.data = C_NPR_LightGroupsBuffer()
        self.UBO = UBO()

    def load(self, scene):
        for i, light in enumerate(scene.lights):
            self.data.light_group_index[i] = light.parameters['Light Group']

        self.UBO.load_data(self.data)

        for material in scene.materials:
            for shader in material.shader.values():
                if 'MATERIAL_LIGHT_GROUPS' in shader.uniforms.keys():
                    shader.uniforms['MATERIAL_LIGHT_GROUPS'].set_value(
                        material.parameters['Light Groups.Light'])

    def shader_callback(self, shader):
        if 'LIGHT_GROUPS' in shader.uniform_blocks:
            self.UBO.bind(shader.uniform_blocks['LIGHT_GROUPS'])
Ejemplo n.º 6
0
class NPR_LightsGroupsBuffer():

    def __init__(self):
        class C_NPR_LightGroupsBuffer(ctypes.Structure):
            _fields_ = [
                ('light_group_index', ctypes.c_int*Lighting.MAX_LIGHTS),
            ]
        self.data = C_NPR_LightGroupsBuffer()
        self.UBO = UBO()
    
    def load(self, scene):
        for i, light in enumerate(scene.lights):
            self.data.light_group_index[i] = light.parameters['Light Group']

        self.UBO.load_data(self.data)

        for material in scene.batches.keys():
            for shader in material.shader.values():
                if 'MATERIAL_LIGHT_GROUPS' in shader.uniforms.keys():
                    shader.uniforms['MATERIAL_LIGHT_GROUPS'].set_value(material.parameters['Light Groups.Light'])

    def shader_callback(self, shader):
        if 'LIGHT_GROUPS' in shader.uniform_blocks:
            self.UBO.bind(shader.uniform_blocks['LIGHT_GROUPS'])    
Ejemplo n.º 7
0
class LightsBuffer(object):
    def __init__(self):
        self.data = C_LightsBuffer()
        self.UBO = UBO()
        self.spots = None
        self.suns = None
        self.points = None

    def load(self,
             scene,
             cascades_count,
             cascades_distribution_scalar,
             cascades_max_distance=1.0):
        #TODO: Automatic distribution exponent basedd on FOV

        spot_count = 0
        sun_count = 0
        point_count = 0

        from collections import OrderedDict

        self.spots = OrderedDict()
        self.suns = OrderedDict()
        self.points = OrderedDict()

        for i, light in enumerate(scene.lights):
            self.data.lights[i].color = light.color
            self.data.lights[i].type = light.type
            self.data.lights[i].position = light.position
            self.data.lights[i].radius = light.radius
            self.data.lights[i].direction = light.direction
            self.data.lights[i].spot_angle = light.spot_angle
            self.data.lights[i].spot_blend = light.spot_blend

            if light.type == LIGHT_SPOT:
                self.data.lights[i].type_index = spot_count

                projection_matrix = make_projection_matrix(
                    light.spot_angle, 1, 0.01, light.radius)
                spot_matrix = projection_matrix * pyrr.Matrix44(light.matrix)

                self.data.spot_matrices[spot_count] = flatten_matrix(
                    spot_matrix)

                self.spots[light] = [(light.matrix,
                                      flatten_matrix(projection_matrix))]

                spot_count += 1

            if light.type == LIGHT_SUN:
                self.data.lights[i].type_index = sun_count

                sun_matrix = pyrr.Matrix44(light.matrix)
                projection_matrix = pyrr.Matrix44(
                    scene.camera.projection_matrix)
                view_matrix = projection_matrix * pyrr.Matrix44(
                    scene.camera.camera_matrix)

                cascades_matrices = get_sun_cascades(
                    sun_matrix, projection_matrix, view_matrix, cascades_count,
                    cascades_distribution_scalar, cascades_max_distance)

                self.suns[light] = []
                for i, cascade in enumerate(cascades_matrices):
                    cascade = flatten_matrix(cascade)
                    self.data.sun_matrices[sun_count * cascades_count +
                                           i] = cascade

                    self.suns[light].append(
                        (cascade, flatten_matrix(pyrr.Matrix44.identity())))

                sun_count += 1

            if light.type == LIGHT_POINT:
                self.data.lights[i].type_index = point_count

                cube_map_axes = [((1, 0, 0), (0, -1, 0)),
                                 ((-1, 0, 0), (0, -1, 0)),
                                 ((0, 1, 0), (0, 0, 1)),
                                 ((0, -1, 0), (0, 0, -1)),
                                 ((0, 0, 1), (0, -1, 0)),
                                 ((0, 0, -1), (0, -1, 0))]
                matrices = []
                for axes in cube_map_axes:
                    position = pyrr.Vector3(light.position)
                    front = pyrr.Vector3(axes[0])
                    up = pyrr.Vector3(axes[1])
                    matrices.append(
                        pyrr.Matrix44.look_at(position, position + front, up))

                projection_matrix = make_projection_matrix(
                    math.pi / 2.0, 1.0, 0.01, light.radius)

                self.points[light] = []
                for i in range(6):
                    self.points[light].append(
                        (flatten_matrix(matrices[i]),
                         flatten_matrix(projection_matrix)))

                point_count += 1

        self.data.lights_count = len(scene.lights)
        self.data.cascades_count = cascades_count

        self.UBO.load_data(self.data)

    def bind(self, location):
        self.UBO.bind(location)