
ursina 并未提供完整的物理光照系统(如点光源衰减、多光源混合或实时阴影),官网示例中的“灯光”实为通过 projector_shader 实现的纹理投射效果,本质是视觉欺骗而非真实光照计算。
ursina 并未提供完整的物理光照系统(如点光源衰减、多光源混合或实时阴影),官网示例中的“灯光”实为通过 projector_shader 实现的纹理投射效果,本质是视觉欺骗而非真实光照计算。
Ursina 是一个面向教育与快速原型开发的 Python 3D 引擎,其设计哲学强调简洁性与易用性,因此并未内置传统游戏引擎级别的光照管线(如 Phong/Blinn-Phong 模型、PBR 渲染、阴影映射 Shadow Mapping 或多光源动态混合)。这一点常被初学者误解——尤其当看到官网首页那张带有柔和光斑与明暗过渡的截图时,容易误以为 Ursina 支持高级光照。
实际上,该效果源自 ursina/shaders/projector_shader.py 中的 projector_shader:它并非光照计算,而是一种纹理投影(Texture Projection)技术。其核心逻辑是将一张预设的“光效纹理”(如中心亮、边缘渐暗的 vignette 图)按世界坐标或屏幕空间方式投射到场景模型表面,从而模拟聚光灯或环境光晕的视觉感受。
以下是一个最小可运行示例,展示如何使用该着色器模拟“地面聚光”效果:
from ursina import *
from ursina.shaders import projector_shader
app = Ursina()
# 创建基础场景
ground = Entity(model='plane', scale=(20, 1, 20), texture='white_cube', collider='box')
for i in range(5):
Entity(model='cube', position=(random.uniform(-8,8), 1, random.uniform(-8,8)),
scale=(1.5,1.5,1.5), texture='brick')
# 创建“投影器”实体(仅作位置/方向参考,不渲染)
projector = Entity(parent=scene, position=(0, 5, 0), rotation_x=-90)
# 应用 projector_shader 到地面,并绑定投影器
ground.shader = projector_shader
ground.set_shader_input('projector', projector)
ground.set_shader_input('texture', 'vignette') # 内置 vignette 纹理(中心亮,四周暗)
# 可选:添加一个发光球体增强视觉提示
light_indicator = Entity(model='sphere', color=color.yellow, scale=.3, position=projector.position, always_on_top=True)
EditorCamera()
app.run()? 关键说明与注意事项:
- ✅ projector_shader 仅影响指定 Entity 的表面着色,需显式调用 .shader 和 .set_shader_input();
- ❌ 它不产生真实阴影,也不影响其他物体的明暗(即无全局光照传播);
- ❌ 无距离衰减、无角度衰减、无法线响应——亮度完全由投影纹理与 UV 映射决定;
- ⚠️ 若需更真实的光照,目前需自行集成 GLSL 片段着色器(如实现简单 Lambert 光照),或切换至支持完整光照管线的引擎(如 Panda3D + PBR 插件、Godot 或 Unity);
- ? Ursina 的 DirectionalLight 是唯一支持基础阴影的光源(需启用 shadow_map_resolution 和 cast_shadows=True),但仅限方向光,且阴影质量受限于默认 shadow map 分辨率(建议设为 2048 或更高)。
总结而言,Ursina 的“光照”应理解为面向表现力的视觉工具集,而非物理仿真系统。合理利用 projector_shader、unlit_shader、自定义着色器及后期处理(如 BlurShader),配合精心设计的纹理与动画,依然能高效构建富有氛围感的 3D 体验——前提是明确其能力边界,避免在不可行的方向上过度调试。










