Пример #1
0
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'])
Пример #2
0
    def __init__(self):
        self.data = C_NPR_LightShadersBuffer()
        self.custom_shading_count = 0
        self.UBO = UBO()

        self.texture = None
        self.fbos = None
Пример #3
0
 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()
Пример #4
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
Пример #5
0
    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
Пример #6
0
    def build_scene_batches(self, objects):
        result = {}
        for obj in objects:
            if obj.material not in result:
                result[obj.material] = {}
            if obj.mesh not in result[obj.material]:
                result[obj.material][obj.mesh] = {}
            mesh_dict = result[obj.material][obj.mesh]
            if obj.mirror_scale:
                if 'mirror_scale' not in mesh_dict:
                    mesh_dict['mirror_scale'] = []
                mesh_dict['mirror_scale'].append(obj)
            else:
                if 'normal_scale' not in mesh_dict:
                    mesh_dict['normal_scale'] = []
                mesh_dict['normal_scale'].append(obj)

        # Assume at least 64kb of UBO storage (d3d11 requirement) and max element size of mat4
        max_instances = 1000
        models = (max_instances * (ctypes.c_float * 16))()
        ids = (max_instances * ctypes.c_uint)()

        for material, meshes in result.items():
            for mesh, scale_groups in meshes.items():
                for scale_group, objs in scale_groups.items():
                    batches = []
                    scale_groups[scale_group] = batches

                    i = 0
                    batch_length = len(objs)

                    while i < batch_length:
                        instance_i = i % max_instances
                        models[instance_i] = objs[i].matrix
                        ids[instance_i] = objs[i].parameters['ID']

                        i += 1
                        instances_count = instance_i + 1

                        if i == batch_length or instances_count == max_instances:
                            local_models = ((ctypes.c_float * 16) *
                                            instances_count).from_address(
                                                ctypes.addressof(models))
                            local_ids = (ctypes.c_uint *
                                         instances_count).from_address(
                                             ctypes.addressof(ids))

                            models_UBO = UBO()
                            ids_UBO = UBO()

                            models_UBO.load_data(local_models)
                            ids_UBO.load_data(local_ids)

                            batches.append({
                                'instances_count': instances_count,
                                'BATCH_MODELS': models_UBO,
                                'BATCH_IDS': ids_UBO,
                            })

        return result
Пример #7
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
Пример #8
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)
Пример #9
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'])
Пример #10
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'])    
Пример #11
0
 def __init__(self):
     self.data = C_NPR_LightGroupsBuffer()
     self.UBO = UBO()
Пример #12
0
 def __init__(self):
     self.data = C_LightsBuffer()
     self.UBO = UBO()
     self.spots = None
     self.suns = None
     self.points = None
Пример #13
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)
Пример #14
0
 def __init__(self):
     self.data = C_LightsBuffer()
     self.UBO = UBO()
     self.spot_matrices = []
     self.sun_matrices = []
     self.point_matrices = []
Пример #15
0
 def __init__(self):
     self.data = C_CommonBuffer()
     self.UBO = UBO()