Jump to content
  • Home
  • Files
  • Docs
Topics
  • All Content

  • This Topic
  • This Forum

  • Advanced Search
  • Existing user? Sign In  

    Sign In



    • Not recommended on shared computers


    • Forgot your password?

  • Sign Up
  • All Activity
  • Home
  • Mod Developer Central
  • Modder Support
  • (1.15.1)[Solved] Baked Model is too dark
Currently Supported: 1.16.X (Latest) and 1.15.X (LTS)
Sign in to follow this  
Followers 0
PianoManu

(1.15.1)[Solved] Baked Model is too dark

By PianoManu, June 10, 2020 in Modder Support

  • Reply to this topic
  • Start new topic

Recommended Posts

PianoManu    0

PianoManu

PianoManu    0

  • Tree Puncher
  • PianoManu
  • Members
  • 0
  • 24 posts
Posted June 10, 2020 (edited)

Hey guys!

I created a block (slab, to be axact), that takes on the texture of the block it is clicked on. For that I used Baked Models. Now nearly everything works fine, but the slab texture (when covered by a block) is way too dark (see attached pictures), as if the light level was zero. As you can see in the first picture, it works well for the json-block-model, when the slab does not contain any block (oak planks texture). So I guess the problem is somewhere in the baked model, but I can't figure it out.

Here's the code for my BakedModel-Class extending IDynamicBakedModel:

getQuads (Overrides interface method)

