MC还原广州塔灯光的设想、截至目前的所有尝试

这是25年月7日在MC里还原的广州塔灯光效果
序
我在2023年下半年在游戏中用小木斧搭建了一个2:1的广州塔,当时搭建出来后,到了夜晚少了广州塔土土的灯光就觉得没有那味,所以就开始尝试各种方法去还原灯光效果
尝试一:使用材质包的动画效果(2024年8月实现)
想必这应该是最简单粗暴的实现效果了,想要达到既能变化颜色又能在夜晚发光的效果,使用支持optifine的游戏版本和制作一个支持emissive材质包就行了

参考文章:
https://ewanhowell.com/guides/emissive-textures/
https://optifine.readthedocs.io/emissive_textures.html
https://optifine.readthedocs.io/custom_animations.html
参考支持emissive的材质包:
https://ewanhowell.com/resourcepacks/example-emissive-textures/
第一步:将一个现成的材质包删减成只剩以下目录结构
├─pack.mcmeta
├─pack.png
└─assets
├─其他模组材质目录
│ ├─optifine
│ └─textures
│ └─block
└─minecraft
├─optifine
└─textures
└─block
第二步:在 assets/minecraft/optifine 创建一个 emissive.properties 文件,保存以下内容
suffix.emissive=_e
此.properties文件会使optifine将材质包中名称以 _e 结尾的任何纹理加载为自发光纹理
第三步:创建动画纹理
- 选择16种不同方块(建议选用染色方块,刚好16种),我用的是1.20.1版本的coloredbrick模组的染色方块
- 类似水的材质,材质动画要求将所有动画帧画在同一个png图片中,垂直或竖直排列,为了复原广州塔灯效,则需要借助绘图工具绘制和导出,例如即时设计,可直接导出像素png并直接命名材质名,注意添加后缀
_e - 将材质图片放入
assets\minecraft(或其他模组名)\textures\block里面,并用python执行以下代码:
点击查看python代码
import os
import json
def create_mcmeta_files(directory):
# 遍历目录中的所有文件
for filename in os.listdir(directory):
# 检查文件名是否以'_e.png'结尾
if filename.endswith('_e.png'):
# 构建.mcmeta文件名
mcmeta_filename = filename + '.mcmeta'
mcmeta_path = os.path.join(directory, mcmeta_filename)
# 创建要写入的JSON数据
mcmeta_data = {
"ctm": {
"ctm_version": 1,
"layer": "CUTOUT",
"extra": {
"light": 12
}
},
"animation": {
"width": 1,
"height": 1,
"frametime": 4
}
}
# 将JSON数据写入文件
with open(mcmeta_path, 'w') as f:
json.dump(mcmeta_data, f, indent=4)
print(f"已创建: {mcmeta_filename}")
def main():
# 提示用户输入目录路径
directory = input("请输入目录路径: ")
# 检查目录是否存在
if not os.path.isdir(directory):
print("错误: 指定的目录不存在!")
return
# 创建.mcmeta文件
create_mcmeta_files(directory)
print("处理完成!")
if __name__ == "__main__":
main()
不足
虽然这个可以完美兼容光影且性能最好、各版本都可以使用,但是需要多种方块来达到动态颜色变化的动画效果,而且做不到像现实中广州塔各种形式的彩虹变化效果
尝试二:使用彩色光源模组
有很多模组能够在不使用光影实现在原版的彩色光源,例如Shimmer、ColoredLux等

