sp614x / optifine

1.79k stars 418 forks source link

Thermal Dynamic covers render black w/ shaders #2192

Open shinji257 opened 5 years ago

shinji257 commented 5 years ago

When using shaders (I tried several) Thermal Dynamics covers end up showing black.

EDIT: Testing modpack FTB Ultimate Reloaded on 1.12.2 w/ Optifine 1.12.2 E3. Shaders tested, KUDA Shaders v6.1 Legacy, SEUS Renewed 1.0.0, Sildurs Enhanced Default v1.07, and (internal).

AA and AF are off already. I also make sure AA is off in the shaders options.

Lalarian commented 5 years ago

I'm having the same problem, with internal, SEUS and all Chocapic Shaders. Minecraft 1.12.2 Thermal Dynamics 2.5.4.18 FML 8.0.99.99

NikaPlays commented 5 years ago

still an issue

molletts commented 5 years ago

I get a crash when I attempt to place a cover with shaders enabled.

Using minimal test pack with only: MC 1.12.2 Forge 14.23.5.2838 OptiFine 1.12.2 HD U E3 Thermal Dynamics 2.5.5.21 Thermal Foundation 2.6.3.27 CoFH Core 4.6.3.27 CoFH World 1.3.1.7 Redstone Flux 2.1.0.6

All settings defaults except Shaders: Internal

Turning off shaders prevents the crash.

Rexhunter99 commented 5 years ago

Still an issue, setting the shaders to "OFF" not "Internal" allows normal play. The issue is in the tessellator code where Team CoFH is using a little cheeky bit of code in the vanilla tessellator code to render the covers themselves, Optifine changes this function which breaks the little hack in the duct cover code. The crash actually happens when looking at an item duct with a duct cover in hand. Once the duct cover is placed, you can re-enable shaders and the game will not crash, the duct cover will not render however as Optifine catches the error and suppresses a crash for you (messages about CCL and OpenGL errors in the server chat for the client)

Tyniann commented 5 years ago

Still an issue. Having the exact same issues as described by Rexhunter99. Using Sky Factory 4 + SEUS shaders, Minecraft 1.12.2.

Trabidroid commented 5 years ago

Is there any nice shaders wich works with TD covers?

codefaux commented 5 years ago

@Trabidroid - no, this is a fundamental issue with the way OptiFine/shaders change rendering routines at their core. If I'm understanding it correctly - The fix would require them to implement a proper rendering routine (like other mods using covers/panels IE Applied Energistics 2) rather than patching a core rendering routine. Might be performance implications, maybe I'd implement a config option in their place but the code itself is beyond me.

FWIW - Obviously still having the issues, and I suspect a similar issue is causing random durations of world-render dropping out (just seeing plain rendered distance fog, all other rendering elements including HUD disappearing) with this mod and shaders, it seems to be incredibly time-, location-, and look-direction-sensitive but once it starts happening it repeats at a VERY regular interval and it is maddening.

EDIT: Also I found this for 1.7.10 but it's apparently outdated and is unmaintained, because one or both mods changed their routines in a way that broke this but didn't actually fix the problem (despite the guy saying newer versions of Minecraft don't have it? I don't get it.) so...

https://www.curseforge.com/minecraft/mc-mods/thermalshade

lucaargolo commented 4 years ago

After almost a year this is still an issue.

If you just look at a duct with a cover in your hand the game will try the render its preview and it will just crash. If the cover was already placed it'll just throw a error in the log and it wont render anything.

Is this even going to be fixed? Anyway here is the crash: crash-2020-03-18_22.05.24-client.txt

ferreusveritas commented 4 years ago

@daninfuchs I'm the author of the ThermalShade hack for 1.7.10. Here's the only piece of code that makes it work(or at least did at the time)

  public void postInit() {
    System.out.println("Thermal Shade Patcher");
    if (Loader.isModLoaded("ThermalDynamics")) {
      System.out.println("Changing Thermal Dynamics Cover Renderer");

      cofh.thermaldynamics.duct.attachments.cover.CoverRenderer.VERTEX_SIZE = 18;

      String[] transformerNames = { "hollowDuct", "hollowDuctLarge", "hollowDuctTile", "hollowDuctCryo", "hollowDuctTransport" };
      for (String name : transformerNames) {
        try {
          setFinalStatic(CoverHoleRender.class.getField(name), null);
        }
        catch (Exception e1) {
          e1.printStackTrace();
        }
      }
    }
  }

  public static void setFinalStatic(Field field, Object newValue) throws Exception {
    field.setAccessible(true);

    Field modifiersField = Field.class.getDeclaredField("modifiers");
    modifiersField.setAccessible(true);
    modifiersField.setInt(field, field.getModifiers() & 0xFFFFFFEF);

    field.set(null, newValue);
  }

The new 1.12.2 rendering code seems to be completely different from what I can tell. Anyway, just posting this here to help remove some of the mystery.

ferreusveritas commented 4 years ago

2020-04-14_23 05 29

I got it working in 1.12.2 with a super heinous java reflection hack.

I wrote over the lighterFlat and lighterSmooth ThreadLocal members in ThermalDynamics CoverRenderer class with a custom extended VertexLighterFlat class using reflection. The modifiers are private static final which is why Reflection was necessary.

This VertexLighterFlatSpecial class reimplements most of the VertexLighterFlat class with a few tweaks. It's setVertexFormat is implemented like this:

    @Override
    public void setVertexFormat(VertexFormat format) {

        if (!Objects.equals(format, baseFormat)) {
            baseFormat = format;
            VertexFormat wNormal = withNormal(format);
            this.format = wNormal;
            dataLength = new byte[wNormal.getElementCount()];
            quadData = new float[wNormal.getElementCount()][4][4];

            updateIndices();
        }

    }

This was necessary since the QuadGatheringTransformer.format member was being storing the wrong value because of some kind of evil voodoo spirits that I was unable to pin down.

The other tweak was to simply bypass all of the color calculations which was resulting in black In processQuad:

                case COLOR:
                    color[v][0] = 1.0f;
                    color[v][1] = 1.0f;
                    color[v][2] = 1.0f;
                    color[v][3] = 1.0f;
                    parent.put(e, color[v]);
                    break;

This simply sets the quad color to white always.

I need to do some more tests to see if this will work as a viable method to work around this problem.

ferreusveritas commented 4 years ago

Okay. So I just published the workaround: https://www.curseforge.com/minecraft/mc-mods/unifine

It's in experimental status but should do the trick. I know this is not the right way to do this but I aimed for the highest quality dumpster fire. Source code is available if any of the official developers are interested in integrating a similar solution.

I'll take it out of experimental status once a few people can confirm that it's stable and works as intended.

shinji257 commented 4 years ago

Just my 2 cents but Unifine is working well here. Takes care of the rendering and the crash that can happen with shaders.

jagyCZ commented 4 years ago

Is there any chance for this to be implemented in optifine by default ? @sp614x

ferreusveritas commented 4 years ago

@jagyCZ This is not an Optifine bug. So it won't be corrected from Optifine.

Lalarian commented 4 years ago

Why not take it as a feature request, as it doesn't seem to be a bug at all, but an incompatibility by design?