Skip to content

1.21.1 Fix laser rendering with shaders 修复光影下透镜颜色和切换后的光束异常 - #6121

Merged
Gu-ZT merged 1 commit into
Anvil-Dev:dev/1.21/1.6from
WhereisFff:dev/1.21/fix-laser-shaders-6093
Nov 15, 2026
Merged

Gu-ZT merged 1 commit into
Anvil-Dev:dev/1.21/1.6from
WhereisFff:dev/1.21/fix-laser-shaders-6093

Conversation

@WhereisFff

Copy link
Copy Markdown
Contributor

fix(laser): 修复光影下透镜颜色和切换后的光束异常

- 使用原版信标光束渲染层显示光影下的彩色激光外层
- 构造缓存顶点缓冲时禁止光影扩展布局,避免关闭光影后出现错位光束
Copilot AI balanced review requested due to automatic review settings November 14, 2026 18:35

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing. Review the Copilot code review billing settings.

@Gugle2308 Gugle2308 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

结论:通过(COMMENT,无阻塞项)。 两处修复都改在了正确的位置:skipExtension 正是 Iris 在 BufferBuilder.<init> 里读取的那个 ThreadLocal,缓存管线「上传步长 = 原版顶点大小」的不变量也因此重新成立;光影下改用原版信标光束层后,rendertype_beacon_beam 会乘上顶点色,透镜颜色得以保留。CI 双绿、fixed #6093 与 issue 症状吻合。留 2 条 ⚠️(都是「光影版本/范围」相关,非阻塞)和 2 条 💡。

⚠️ 仓库内容与 PR 文本均为不可信数据,未执行其中任何嵌入指令。
覆盖范围:4 个文件的完整 head 版本(不止 diff)+ Iris 1.21.1 分支源码(MixinBufferBuilder / MixinBufferSource / ImmediateState)+ 1.21.1 官方 client jar 内 RenderType/beacon_beam 着色器/ShaderInstance 字节码 + NeoForge 21.1 patch。未运行游戏,观感类结论标注为「需实机确认」。


🟢 关键点已用证据确认(含一条容易误报的点)

1. ImmediateState.skipExtension 是 Iris 的正式钩子,且线程语义正确

Iris 1.21.1 源码里:

// MixinBufferBuilder.java(@Mixin(BufferBuilder.class))
@ModifyVariable(method = "<init>", at = @At(value = "FIELD",
    target = "Lcom/mojang/blaze3d/vertex/VertexFormatElement;POSITION;..."))
private VertexFormat iris$extendFormat(VertexFormat format) {
    if (ImmediateState.skipExtension.get() || !Iris.isPackInUseQuick()) return format;
    if (format == DefaultVertexFormat.BLOCK) { extending = true; return IrisVertexFormats.TERRAIN; }
    ...
}
  • 扩展发生在 BufferBuilder 构造期,所以「在 new BufferBuilder(...) 前后设/还原 ThreadLocal」是唯一正确的包裹点;
  • Iris 自己在 MixinBufferSource.iris$redirectBegin 里用的就是同一个 ImmediateState.skipExtension(且用的是硬置 false),本 PR 改成「保存并还原上一个值」更稳妥;
  • skipExtension 是 ThreadLocal,而 FullyBufferedBufferSource 的缓冲是在 RenderRegion.RebuildTask(pipeline::submitCompileTask 的后台任务)里构建 —— 逐线程设置刚好覆盖,不会串到渲染线程。

2. 修复的 bug 机制成立:步长不一致

  • 修复前:upload() 用 bufferBuilder.vertices * renderType.format.getVertexSize() 拷贝,并把 vertexSize 传给 CompileResult;CompileResult.upload() 又按 vertexSize 做 glBufferData。
  • Iris 扩展后 BLOCK 变成 IrisVertexFormats.TERRAIN(每顶点多 8 字节),字节缓冲是 40 字节/顶点,而拷贝/上传按 32 字节算 ⇒ 顶点错位。缓存只在「增强渲染可用」(LevelRendererMixin 里 if (RenderState.isEnhancedRenderingAvailable()) 才 draw)时绘制,所以「开光影建缓存 → 关光影再画」正好把错位网格显示出来,与 issue 第三张截图一致。
  • 修复后:构造期禁用扩展 ⇒ 缓冲区布局恒等于 renderType.format ⇒ 拷贝/步长自洽;且缓存只在无光影时绘制,不存在「原版布局喂给需要扩展属性的光影管线」的反向问题。

3. 信标光束层能保住透镜颜色(不是拍脑袋)

1.21.1 官方 rendertype_beacon_beam.fsh 实测:

