Shuvit game master repo. http://shuvit.org
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

custom_shader_utils.py 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. from bge import logic
  2. from math import radians, cos
  3. # Helper functions:
  4. def get_material(object, name):
  5. """Return a object material."""
  6. for mesh in object.meshes:
  7. for mat in mesh.materials:
  8. if str(mat) == "MA" + name:
  9. return mat
  10. def get_view_matrix(camera):
  11. """Return view matrix."""
  12. view_mat = camera.worldTransform
  13. view_mat_inv = view_mat.inverted()
  14. return view_mat_inv
  15. def _lights_transform_handler():
  16. """Update position and orientation properties."""
  17. scene = logic.getCurrentScene()
  18. view = get_view_matrix(scene.active_camera)
  19. for light in scene.lights:
  20. transform = light.worldTransform
  21. light['_position'] = (view * light.position)
  22. light['_orientation'] = (view * -(transform.col[2].normalized()))
  23. LIGHTS_HANDLER = _lights_transform_handler
  24. LIGHT_TYPES = {'SPOT':0, 'SUN':1, 'POINT':2, 'HEMI':3}
  25. # Light uniforms:
  26. def update_light_transform(shader, scene, names=["lightPosition", "lightOrientation"]):
  27. """Update uniforms for light position and orientation."""
  28. if not LIGHTS_HANDLER in scene.pre_draw:
  29. LIGHTS_HANDLER()
  30. scene.pre_draw.append(LIGHTS_HANDLER)
  31. for i, light in enumerate(scene.lights, 0):
  32. shader.setUniform3f(names[0] + "[%s]"%i, *light['_position'])
  33. shader.setUniform3f(names[1] + "[%s]"%i, *light['_orientation'].xyz)
  34. def update_light_settings(shader, scene, names=["lightType", "lightDistance", "lightColor", "lightSpotsize", "lightSpotblend", "lightCount"]):
  35. """Update uniforms for light settings."""
  36. for i, light in enumerate(scene.lights, 0):
  37. if 'type' in light:
  38. # Lighttype must set manually via property ('SPOT', 'SUN', 'POINT', 'HEMI') because hemi lamps can't be detected ingame.
  39. shader.setUniform1i(names[0] + "[%s]"%i, LIGHT_TYPES[light['type']])
  40. else:
  41. # Upbge can detect all light types without property.
  42. shader.setUniform1i(names[0] + "[%s]"%i, light.type)
  43. shader.setUniform1f(names[1] + "[%s]"%i, light.distance)
  44. color = light.color
  45. energy = light.energy
  46. shader.setUniform3f(names[2] + "[%s]"%i, color[0] * energy, color[1] * energy, color[2] * energy)
  47. spotsize = cos(radians(light.spotsize) * 0.5)
  48. shader.setUniform1f(names[3] + "[%s]"%i, spotsize)
  49. spotblend = (1.0 - spotsize) * light.spotblend
  50. shader.setUniform1f(names[4] + "[%s]"%i, spotblend)
  51. shader.setUniform1i(names[5], i+1)
  52. # World uniforms:
  53. def update_ambient_color(shader, scene, name="ambientColor"):
  54. """Update uniform for ambient color."""
  55. shader.setUniform3f(name, *scene.world.ambientColor)
  56. def update_mist(shader, scene, names=["mistEnable", "mistStart", "mistDistance", "mistIntensity", "mistType", "mistColor"]):
  57. """Update uniforms for mist."""
  58. shader.setUniform1f(names[0], scene.world.mistEnable)
  59. shader.setUniform1f(names[1], scene.world.mistStart)
  60. shader.setUniform1f(names[2], scene.world.mistDistance)
  61. shader.setUniform1f(names[3], scene.world.mistIntensity)
  62. shader.setUniform1f(names[4], scene.world.mistType)
  63. shader.setUniform3f(names[5], *scene.world.mistColor)
  64. def update_world(shader, scene, names=["ambientColor", "mistEnable", "mistStart", "mistDistance", "mistIntensity", "mistType", "mistColor"]):
  65. """Update uniforms for world settings"""
  66. update_ambient_color(shader, scene, name=names[0])
  67. update_mist(shader, scene, names=[names[1], names[2], names[3], names[4], names[5], names[6]])
  68. # Material uniforms:
  69. def update_material(shader, material, names=["diffuseColor", "specularColor", "hardness", "emit"]):
  70. """Update uniforms for material settings."""
  71. update_diffuse_color(shader, material, name=names[0])
  72. update_specular(shader, material, names=[names[1], names[2]])
  73. update_emit(shader, material, name=names[3])
  74. def update_diffuse_color(shader, material, name="diffuseColor"):
  75. """Update uniform for diffuse color."""
  76. shader.setUniform3f(name, *material.diffuseColor * material.diffuseIntensity)
  77. def update_specular(shader, material, names=["specularColor", "hardness"]):
  78. """Update uniforms for specular."""
  79. update_specular_color(shader, material, name=names[0])
  80. update_specular_hardness(shader, material, name=names[1])
  81. def update_specular_color(shader, material, name="specularColor"):
  82. """Update uniform for specular color."""
  83. shader.setUniform3f(name, *material.specularColor * material.specularIntensity)
  84. def update_specular_hardness(shader, material, name="hardness"):
  85. """Update uniform for specular hardness."""
  86. shader.setUniform1f(name, material.hardness*4)#Blender returns wrong value (bug)
  87. def update_emission(shader, material, name="emission"):
  88. """Update uniform for emit."""
  89. shader.setUniform1f(name, material.emit)