Jump to content

Custom OBJ, vanilla texture - loads, but is not scaled correctly


briclabs

Recommended Posts

Greetings,

 

I have been working on developing my first mod. It involves loading an OBJ file as a model for a block that extends the StairsBlock class, so it has the same capabilities as stairs in terms of placement and shape, etc. In the OBJ file, it points at an MTL file. In the MTL file, I'm indicating:

 

map_Kd minecraft:block/oak_planks

 

It correctly finds the texture and applies it. The model renders just fine and is the right scale. However, the texture itself is scaled far too large, so a single pixel in the normal texture now takes 1/4 of the block.

 

I've read that with wavelength mtl files one can set the scale for the texture by using "-s x y z" but that doesn't seem to get honored in this case. I'm suspecting that is not supported in Minecraft Forge as a way of rescaling textures.

 

The block model itself is the perfect size, so why is the texture rendering at the wrong scale? Anyone have thoughts as to what I could be doing wrong or things I can try?

 

Thanks,

 

~ Bric

2020-03-28_21.15.56.png

Edited by briclabs
adding screenshot for illustration purposes
Link to comment
Share on other sites

Hi

That is a strange one.

I've just implemented obj model in this example project (for a TER, not a block admittedly), you might have a look for clues in there (https://github.com/TheGreyGhost/MinecraftByExample see RenderWavefrontObj)

 

My guess: Forge is assuming that your texture is for a single face but your texture sheet is actually for all six faces, i.e. it is using u,v = 0,0 to 0.25, 0.25 or similar.  Might be a forge bug, or might be something you've configured incorrectly

 

I'd suggest either trial and error to get the texture right, or digging into the model baking process (set a breakpoint inside OBJloader and/or OBJmodel to see what happens to your vertices and textures after your model loads).

 

It may be a bit tricky because minecraft stitches block textures together into a single texture sheet, so the u,v are harder to interpret.

 

-TGG

 

Link to comment
Share on other sites

I think you're probably right; I didn't think of that. It seems to make sense given the way its rendering that its using the default texture as a single square texture to apply to all faces at the same time. I'll see if I can figure out how to have it apply to each face like a normal block. I'll also look at the example you gave (thank you!) and see if that gives me any leads.

Link to comment
Share on other sites

Seems like its something with the OBJ model itself. In blender, I just did the following:

 

  1. Showed the UV Editing window.
  2. Noted that the UV map presented was an unfolded version of my object.
  3. Changed to Edit Mode.
  4. Changed select mode to Face Select mode.
  5. Selected each face of my model one at a time, right-clicked and chose "UV Unwrap Faces -> Unwrap".
  6. Noted in the UV window, the map presented was now a single square, with each face overlapping on said square.

I have the scale correct now, and my mtl file still just has to look like this (none of the extra lines Blender added during export were needed):

# Blender MTL File: 'fortyfive.blend'
# Material Count: 1

newmtl fortyfive
map_Kd minecraft:block/oak_planks

 

The item model is still showing the bad scaling for the texture, but that's because I hadn't applied the new OBJ file to that yet, just to the block.

 

I'm going to continue fiddling with (read: learning) Blender to now figure out how to get the faces' textures to have the correct orientation. Will continue to post for the benefit of anyone else that runs into this issue.

Link to comment
Share on other sites

Well... significant progress. I think the moral of the story here is that one should not try and do a Blender custom model unless they actually put the texture in first, and then align it using the steps I had in my previous post so that its correctly laid out. Seems the UV orientation is contained in the OBJ data. Unfortunately OBJ syntax feels more like machine code rather than meant-for-a-human-to-write-manually, so I couldn't begin to guess at the differences. It also appears, as can be seen in my screenshot below, that stairs are literally upside-down blocks, which is why the texture is likewise also upside-down, hence the lines in the oak planks texture not lining up. So it appears I'll need an additional model just for that variant, since the model determines the UV orientation, and that determines the orientation of the textures.

 

And my MTL file, fyi, is still just this simple, so it could point at any existing texture. I wanted to make sure I did it this way so that texture packs that replace vanilla textures would automatically apply here as well.

# Blender MTL File: 'fortyfive.blend'
# Material Count: 1

newmtl fortyfive
map_Kd minecraft:block/oak_planks

 

Unfortunately unless I can figure out how to assign the actual texture image file to the model dynamically in the Java code, I think I'm going to abort much more work on this mod attempt. I wanted to introduce diagonal blocks of all applicable material types (stone, quartz, etc) but I haven't found any examples where this has been done. The model would stay the same, but the image used for the texture would be changed. I'm not excited about making several hundred JSON -> OBJ -> MTL file sets just to accomplish that. Seems like there should be a simpler way of using the same JSON -> OBJ file chain and assigning the MTL within Java instead of a static file.

 

 

2020-03-28_23.53.57.png

Edited by briclabs
clarifying that the texture is not embedded in the OBJ file; its still getting referenced in the MTL file
Link to comment
Share on other sites

Hi

 

Ah yeah that makes sense.

BTW these is a flag available in the loader to flip the V texture coordinate  

https://github.com/TheGreyGhost/MinecraftByExample/blob/master/src/main/resources/assets/minecraftbyexample/models/block/mbe21_ter_wavefront_model.json

You can also override the path to the mtl file, so at least you would only need one obj file.

 

There is a more-compact way to use the same obj with different texture each time, but you will need to write your own OBJmodel loader by customising the Forge one to add a couple of custom flags for your own use, or to automatically choose a texture based on the block that's being loaded.  The Forge code (OBJloader and OBJmodel) is not too difficult to understand once you know what it's doing.

 

-TGG

 

 

Link to comment
Share on other sites

Still fiddling, but I don't think most of the typical JSON flags work when applied to OBJ files. I think the reason is that things like coords for the UV textures are actually part of the OBJ file itself, and therefore get overriden. Since a typical JSON file just deals with code-generated blocks, I don't think they have this hardcoded limitation. For example, so far I now need a separate model, with appropriate UV coords, just to define a block that's upside down, since the faces on the side of the block have to be rotated 180 degrees to avoid the issue in my previous screenshot. That works. However I then discovered that I'll need an additional OBJ model for north/south, east/west, since the top and bottom faces would need their UV coords changed to match what the vanilla blocks' textures are. I looked at the OBJ file format and did some experimenting, and there's no way to uncouple the UV mapping from the model; doing so results in invisible faces. Therefore I don't think OBJ is a suitable pursuit for this project, as it is too encumbered by having to have static files define every detail. While I haven't looked into trying to implement a custom OBJloader / OBJmodel, I suspect that as long as I'm using static OBJ files, I'm going to be stuck making a mess-load of them just to do basic orientation of the textures applied to each face.

 

I'm probably going to abandon this pursuit, but I'll see if there's a way to generate a non-cubic model in Java, instead of using static OBJ files. Working in Java would be significantly more flexible I'd expect, since by nature static files don't have as much accessibility to the code (and basically, if it did, it would be an override in the code anyway). I'll mark this thread resolved since the original issue was resolved (thank you!) but I think OBJ files for non-cubic shapes are too cumbersome for what I'm trying to accomplish.

Edited by briclabs
doesn't appear I can change the subject of this thread, so unless I was missing how to do it, I don't think I can mark it resolved
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.