public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction side, @Nonnull Random rand, @Nonnull IModelData extraData) {
        //get block saved in slab's tile entity
        BlockState mimic = extraData.getData(FrameBlockTile.MIMIC);
        //check if not empty
        if (mimic != null && !(mimic.getBlock() instanceof FrameBlock)) {
            //location of BlockModel
            ModelResourceLocation location = BlockModelShapes.getModelLocation(mimic);
            if (location != null) {
                IBakedModel model = Minecraft.getInstance().getModelManager().getModel(location);
                model.getBakedModel().getQuads(mimic, side, rand, extraData);
                if (model != null) {
                    //new quad-model with data from slab
                    return getMimicQuads(mimic, side, rand, extraData);
                }
            }
        }
        return Collections.emptyList();

the called method "getMimicQuads":

public List<BakedQuad> getMimicQuads(@Nullable BlockState state, @Nullable Direction side, @Nonnull Random rand, @Nonnull IModelData extraData) {
        if (side != null) {
            return Collections.emptyList();
        }
        BlockState mimic = extraData.getData(FrameBlockTile.MIMIC);
        if (mimic!=null) {
          	//get texture from block saved in slab
            TextureAtlasSprite texture = Minecraft.getInstance().getAtlasSpriteGetter(AtlasTexture.LOCATION_BLOCKS_TEXTURE).apply(new ResourceLocation(mimic.getBlock().getRegistryName().getNamespace(), "block/"+mimic.getBlock().getRegistryName().getPath()));
            List<BakedQuad> quads = new ArrayList<>();
          	//create 6 faces of slab
            //down
            quads.add(createQuad(v(1, 0, 0), v(1, 0, 1), v(0, 0, 1), v(0, 0, 0), texture));
            //up
            quads.add(createQuad(v(0, 0.5, 0), v(0, 0.5, 1), v(1, 0.5, 1), v(1, 0.5, 0), texture));
            //sides
            quads.add(createHalfQuad(v(0, 0, 0), v(0, 0, 1), v(0, 0.5, 1), v(0, 0.5, 0), texture));
            quads.add(createHalfQuad(v(0, 0, 0), v(0, 0.5, 0), v(1, 0.5, 0), v(1, 0, 0), texture));
            quads.add(createHalfQuad(v(0, 0, 1), v(1, 0, 1), v(1, 0.5, 1), v(0, 0.5, 1), texture));
            quads.add(createHalfQuad(v(1, 0.5, 0), v(1, 0.5, 1), v(1, 0, 1), v(1, 0, 0), texture));

            return quads;
        }
        return Collections.emptyList();
    }

the called createQuad and createHalfQuad methods:

	//for squared part of slab (top and bottom side)
	private BakedQuad createQuad(Vec3d v1, Vec3d v2, Vec3d v3, Vec3d v4, TextureAtlasSprite sprite) {
        Vec3d normal = v3.subtract(v2).crossProduct(v1.subtract(v2)).normalize();

        BakedQuadBuilder builder = new BakedQuadBuilder(sprite);
        builder.setQuadOrientation(Direction.getFacingFromVector(normal.x, normal.y, normal.z));
        putVertex(builder, normal, v1.x, v1.y, v1.z, 0, 0, sprite, 1.0f, 1.0f, 1.0f);
        putVertex(builder, normal, v2.x, v2.y, v2.z, 0, 16, sprite, 1.0f, 1.0f, 1.0f);
        putVertex(builder, normal, v3.x, v3.y, v3.z, 16, 16, sprite, 1.0f, 1.0f, 1.0f);
        putVertex(builder, normal, v4.x, v4.y, v4.z, 16, 0, sprite, 1.0f, 1.0f, 1.0f);
        return builder.build();
    }
	//for rectangles (sides of slab)
	private BakedQuad createHalfQuad(Vec3d v1, Vec3d v2, Vec3d v3, Vec3d v4, TextureAtlasSprite sprite) {
        Vec3d normal = v3.subtract(v2).crossProduct(v1.subtract(v2)).normalize();

        BakedQuadBuilder builder = new BakedQuadBuilder(sprite);
        builder.setQuadOrientation(Direction.getFacingFromVector(normal.x, normal.y, normal.z));
        putVertex(builder, normal, v1.x, v1.y, v1.z, 0, 0, sprite, 1.0f, 1.0f, 1.0f);
        putVertex(builder, normal, v2.x, v2.y, v2.z, 0, 8, sprite, 1.0f, 1.0f, 1.0f);
        putVertex(builder, normal, v3.x, v3.y, v3.z, 16, 8, sprite, 1.0f, 1.0f, 1.0f);
        putVertex(builder, normal, v4.x, v4.y, v4.z, 16, 0, sprite, 1.0f, 1.0f, 1.0f);
        return builder.build();
    }

and the putVertex-method for creating the vertices:

private void putVertex(BakedQuadBuilder builder, Vec3d normal,
                           double x, double y, double z, float u, float v, TextureAtlasSprite sprite, float r, float g, float b) {

        ImmutableList<VertexFormatElement> elements = builder.getVertexFormat().getElements().asList();
        for (int j = 0 ; j < elements.size() ; j++) {
            VertexFormatElement e = elements.get(j);
            switch (e.getUsage()) {
                case POSITION:
                    builder.put(j, (float) x, (float) y, (float) z, 1.0f);
                    break;
                case COLOR:
                    builder.put(j, r, g, b, 1.0f);
                    break;
                case UV:
                    switch (e.getIndex()) {
                        case 0:
                            float iu = sprite.getInterpolatedU(u);
                            float iv = sprite.getInterpolatedV(v);
                            builder.put(j, iu, iv);
                            break;
                        case 2:
                            builder.put(j, 0f, 1f);
                            break;
                        default:
                            builder.put(j);
                            break;
                    }
                    break;
                case NORMAL:
                    builder.put(j, (float) normal.x, (float) normal.y, (float) normal.z);
                    break;
                default:
                    builder.put(j);
                    break;
            }
        }
    }

 

Ambient Occlusion is set to true (I read, that this might be the reason, but when I toggled it multiple times nothing really changed)

Gui3d and BuildInRenderer both return false

 

As I said, the texture is too dark, like if the light level was zero and I want to fix that. I really don't know what to do anymore. Any help is appreciated. Thanks in advance

(I hope you understand, what I was trying to say, english is not my native language)

Kind Regards, Manu

2020-06-10_13.30.52.png

2020-06-10_13.30.55.png

Edited June 13, 2020 by PianoManu
Problem is solved. Thanks to you, TGG!
  • Quote

Share this post


Link to post
Share on other sites

TheGreyGhost    818

TheGreyGhost

TheGreyGhost    818

  • Reality Controller
  • TheGreyGhost
  • Members
  • 818
  • 3280 posts
Posted June 10, 2020

Howdy

I don't see you put any lightmap information into your vertex, but I presume you are using the Block vertex format?  In my previous digging through the rendering code, I sometime found that to be important.

 

DefaultVertexFormats.BLOCK

    // IVertexBuilder::addQuad and FaceBakery; see also DefaultVertexFormats.BLOCK.
    // Summary:
    //    faceData[i + 0] = Float.floatToRawIntBits(positionIn.getX());
    //    faceData[i + 1] = Float.floatToRawIntBits(positionIn.getY());
    //    faceData[i + 2] = Float.floatToRawIntBits(positionIn.getZ());
    //    faceData[i + 3] = shadeColor;
    //    faceData[i + 4] = Float.floatToRawIntBits(textureU));
    //    faceData[i + 5] = Float.floatToRawIntBits(textureV));
    //    faceData[i + 6] = baked lighting (blocklight + skylight)
    //    faceData[i + 7] = normal;

 

You could consider using the face bakery to generate your quads, like this

  /**
   * Returns a quad for the given digit
   * @param digit the digit (0 -> 9)
   * @param isBlank if true: this digit should be blank (is a leading zero)
   * @param minX: the minimum [x,y,z] of the digit quad (from the viewer's point of view).  units = model space i.e. 0->16 is 1 metre block
   * @param maxX: the maximum [x,y,z] of the digit quad (from the viewer's point of view).  units = model space i.e. 0->16 is 1 metre block
   * @return
   */
  private BakedQuad getQuadForDigit(int digit, boolean isBlank, Direction whichFace,
                                    double minX, double minY, double minZ, double maxX, double maxY, double maxZ) {
    // generate a BakedQuad for the given digit

    // we can do this manually by providing a list of vertex data, or we can use the FaceBakery::bakeQuads method
    // FaceBakery::bakeQuad is much simpler and suitable for pretty much any block-style rendering, so I've used that here
    // If you want to manually provide vertex data yourself, the format is an array of ints; look in
    // IVertexBuilder::addQuad and FaceBakery; see also DefaultVertexFormats.BLOCK.
    // Summary:
    //    faceData[i + 0] = Float.floatToRawIntBits(positionIn.getX());
    //    faceData[i + 1] = Float.floatToRawIntBits(positionIn.getY());
    //    faceData[i + 2] = Float.floatToRawIntBits(positionIn.getZ());
    //    faceData[i + 3] = shadeColor;
    //    faceData[i + 4] = Float.floatToRawIntBits(textureU));
    //    faceData[i + 5] = Float.floatToRawIntBits(textureV));
    //    faceData[i + 6] = baked lighting (blocklight + skylight)
    //    faceData[i + 7] = normal;
    // When constructing a face manually in this way, the order of vertices is very important!
    // 1) must be added anti-clockwise (from the point of view of the person looking at the face).  Otherwise the face
    //    will point in the wrong direction and it may be invisible (backs of faces are usually culled for block rendering)
    // 2) ambient occlusion (a block lighting effect) assumes that the vertices are added in the order:
    //     top left, then bottom left, then bottom right, then top right - for the east, west, north, south faces.
    //     for the top face: NW, SW, SE, NE.  for the bottom face: SW, NW, NE, SE
    //    If your face has ambient occlusion enabled, and the order is wrong, then the shading will be messed up

    // FaceBakery:
    //  Vanilla uses it to convert from the elements in a block model, i.e.
    //    "elements": [
    //    { "from": [ 7, 0, 7 ],
    //      "to": [ 9, 10, 9 ],
    //      "shade": false,
    //      "faces": {
    //        "down": { "uv": [ 7, 13, 9, 15 ], "texture": "#torch" },
    //        "up":   { "uv": [ 7,  6, 9,  8 ], "texture": "#torch" }
    //      }
    //    },
    //    see https://minecraft.gamepedia.com/Model#Block_models
    //  In order to use the FaceBakery::bakeQuad method, we need to provide:
    //   1) A suitable cuboid 'from' and 'to', in model coordinate (eg the full 1 metre cube is from [0,0,0] to [16, 16, 16])
    //   2) the corresponding [u,v] texture coordinates for the face: [minU,minV] first then [maxU,maxV], again in texels 0->16
    //   3) the face we want to make the quad for (eg up, down, east, west, etc).

    Vector3f from = new Vector3f((float)minX, (float)minY, (float)minZ);
    Vector3f to = new Vector3f((float)maxX, (float)maxY, (float)maxZ);

    // texture UV order is important! i.e. [minU,minV] first then [maxU,maxV]
    float [] uvArray = getDigitUVs(digit, isBlank);
    final int ROTATION_NONE = 0;
    BlockFaceUV blockFaceUV = new BlockFaceUV(uvArray, ROTATION_NONE);

    final Direction NO_FACE_CULLING = null;
    final int TINT_INDEX_NONE = -1;  // used for tintable blocks such as grass, which make a call to BlockColors to change their rendering colour.  -1 for not tintable.
    final String DUMMY_TEXTURE_NAME = "";  // texture name is only needed for loading from json files; not needed here
    BlockPartFace blockPartFace = new BlockPartFace(NO_FACE_CULLING, TINT_INDEX_NONE, DUMMY_TEXTURE_NAME,  blockFaceUV);

    // we have previously registered digitsTexture in StartupClientOnly::onTextureStitchEvent
    AtlasTexture blocksStitchedTextures = ModelLoader.instance().getSpriteMap().getAtlasTexture(AtlasTexture.LOCATION_BLOCKS_TEXTURE);
    TextureAtlasSprite digitsTextures = blocksStitchedTextures.getSprite(digitsTextureRL);

    final IModelTransform NO_TRANSFORMATION = IDENTITY;
    final BlockPartRotation DEFAULT_ROTATION = null;   // rotate based on the face direction
    final boolean APPLY_SHADING = true;
    final ResourceLocation DUMMY_RL = new ResourceLocation("dummy_name");  // used for error message only
    BakedQuad bakedQuad = faceBakery.bakeQuad(from, to, blockPartFace, digitsTextures, whichFace, NO_TRANSFORMATION, DEFAULT_ROTATION,
                             APPLY_SHADING, DUMMY_RL);
    return bakedQuad;
  }

 

If that doesn't help, I'd suggest you add a breakpoint to ForgeBlockModelRenderer::renderModelSmooth (or much easier - ::renderModelFlat if you turn off ambient occlusion) and watch how your block's quads are rendered to the buffer.

 

I've also had this problem arise previously with blocks which used the skylight+blocklight value for rendering but which had a calculated skylight+blocklight of 0 due to the block's settings (I forget which, sorry).   The breakpoint I suggested above should show that, if it's the cause.

 

-TGG

 

 

 

 

  • Like 1
  • Quote

Share this post


Link to post
Share on other sites

PianoManu    0

PianoManu

PianoManu    0

  • Tree Puncher
  • PianoManu
  • Members
  • 0
  • 24 posts
Posted June 10, 2020

Hey, thanks for your reply!

I've read your text several times and I'm beginning to understand, but I've never worked with the FaceBakery before, so I don't have any experiences with that. Do I have to rewrite the whole baked model class to extend the FaceBakery instead of implementing IDynamicBakedModel? I've looked through the FaceBakery class and the IVertexBuilder, but I have no clue where to begin with... Maybe you could give me a hint?

Or do I have to rewrite everything at all?

 

Also, where is this code part from? I couldn't find anything on Google, when I searched for "getQuadForDigit". I ask because maybe I could get some more information from the context of the code

 

Thank you for your help!

  • Quote

Share this post


Link to post
Share on other sites

PianoManu    0

PianoManu

PianoManu    0

  • Tree Puncher
  • PianoManu
  • Members
  • 0
  • 24 posts
Posted June 11, 2020
21 hours ago, TheGreyGhost said:

I don't see you put any lightmap information into your vertex

Sorry for bothering you again, but I've searched and tested a bit further and honestly I don't know how to put it into the vertex as I don't have any lightmap information (as far as I know) and both the BakedQuadBuilder and the VertexFormatElement do not take/contain any lighting information. How do you mean that? Like, what do I have to add?

Thanks for helping me!

  • Quote

Share this post


Link to post
Share on other sites

TheGreyGhost    818

TheGreyGhost

TheGreyGhost    818

  • Reality Controller
  • TheGreyGhost
  • Members
  • 818
  • 3280 posts
Posted June 11, 2020

Howdy

The code is from this example project

https://github.com/TheGreyGhost/MinecraftByExample

(mbe04 AltimeterBakedModel)

 

The definition for the vertex format of BLOCK is 

public static final VertexFormat BLOCK = new VertexFormat(ImmutableList.<VertexFormatElement>builder()
  .add(POSITION_3F)  //[x,y,z]
  .add(COLOR_4UB) // colour info
  .add(TEX_2F) // texture
  .add(TEX_2SB) // lighting (blocklight + skylight)
  .add(NORMAL_3B) // normal 
  .add(PADDING_1B).build());

but you're right, the lighting is often not used / is added during rendering.

 

If you put your code into a github I'll have a look in the next day or so to figure it out.  I think it's almost certainly a block setting or voxelshape problem that's causing the lightmap to be wrong, it won't take me long to confirm it.

 

Cheers

  TGG

 

 

 

  • Thanks 1
  • Quote

Share this post


Link to post
Share on other sites

PianoManu    0

PianoManu

PianoManu    0

  • Tree Puncher
  • PianoManu
  • Members
  • 0
  • 24 posts
Posted June 11, 2020 (edited)
2 hours ago, TheGreyGhost said:

The code is from this example project

https://github.com/TheGreyGhost/MinecraftByExample

(mbe04 AltimeterBakedModel)

Thank you very much!

 

This is my git repository: https://github.com/PianoManu/BlockCarpentry

The registration of the block is located in the setup-package in the Registration class.

The model loaders are registered in the setup-package in the ClientSetup class - there are three model loaders, the "frameloader" loads the full block and works fine. The problematic one is the "frame_slab_bottom_loader".

The Baked Model for the slab is located in the bakedmodels package as "SlabFrameBottomBakedModel" class

 

Thank you very much for your help! I will be really happy if you find my mistake ?

Regards, Manu

 

Edit: for some weird reason, the "main" directory is outside of the "src" directory in the git repository and you can't open the src directory... But everything is contained in the main directory so I guess it's fine...

Edited June 11, 2020 by PianoManu
  • Quote

Share this post


Link to post
Share on other sites

TheGreyGhost    818

TheGreyGhost

TheGreyGhost    818

  • Reality Controller
  • TheGreyGhost
  • Members
  • 818
  • 3280 posts
Posted June 13, 2020

Howdy

 

The problem is here; you mixed up short (2 bytes long) and float(4 bytes long) so your UV was overwriting dud values into the baked skylight+blocklight.

 

    private void putVertex(BakedQuadBuilder builder, Vec3d normal,
                           double x, double y, double z, float u, float v, TextureAtlasSprite sprite, float r, float g, float b) {

        //ImmutableList<VertexFormatElement> elements = builder.getVertexFormat().getElements().asList();
        ImmutableList<VertexFormatElement> elements = SLAB_BLOCK.getElements().asList();
        for (int j = 0 ; j < elements.size() ; j++) {
            VertexFormatElement e = elements.get(j);
            switch (e.getUsage()) {
                case POSITION:
                    builder.put(j, (float) x, (float) y, (float) z, 1.0f);
                    break;
                case COLOR:
                    builder.put(j, r, g, b, 1.0f);
                    break;
                case UV:
                    switch (e.getIndex()) {
                        case 0:
                            float iu = sprite.getInterpolatedU(u);
                            float iv = sprite.getInterpolatedV(v);
                            builder.put(j, iu, iv);
                            break;
                        case 2:
                            builder.put(j, (short)0, (short)0);  // error is here
                            break;
                        default:
                            builder.put(j);
                            break;
                    }
                    break;
                case NORMAL:
                    builder.put(j, (float) normal.x, (float) normal.y, (float) normal.z);
                    break;
                default:
                    builder.put(j);
                    break;
            }
        }
        builder.setApplyDiffuseLighting(true);
    }

 

Due to non-defensive coding assumptions in IForgeVertexBuilder, it was taking your incorrect slBaked value (2047 instead of 0), overwriting the skylight (15), leaving a packed texture coordinate with zeros in the least significant bits, i.e. effectively 0 skylight = dark.

    default int applyBakedLighting(int lightmapCoord, ByteBuffer data) {
        int bl = LightTexture.getLightBlock(lightmapCoord);
        int sl = LightTexture.getLightSky(lightmapCoord);
        int offset = LightUtil.getLightOffset(0) * 4; // int offset for vertex 0 * 4 bytes per int
        int blBaked = Short.toUnsignedInt(data.getShort(offset)) >> 4;
        int slBaked = Short.toUnsignedInt(data.getShort(offset + 2)) >> 4;
        bl = Math.max(bl, blBaked);
        sl = Math.max(sl, slBaked);
        return LightTexture.packLight(bl, sl);
    }

 

It works fine now...

 

-TGG

 

2020-06-13_13_43_31.png.22d1a6e1f7845bd661978507894c5193.png

  • Thanks 1
  • Quote

Share this post


Link to post
Share on other sites

PianoManu    0

PianoManu

PianoManu    0

  • Tree Puncher
  • PianoManu
  • Members
  • 0
  • 24 posts
Posted June 13, 2020

Oh my... I'm so stupid. Thank you very much, that solved it! Many thanks for your effort!! :D

 

Problem is solved, thread can be closed!

  • Quote

Share this post


Link to post
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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  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.

    • Insert image from URL
×
  • Desktop
  • Tablet
  • Phone
Sign in to follow this  
Followers 0
Go To Topic Listing



  • Recently Browsing

    No registered users viewing this page.

  • Posts

    • JeffMan
      [1.15] replacing chunks

      By JeffMan · Posted 5 minutes ago

      I am familiar with java and other oop languages, but not familiar with how forge + Minecraft works.    I am trying to port Bobby [fabric] to forge: https://www.curseforge.com/minecraft/mc-mods/bobby   Goal: ----------  - Load chunks from a saved singleplayer world into array?  - replace chunks in player current world (connected to server but only show for client) with a chunk from the array outside of server view distance. - unload chunks from client side as needed as player moves.   Is this possible with version 1.15 forge api or is there a library addon that I can use ?  
    • diesieben07
      Server Console errors

      By diesieben07 · Posted 7 minutes ago

      Please post the server debug.log.
    • diesieben07
      1.16.4 "The Vanilla Experience" Server problem

      By diesieben07 · Posted 12 minutes ago

      Looks like you have a client-only mod ("Omega Mute") installed on the server. If this is a pre-made modpack, make sure it does not have a dedicated server pack. If it doesn't, report this to the pack owners.
    • diesieben07
      Minecraft forge server login problem

      By diesieben07 · Posted 14 minutes ago

      User was banned for supporting piracy. Buy the game.
    • Gęsioł
      1.16.4 "The Vanilla Experience" Server problem

      By Gęsioł · Posted 15 minutes ago

      crash-2021-01-16_21.08.57-fml.txt Was fallowing instructions in description. Cannot load
  • Topics

    • JeffMan
      0
      [1.15] replacing chunks

      By JeffMan
      Started 5 minutes ago

    • chuckdie5el
      1
      Server Console errors

      By chuckdie5el
      Started 17 minutes ago

    • Gęsioł
      1
      1.16.4 "The Vanilla Experience" Server problem

      By Gęsioł
      Started 15 minutes ago

    • Greenshark3D
      5
      Minecraft forge server login problem

      By Greenshark3D
      Started 1 hour ago

    • Badnews4u
      3
      My forge server won't load all the mods

      By Badnews4u
      Started 17 hours ago

  • Who's Online (See full list)

    • Chumbanotz
    • JeffMan
    • ambermarsh
    • Talp1
    • Rokas_Lithuania
    • diesieben07
    • Draco18s
    • Sr_endi
    • MrLoop95
    • chuckdie5el
    • Greenshark3D
    • Aggeldos
    • Gęsioł
    • Abdymazhit
    • Caleb949
  • All Activity
  • Home
  • Mod Developer Central
  • Modder Support
  • (1.15.1)[Solved] Baked Model is too dark
  • Theme

Copyright © 2019 ForgeDevelopment LLC · Ads by Longitude Ads LLC Powered by Invision Community