Flywheel (Legacy)

Flywheel (Legacy)

41M Downloads

Instance lighting has a tendency to break

TropheusJ opened this issue ยท 10 comments

commented

Describe the Bug

Lighting of instances will sometimes go completely or partially dark. This can be seen on large, moving Create contraptions.
This issue was recently opened, showing it happening to chests.

When looking for an issue to direct that to, I was very surprised to find this has never been formally reported?? It's a pretty common problem. I checked Flywheel and both Creates and found nothing. So now there is one.

Reproduction Steps

unknown, very random

Expected Result

correct lighting

Screenshots and Videos

see this issue

Crash Report or Log

No response

Operating System

Windows 10

What is your GPU?

I've had this occur on my 3060, unknown for original reporter.

Mod Version

0.6.8.a

Minecraft Version

1.19.2

Loader Version

unimportant, happens on all loaders and game versions

Other Mods

No response

Additional Context

No response

commented

I've also experienced this issue, and spent the last week trying to figure out why this happens and fixing it. I will not be posting a jar of the fixed version as i'm not sure if that is allowed and you probably shouldn't download and run jars from stranger's on the internet anyways. Fortunately, it is very easy to fix if you know how to clone the code and build your own jar.
There are 2 files that you need to change, InstancedMaterialGroup.java and FallbackAllocator.java. in InstancedMaterialGroup.java, you'll want to look for the following bits of code at lines 97 and 158:

P program = owner.context.getProgram(ProgramContext.create(entry.getKey().getProgramSpec(), Formats.BLOCK, layer));
and
return new ModelPool(Formats.BLOCK);

In FallbackAllocator.java, look for line 11:

IndexedModel out = new IndexedModel(model, Formats.BLOCK);

In all 3 of these places, change Formats.BLOCK to Formats.POS_TEX_NORMAL

This is what fixed it for me, so if you're only interested in that the below information will not be relevant. Here are some things i've found while trying to figure out why it breaks.

In the vertex shaders, the normal is multiplied with a matrix 'normalMat' (done in the vertex(inout Vertex v, Instance i) function defined in model.vert). For some reason, the 'normalMat' that is passed to the shaders is all zeroes sometimes, following a certain pattern (more on that later). This then causes the normal to be set to zeroes, which in turn makes the diffusefactor zero, which finally makes the color zero (black). As to why 'normalMat' is the zero-matrix in the shaders, i couldn't figure that out. By using the debugger, i found that the matrices generated in the code in the BeginFrame() methods of broken instances are completely as expected (and i did not see them get altered after this method). I also checked memory locations the values were written to, and everything seemed to check out. At some point i noticed that there was a place in the constructor of ModelPart.java, which is used to create the broken instances, where POS_TEX_NORMAL format is used to create a PosTexNormalWriterUnsafe. After altering this to a BlockWriterUnsafe (and also implementing some methods in PartBuilder.java to accept the blockwriter), the issue still persisted. I think i looked at basically everything as to why using the BLOCK format might break it, and by all accounts, it shouldn't. In fact, it doesn't for most people: i asked a friend to quickly test it and released version of flywheel where the BLOCK format is used works just fine on his device. This leads me to believe that the issue is perhaps cause by certain graphics drivers or hardware configurations.

I mentioned a pattern in how instances are broken earlier. I noticed that at any point, the oldest half of created instanced (rounded up) of one type works normally, while the newest half (rounded down) is rendered incorrectly. With 'of one type', i mean things such as chest lids and minecarts being distinct types. Also, left- and right-half chest lids for double chests and single lids are considered different types. Shulker boxes top-and bottom halves are also distinct types, as well as shulker boxes of different colors.

Lastly, i noticed that broken instances either rendered too bright or completely black (i assume this is because diffusefactor in the shader is either 0 or 1, but never something in between as a result of the broken 'normalMat'). But once an instance of particular type is destroyed, instances of that type are always completely black until the world is closed and restarted.

This has been a very long comment. To finish i would like to mention that looked through several different branches and commits, and this commit is the one that introduced the problem. This commit happened quite a while ago, so it must be a quite rare occurrence for this problem to happen. Also, i noticed a new version is being worked on on the branch 1.20/next. This problem doesn't occur (at least for me) on that branch.

That was all. I hope this helps!

commented

I'm able to reproduce this on an intel iGPU on 1.20/next. Seems to be related to using integer vertex attributes.

commented

I would like to fix it, so I'm wondering if anyone has an exact list of things I need to do? Because from that post I don't even know where to look for the files...

commented

@HiMikoHyuga The issue is now mostly resolved on 1.20/next and I don't know if there's a true solution that isn't just another workaround.

The problem is that some drivers simply don't handle integer vertex attributes correctly. Flywheel used integer attributes for light (and still uses them for overlay), so sometimes the shader ends up with garbage data.

The workaround you might want to try is to avoid using integer attributes at all. The 2 places I'll point you to are vertex_input.glsl for the GPU side code, and InternalVertex for the CPU side representation.

commented

@HiMikoHyuga The issue is now mostly resolved on 1.20/next and I don't know if there's a true solution that isn't just another workaround.

The problem is that some drivers simply don't handle integer vertex attributes correctly. Flywheel used integer attributes for light (and still uses them for overlay), so sometimes the shader ends up with garbage data.

The workaround you might want to try is to avoid using integer attributes at all. The 2 places I'll point you to are vertex_input.glsl for the GPU side code, and InternalVertex for the CPU side representation.

is it solved? i don't think so, I'm on 1.20.1 create and I still get this with instancing, I did try backend. after I found out you can type that command but with that other thing is broken valk skies doesn't work and crashes, and with it off another mod doesn't work png file items are black... :\ not to mention fps is way worse with other that instancing

commented

It is fixed entirely in dev but the fix has not been released yet

commented

Downgraded to AMD Adrenalin 23.12.1 and this issue doesn't occur for me anymore even while on instancing engine (AMD GPU)
image_2024-07-27_010338657

commented

I'm also getting this issue like the this post, the top of my chest is just black.

commented

After harf a year by "fixed in dev", it still not fix in release? what can i say.

i try an old version about amd driver, it`s ok, but i need to play other games with new driver too.
I must play MC with black chest and purple belt now.
Wish it will be here soon.

commented

Also still experiencing this issue on Adrenalin 24.9.1. Would very much appreciate a fix for this.