from bge import logic from math import radians, cos # Helper functions: def get_material(object, name): """Return a object material.""" for mesh in object.meshes: for mat in mesh.materials: if str(mat) == "MA" + name: return mat def get_view_matrix(camera): """Return view matrix.""" view_mat = camera.worldTransform view_mat_inv = view_mat.inverted() return view_mat_inv def _lights_transform_handler(): """Update position and orientation properties.""" scene = logic.getCurrentScene() view = get_view_matrix(scene.active_camera) for light in scene.lights: transform = light.worldTransform light['_position'] = (view * light.position) light['_orientation'] = (view * -(transform.col[2].normalized())) LIGHTS_HANDLER = _lights_transform_handler LIGHT_TYPES = {'SPOT':0, 'SUN':1, 'POINT':2, 'HEMI':3} # Light uniforms: def update_light_transform(shader, scene, names=["lightPosition", "lightOrientation"]): """Update uniforms for light position and orientation.""" if not LIGHTS_HANDLER in scene.pre_draw: LIGHTS_HANDLER() scene.pre_draw.append(LIGHTS_HANDLER) for i, light in enumerate(scene.lights, 0): shader.setUniform3f(names[0] + "[%s]"%i, *light['_position']) shader.setUniform3f(names[1] + "[%s]"%i, *light['_orientation'].xyz) def update_light_settings(shader, scene, names=["lightType", "lightDistance", "lightColor", "lightSpotsize", "lightSpotblend", "lightCount"]): """Update uniforms for light settings.""" for i, light in enumerate(scene.lights, 0): if 'type' in light: # Lighttype must set manually via property ('SPOT', 'SUN', 'POINT', 'HEMI') because hemi lamps can't be detected ingame. shader.setUniform1i(names[0] + "[%s]"%i, LIGHT_TYPES[light['type']]) else: # Upbge can detect all light types without property. shader.setUniform1i(names[0] + "[%s]"%i, light.type) shader.setUniform1f(names[1] + "[%s]"%i, light.distance) color = light.color energy = light.energy / 2 shader.setUniform3f(names[2] + "[%s]"%i, color[0] * energy, color[1] * energy, color[2] * energy) spotsize = cos(radians(light.spotsize) * 0.5) shader.setUniform1f(names[3] + "[%s]"%i, spotsize) spotblend = (1.0 - spotsize) * light.spotblend shader.setUniform1f(names[4] + "[%s]"%i, spotblend) shader.setUniform1i(names[5], i+1) # World uniforms: def update_ambient_color(shader, scene, name="ambientColor"): """Update uniform for ambient color.""" shader.setUniform3f(name, *scene.world.ambientColor) def update_mist(shader, scene, names=["mistEnable", "mistStart", "mistDistance", "mistIntensity", "mistType", "mistColor"]): """Update uniforms for mist.""" shader.setUniform1f(names[0], scene.world.mistEnable) shader.setUniform1f(names[1], scene.world.mistStart) shader.setUniform1f(names[2], scene.world.mistDistance) shader.setUniform1f(names[3], scene.world.mistIntensity) shader.setUniform1f(names[4], scene.world.mistType) shader.setUniform3f(names[5], *scene.world.mistColor) def update_world(shader, scene, names=["ambientColor", "mistEnable", "mistStart", "mistDistance", "mistIntensity", "mistType", "mistColor"]): """Update uniforms for world settings""" update_ambient_color(shader, scene, name=names[0]) update_mist(shader, scene, names=[names[1], names[2], names[3], names[4], names[5], names[6]]) # Material uniforms: def update_material(shader, material, names=["diffuseColor", "specularColor", "hardness", "emit"]): """Update uniforms for material settings.""" update_diffuse_color(shader, material, name=names[0]) update_specular(shader, material, names=[names[1], names[2]]) update_emit(shader, material, name=names[3]) def update_diffuse_color(shader, material, name="diffuseColor"): """Update uniform for diffuse color.""" shader.setUniform3f(name, *material.diffuseColor * material.diffuseIntensity) def update_specular(shader, material, names=["specularColor", "hardness"]): """Update uniforms for specular.""" update_specular_color(shader, material, name=names[0]) update_specular_hardness(shader, material, name=names[1]) def update_specular_color(shader, material, name="specularColor"): """Update uniform for specular color.""" shader.setUniform3f(name, *material.specularColor * material.specularIntensity) def update_specular_hardness(shader, material, name="hardness"): """Update uniform for specular hardness.""" shader.setUniform1f(name, material.hardness*4)#Blender returns wrong value (bug) def update_emission(shader, material, name="emission"): """Update uniform for emit.""" shader.setUniform1f(name, material.emit)