PepperCode1 / Continuity

A Fabric mod that allows for efficient connected textures
GNU Lesser General Public License v3.0
275 stars 76 forks source link

innerSeams configuration for internal faces of hollow cube model #231

Open muzikbike opened 1 year ago

muzikbike commented 1 year ago

Currently developing a resource pack which contains a custom model for glass blocks containing inner faces. I've attached minimal resource packs containing these models for testing.

When innerSeams is not enabled, the back faces of pretty much any shape constructed from glass blocks render connected like the front faces do. 2023-03-30_07 13 30 2023-03-30_07 14 05 2023-03-30_07 14 20

I, however, want to use innerSeams, and that's where the problem arises: turning it on causes the texture connections on the back faces to just give up. The front still works fine, the back faces are the issue here. 2023-03-30_07 16 23

The two test resource packs can be found as follows: hollow-glass-continuity-no-seams.zip hollow-glass-continuity-with-seams.zip

The same issue is also present in OptiFine 1.19.4, but is blocked by a more significant bug (https://github.com/sp614x/optifine/issues/7338).

PepperCode1 commented 1 year ago

From my understanding of innerSeams, this is intended. Continuity does not care what depth the face is at or what its cull face is.

Assume connected textures are being applied to the inner face of an outer center block $B_O$ at position $P_O$. To make explanation easier, also assume that right now the up direction is being checked for a connection. Block $B_A$ at position $P_A$, the position offset in the relative up direction, is checked for a connection. If the predicates in the properties file match $B_A$, the connection succeeds. However, if innerSeams=true, block $B_B$ at position $P_B$, the position "in front" (offset in the direction of the quad's light face) of position $P_A$, is also checked. If block $B_B$ also passes the connection predicates, the original up connection fails; otherwise, it succeeds.

I would like to know how you would like this issue to be resolved, since right now I do not imagine how it could be done without special-casing. Did innerSeams work differently in MCPatcher and would such functionality resolve this issue? If so, how did it work?

muzikbike commented 1 year ago

Here's glass from Misa's resource pack in 1.7.10, which is the look that I'm going for in the pack I'm developing, model-wise: 2023-03-30_18 02 07 2023-03-30_18 02 16 2023-03-30_18 02 26 2023-03-30_18 03 13 2023-03-30_18 03 16

Checking the properties file for glass CTM reveals that innerSeams are set to true . 47 files are specified instead of 46, and the properties file specifies this accordingly, but in terms of connection geometry 0-46 are the same as in vanilla Continuity and 47 appears to duplicate 26 (the images are identical), so I'm not sure what it represents.

Since this is 1.7.10, a version that predates models, the effect seen in these screenshots would likely have been achieved by simply not culling the rear faces of the blocks, which is admittedly a far simpler approach than defining a completely new model with extra planes explicitly specified as stand-ins for those faces. I'm not sure if this is something that would actually be possible to implement in Continuity at all.

I assume this is what "renderPass" (https://github.com/sp614x/optifine/issues/5084) is referring to? I myself have never actually developed resource packs until many years after MCPatcher stopped being a thing, so I wouldn't know. The properties file for Misa's glass defines renderPass to be 3 for the glass itself, and 2 for the overlaid edge frame texture.

muzikbike commented 1 year ago

According to the following forum post, renderPass was for changing the render type of the target block: https://www.minecraftforum.net/forums/mapping-and-modding-java-edition/resource-packs/resource-pack-discussion/1256343-a-texture-artists-guide-to-mcpatchers-features

Its functionality appears to have since been moved into a new block.properties file, if I'm understanding it correctly: https://github.com/sp614x/optifine/blob/master/OptiFineDoc/doc/block.properties

This is what the latest version of Misa's for 1.19 seems to use. I've compared the glass geometry, and most things match up, with the only difference is that innerSeams only appear to render from the outside, and not on the inside. I don't know if this is down to the custom model or not. 2023-03-31_23 06 39 2023-03-31_23 06 55 2023-03-31_23 07 33 2023-03-31_23 07 43

Does Continuity also support block.properties and other such files?

PepperCode1 commented 1 year ago

Yes, Continuity supports block.properties, but this file has never had an option to disable back face culling. Disabling back face culling is not something Continuity can do because it does not control rendering and the API that it uses does not have an option for this.

muzikbike commented 1 year ago

I've done some more experimentation. Here's a minimal-ish implementation of the partial workaround from Misa's pack: hollow-glass-continuity-partial-seam-fix.zip

This works by having the inside and outside of the model used point to separate texture files. That way, it's possible for CTM to apply different types of connected texture specifications to the outside faces and inside faces. This almost resolves our issue.

Here's the original demo without innerSeams: 2023-04-01_20 36 28

Here's the original demo with innerSeams: 2023-04-01_20 36 42

And here's the new partial workaround: 2023-04-01_20 36 54

The reason why this is only a "partial" workaround is that this fix only enables innerSeams on the outer faces: it's disabled on the inner faces, which we can see from the L-shape above. If we enable it on the inner faces, we just run into the original issue again.

It seems entirely possible to fix this issue properly now that we define the inner and outer faces separately. While Continuity doesn't care about what depth a given face is in a model, we can still explicitly define what counts as an "inner" face and what counts as an "outer" face in the resource pack itself and configure their CTM settings independently.

My proposal for fixing this is as follows: the CTM .properties file would accept a new optional parameter - let's call it "seamType". This new "seamType" would define the way that innerSeams would detect adjacent glass blocks and how it would change the texture used. By default (and if omitted), it would be set to "outer", which is the current innerSeams behaviour. It could also be set to "inner", in which case the checks would instead be performed in a way that would be appropriate for inner faces instead, and the chosen textures would be applied accordingly. So, if "seamType" was implemented, we could set innerSeams to true for both the inner and outer textures, and set "seamType" to "outer" for the outer textures and to "inner" for the inside textures. With this, we would be able to recreate MCPatcher's backface functionality perfectly.

Of course, that's just off the top of my head - I wouldn't be surprised at all if it turned out to not be that simple, but one can hope.

muzikbike commented 1 year ago

For the record, here's the same arrangement as above in 1.7.10 with MCPatcher. This is the visual result we're looking for. Note the vertical white bar inside the L-shaped cavity from the inside - we want to be seeing this in 1.19.4 as well. 2023-04-01_20 59 50

Also, since you said that Continuity doesn't touch the rendering, I have a few questions:

PepperCode1 commented 1 year ago
muzikbike commented 1 year ago

Not to get too off topic, but is block.properties expected to be formatted differently somehow compared to that of Optifine? I have the following test resource pack with a block.properties file formatted correctly for Optifine to my knowledge, but it doesn't work in Continuity and the glass remains completely opaque. Is there something I should be doing differently to make the glass translucent without relying on an extra mod? block-properties-test.zip 2023-04-04_22 20 57

PepperCode1 commented 1 year ago

block.properties works exactly like in Optifine. block.properties must be located in the minecraft namespace, just like in Optifine.