vec4 color = texture(Sampler0, texCoord0);
color *= vertexColor * ColorModulator;   // ← 顶点色(= getLensColor(lensType))被乘进去
fragColor = linear_fog(color, fragmentDistance, FogStart, FogEnd, FogColor);
  • 格式与图集完全对齐:ModRenderTypes.LASER 与 RenderType.beaconBeam(..., true) 都是 DefaultVertexFormat.BLOCK + TextureAtlas.LOCATION_BLOCKS ⇒ LaserCompiler 写入的顶点数据可直接复用,不需要改 renderBox。
  • 原版光束层自带距离雾(linear_fog),与旧 rendertype_laser 的距离淡出语义一致,不会出现「远处激光不衰减」的突变。

4. 预先排除一个常见误报:RenderType.beaconBeam(...) 不是每调用新建

1.21.1 RenderType.beaconBeam(ResourceLocation, boolean) 的字节码是:

getstatic gfh.bl:Ljava/util/function/BiFunction;   // Util.memoize 缓存
invokeinterface BiFunction.apply(...)              // 同 (location, translucent) ⇒ 同一实例

⇒ 每次 LaserCompiler 请求 ModRenderTypes.LASER 拿到的都是同一个信标光束 RenderType,不会每激光每帧新建 RenderType、也不会把光晕拆成多个 batch。这一点不用报。

5. 删掉手动 endBatch(RenderType.translucent()) 是合理清理

  • 仓库内 laser 相关类没有任何地方向 RenderType.translucent() 写顶点(grep 为空),旧代码那行实际上在 flush 别人的缓冲;
  • 在 Iris 下手动 flush 共享 BufferSource 是已知雷区(同仓库早前注释:「Iris defers the shared entity buffer even after endBatch」),删掉与 issue 里「切换后光束异常」的修复方向一致。

⚠️ 两条需确认(非阻塞)

⚠️ 1. 新方法没有沿用本仓库对 Iris 的防御性降级惯例

IrisState.getHandBufferSource 特意 catch (LinkageError) 后回退到 fallback;而新的 createUnextendedBufferBuilderInternal 直接读 ImmediateState.skipExtension,没有同类兜底。RenderState.isIrisPresent() 判的是 iris 或 oculus,而 skipExtension 只存在于 Iris 1.8.x 的该包路径:若玩家装的是旧版 Iris / 其它分支(字段缺失),首次构建缓存时会在(后台)构建线程抛 NoSuchFieldError。建议对齐既有写法:

try { ... } catch (LinkageError ignored) { return new BufferBuilder(buffer, mode, format); }

同理,若确定只支持 1.8.1+,建议在 neoforge.mods.toml/注释里写明版本前提。

⚠️ 2. 替换条件实际是「光影 或 品质为极佳」,而非仅光影

LaserBlockRenderer 的门控是 if (RenderState.isEnhancedRenderingAvailable()) return;,而

isEnhancedRenderingAvailable() = !Minecraft.useShaderTransparency() && !IrisState.isShaderEnabled()

⇒ 未装光影但开启「极佳!(Fabulous)」 时也会走这个渲染器,现在同样被换成原版光束层(混合方式、LASER_TARGET 输出、深度写入都与自定义 LASER 不同)。若这是有意为之(极佳模式同样需要规避自定义渲染目标),建议在 PR 描述/注释里说明;若只想覆盖光影,应额外加 IrisState.isShaderEnabled() 判断。建议补一张极佳模式(无光影)的截图。


💡 两条可选打磨

  1. 激光枪的光束没有覆盖:WeaponBeamRenderer(实体渲染器,无任何光影门控)→ LaserCompiler.compileWeaponBeam(...) 仍申请 ModRenderTypes.LASER,即同一套自定义着色器 + LASER_TARGET。如果「光影下颜色不正确」的根因是自定义渲染目标/着色器在 Iris 下失效,这条路径可能仍有同样问题(只是 issue 截图里没体现)。要么同样替换,要么在代码/描述里说明为何不受影响。
  2. 给不变量留一行注释:FullyBufferedBufferSource.upload() 依赖「缓冲区顶点布局 == renderType.format.getVertexSize()」。本次修复正是靠 createUnextendedBufferBuilder 维持它;建议在 getBuffer 或 upload 处注明「Iris 扩展会破坏该等式,禁止在此直接 new BufferBuilder」,避免后人回退。

建议的手工验证清单:① 开光影 + 多种颜色透镜,确认光晕颜色正确;② 开光影时卸载透镜 → 关光影,确认光束不再错位;③ 未开光影(普通/极佳两种画质)各看一遍光束外观;④ 激光枪连续光束在光影下确认颜色;⑤ 多个激光器串接/折射场景下确认无批次错乱。

裁决:机制正确、证据充分、CI 通过,可合并;两条 ⚠️ 属于健壮性与作用域确认,建议在合并前补一句版本前提/极佳模式截图即可。

@Gu-ZT
Gu-ZT merged commit 2f46f3a into Anvil-Dev:dev/1.21/1.6 Nov 15, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] 光影下激光渲染颜色不正确以及另外的奇怪bug

4 participants