在这里以ColoredLux为例(因为没试过用Shimmer还原)
版本:1.12.2 + forge + HammerLib12.2.58 + ColoredLux12.6.34
ColoredLux支持玩家自制Lux Pack(类似材质包)为其他模组的方块和实体绑定彩色光源效果,并且支持使用JavaScript(ES5)来控制,这就非常适合用于制作变化灯光效果了
看了下模组源码,这个模组是基于方块和实体的世界坐标来渲染光照的,那就比较容易控制哪些光源是什么颜色了
第一步:安装模组
第二步:在 1.12.2\luxpacks,即游戏目录中由ColoredLux模组自动生成的lux pack目录中,创建一个towerLight文件夹,并创建以下文件
├─icon.png
├─main.js
├─pack.json
└─scripts
icon.png 是当前lux pack的图标
pack.json 为以下内容,表示lux pack的信息,其中dependencies写了 littletiles 是因为这个尝试中,我用了littletiles这个模组还原了个2:3的广州塔,并将使用littletiles的方块作为彩色光源:
{
"api": 2,
"name": "towerLight",
"authors": [ "null" ],
"description": "",
"dependencies": [ "littletiles" ]
}
main.js 为以下内容,表示需要绑定彩色光照的方块或实体,addTileScript第一个参数表示某个模组某个注册的tile或tileentity的完整类名(若想绑定实体,需要改为addEntityScript方法,并将实体的完整类名作为第一个参数),第二个参数表示JavaScript脚本控制的文件相对路径:
function main() {
addTileScript("com.creativemd.littletiles.common.tileentity.TileEntityLittleTiles", "scripts/snow.js");
}
scripts 是一个文件夹,里面在创建一个 snow.js 文件,即可
第三步:使用JavaScript控制彩色光源
在 snow.js 文件中保存以下代码,即可实现对littletiles模组搭建的雪小方块的简单彩色光照效果(更多API请查阅源码):
点击查看代码
import com.zeitheron.hammercore.utils.color.ColorHelper;
function redColor(pos, sunAngle, aa, bb, cc) {
var phase = 600.0 * sunAngle + 0.1 * (aa * pos.x + bb * pos.y + cc * pos.z);
return Math.min(Math.max(2.0 * Math.sin(phase) + 0.5, 0.0), 1.0);
}
function greenColor(pos, sunAngle, aa, bb, cc) {
var phase = 600.0 * sunAngle - 79.9999999 + 0.1 * (aa * pos.x + bb * pos.y + cc * pos.z);
return Math.min(Math.max(2.0 * Math.sin(phase) + 0.5, 0.0), 1.0);
}
function blueColor(pos, sunAngle, aa, bb, cc) {
var phase = 600.0 * sunAngle - 39.9999999 + 0.1 * (aa * pos.x + bb * pos.y + cc * pos.z);
return Math.min(Math.max(2.0 * Math.sin(phase) + 0.5, 0.0), 1.0);
}
function light(world, poss, tileEntity) {
var bld = Light.builder().pos(poss).color(ColorHelper.multiply(0x088088, 0.5), false).radius(10).build()
var iterator = tileEntity.groups().iterator();
while (iterator.hasNext()) {
var parentTileList = iterator.next();
var tileSize = parentTileList.size();
for (var i = 0; i < tileSize; i++) {
var littleTile = parentTileList.get(i)
var blockName = littleTile.getBlock().toString();
if (blockName.indexOf("now") !== -1) {
var tileBox = littleTile.getBox();
var center = tileBox.getCenter();
var pos = {
x: bld.x + center.x / 16.0,
y: bld.y + center.y / 16.0,
z: bld.z + center.z / 16.0,
};
var time = world.getWorldTime();
var aa, bb, cc;
var MODE_COUNT = 2;
var SHOW_TIMES = 40;
var sunAngle = time / 24000;
var cyclePosition = sunAngle * SHOW_TIMES;
var currentMode = Math.floor(cyclePosition) % MODE_COUNT;
if (currentMode === 0) {
aa = 0.0;
bb = 0.0;
cc = 0.0;
} else {
aa = 2.0;
bb = -1.0;
cc = 0.0;
}
var r = redColor(pos, sunAngle, aa, bb, cc);
var g = greenColor(pos, sunAngle, aa, bb, cc);
var b = blueColor(pos, sunAngle, aa, bb, cc);
var bder = Light.builder().pos(poss).color(r, g, b, 1.0).radius(2).build();
add(bder);
}
}
}
}
不足
虽然这种方式能直接对世界坐标系中的方块或实体实现彩色光照,但是
- 在数量上如果过多就会导致性能大幅下降
- ta的光照是能透过不完整方块的,导致出现完全染色的效果
- 模组依赖性强,且作者没有更新到新版本的意愿,不利于版本迁移
- 不兼容光影
尝试三:使用支持彩色光照的光影
支持彩色光照的光影有很多,如Complementary、Photon Shaders等,文章封面的效果就是 Photon Shaders 实现的
尝试了一下,Complementary 似乎是根据屏幕位置来渲染彩色光照的,这就没办法控制不同地方的光源有不同的变化了
而 Photon Shaders 是采用 体素化 + FloodFill 来实现的彩色光照,确实是用坐标来定位彩色光源位置,但是是以玩家为原点的坐标系来定位,所以我们首先就需要变换坐标:
假设广州塔的位置是C,玩家的位置是B
在世界坐标系中,C(\(x_1\), \(y_1\), \(z_1\)),B(\(x_B\), \(y_B\), \(z_B\))
在以B为原点的坐标系(坐标轴方向与世界坐标系一致)中,C(\(x_2\), \(y_2\), \(z_2\))
那么转换公式为:
\(x_1=x_B+x_2\)
\(y_1=y_B+y_2\)
\(z_1=z_B+z_2\)
然后用 尝试二 代码中类似的方法魔改 FloodFill.glsl 就能实现了
不足
直接使用光影,在实现复原广州塔灯光效果的同时,实现游戏其他部分的光影效果,性能上比尝试二要好很多。美中不足的是彩色光照的体素空间有限制,一旦广州塔移出了以玩家为中心的体素空间,彩色光照效果就会消失,另外在穿透非完整方块的实现上欠佳。如果强制加大体素空间,性能会大幅下降
总结(以下为智谱清言生成)
| 维度 | 尝试一:材质包 | 尝试二:模组 | 尝试三:光影 |
|---|---|---|---|
| 核心技术 | OptiFine的emissive自发光材质 + 自定义动画纹理 |
Forge模组,通过Lux Pack和JavaScript为方块/实体绑定动态彩色光源 | 光影包的体素化与FloodFill算法,在着色器层面实现彩色光照 |
| 实现效果 | 方块表面发光并播放预设的颜色动画 | 在世界坐标系中精确控制每个方块/实体的光照颜色、亮度和范围,可实现复杂的逻辑动画 | 在玩家周围一定范围内渲染逼真的彩色光照,能与光影的其他效果(如阴影、水面反射)完美融合 |
| 优点 | 1. 性能最佳:对游戏性能影响极小 2. 兼容性好:兼容所有支持OptiFine的光影 3. 版本跨度大:适用于所有版本 4. 实现简单:无需编程,只需制作材质和配置文件 |
1. 控制精度高:可针对世界坐标的每一个方块进行独立控制 2. 动态逻辑强:使用JavaScript编程,可实现基于时间、位置、玩家交互等复杂逻辑的灯光秀 3. 无需光影:在不使用或无法使用光影的设备上也能实现彩色光 |
1. 视觉效果最佳:光照最真实,能与场景环境(如阴影、反射)互动,沉浸感最强 2. 性能相对较好:在有效范围内,性能优于同规模的彩色光源模组 3. 集成度高:是光影效果的一部分,无需额外为灯光本身安装功能性模组 |
| 缺点 | 1. 动画模式单一:无法实现复杂的、有逻辑的渐变或彩虹效果 2. 资源消耗大:占用大量方块,对建筑结构有要求 3. “假”光源:仅方块自身发光,不会照亮周围环境 |
1. 性能瓶颈明显:当光源数量巨大时(如整个广州塔),会导致帧数急剧下降 2. 光影不兼容:与大多数光影包冲突,无法同时使用 3. 版本依赖性强:模组作者更新慢,难以迁移到新版本 4. 光照穿透问题:光线会穿透非完整方块,导致“染色”效果不真实 |
1. 范围限制:光照效果受限于以玩家为中心的体素空间,距离过远或塔身过高时效果会消失 2. 穿透问题欠佳:在处理非完整方块时,光照效果不能穿透 4. 硬件要求高:对显卡性能有较高要求 |
未来进一步实现的设想
针对每种尝试的不足,未来可以从以下几个方面进行深化和优化:
尝试一:使用材质包的动画效果
- 设想一:结合数据包与命令方块
- 思路:虽然材质包本身的动画是固定的,但可以利用游戏内的
/execute和/data命令,结合tick函数的数据包,在游戏运行时动态更换广州塔的方块。例如,预先制作好对应不同颜色帧的多个结构方块(NBT文件),然后通过命令按顺序、按位置加载这些结构,从而实现宏观上的动态变化 - 优势:可以突破材质包动画的单一性,实现更复杂的、有逻辑的灯光模式切换(如节日模式、日常模式、彩虹模式等)
- 挑战:命令执行和结构加载对性能有一定压力,且实现过程较为繁琐,需要精确的坐标计算和时序控制
- 思路:虽然材质包本身的动画是固定的,但可以利用游戏内的
- 设想二:利用更高级的材质包特性
- 思路:深入研究OptiFine的自定义物品模型或实体模型特性,或许可以将整个广州塔的灯光部分做成一个巨大的、由多个部分组成的“实体”或“物品”,然后利用材质包的条件渲染(如基于游戏时间、天气、玩家所在生物群系)来切换其显示的纹理,实现更智能的灯光变化
- 优势:理论上可以实现比方块动画更复杂的逻辑,且对游戏世界的影响更小
- 挑战:技术实现非常复杂,文档和案例较少,需要大量的试错和探索
尝试二:使用彩色光源模组
- 设想一:性能优化与光源分组
- 思路:针对性能问题,可以在JavaScript脚本中进行优化。例如,将塔上功能相似、位置相近的多个小方块“合并”为一个虚拟的、范围更大的光源进行计算和渲染,而不是为每一个小方块都创建一个光源。通过空间分区算法(如四叉树、八叉树)来管理光源,只计算和渲染玩家视野内或一定距离内的光源
- 优势:能显著降低同时渲染的光源数量,大幅提升性能
- 挑战:需要深厚的编程功底和对模组API的深入理解,实现复杂的空间管理和逻辑简化
- 设想二:开发或寻找现代版的替代模组
- 思路:鉴于
ColoredLux等模组更新慢,可以尝试在Fabric或更高版本的Forge上寻找或自己开发一个功能类似的现代模组。新的模组可以利用更现代的渲染API(如Vulkan、OpenGL的更高版本特性),从底层优化渲染效率,并解决光照穿透问题 - 优势:一劳永逸地解决版本兼容性问题,并有可能从根本上提升性能和效果
- 挑战:开发一个功能完善的模组工作量巨大,需要专业的模组开发知识
- 思路:鉴于
尝试三:使用支持彩色光照的光影
- 设想一:动态调整体素空间
- 思路:修改光影的源代码,使其体素空间不再是固定的以玩家为中心的立方体,而是可以动态调整的。例如,可以设置一个“焦点”坐标(即广州塔的基座坐标),让体素空间始终围绕这个焦点生成和计算,或者根据玩家与焦点建筑的距离动态缩放体素空间的大小
- 优势:彻底解决因距离过远导致灯光消失的问题,确保无论玩家在哪个角度观看,广州塔的灯光效果都是完整的
- 挑战:需要对光影渲染管线有极深的理解,修改核心算法非常困难,且可能带来新的性能问题
- 设想二:混合渲染方案
- 思路:将“尝试一”和“尝试三”结合。在光影中,只处理广州塔轮廓上关键节点的、大范围的彩色光源(用于照亮环境和产生氛围)。而塔身细节上的、密集的灯光变化,则通过
emissive自发光材质来实现。这样,光影负责“照亮世界”,材质包负责“点亮塔身” - 优势:兼顾了性能与效果。光影的计算量不会因为细节光源过多而爆炸,同时材质包的
emissive材质可以完美展现细节动画,且不受体素空间限制 - 挑战:需要精心设计和协调两种光源的亮度、颜色和范围,避免视觉冲突或效果叠加不当。这更像是一种艺术和技术的平衡,而非纯技术实现
综上所述,每种方法都有其独特的价值和改进空间。未来的实现可以不再是单一路径的极致追求,而是根据实际需求,将不同方法的优势结合起来,创造出性能、效果和兼容性俱佳的最终方案
- 思路:将“尝试一”和“尝试三”结合。在光影中,只处理广州塔轮廓上关键节点的、大范围的彩色光源(用于照亮环境和产生氛围)。而塔身细节上的、密集的灯光变化,则通过

浙公网安备 33010602011771号