Jump to content

[1.15.1] Transparent baked models/quads


PianoManu

Recommended Posts

Hey guys, I'm again having a question concerning baked quads/models. How do I create transparent quads?

This fence block I created takes the texture of the block it is clicked with (it can mimic blocks), but for glass and ice, the block appears solid. How can I make them transparent? Here you can see an example screenshot of the problem so far.

2020-08-28_12.18.03.png

I made a class that implements IDynamicBakedModel and for the getQuads(...)-method I made a method "createCuboid()" that returns a list of baked quads

The createCuboid(...)-method:

public static List<BakedQuad> createCuboid(float xl, float xh, float yl, float yh, float zl, float zh, TextureAtlasSprite texture, int tintIndex) {
   List<BakedQuad> quads = new ArrayList<>();
   //Eight corners of the block
   Vec3d NWU = v(xl, yh, zl); //North-West-Up
   Vec3d NEU = v(xl, yh, zh); //...
   Vec3d NWD = v(xl, yl, zl);
   Vec3d NED = v(xl, yl, zh);
   Vec3d SWU = v(xh, yh, zl);
   Vec3d SEU = v(xh, yh, zh);
   Vec3d SWD = v(xh, yl, zl);
   Vec3d SED = v(xh, yl, zh); //South-East-Down
   //following if statements check whether one of the values goes over the block bounds -> increment/decrement them
   if (xl < 0) {
       xl++;
   }
   if (xh > 1) {
       xh--;
   }
   if (yl < 0) {
       yl++;
   }
   if (yh > 1) {
       yh--;
   }
   if (zl < 0) {
       zl++;
   }
   if (zh > 1) {
       zh--;
   }
   //six faces of the block, createQuad(...)-method is shown below
   //	            1st vector, 2nd,  3rd, 4th,    , small u, high u, small v,  high v, 
   quads.add(createQuad(NWU, NEU, SEU, SWU, texture, xl * 16, xh * 16, zl * 16, zh * 16, tintIndex));
   quads.add(createQuad(SWD, SED, NED, NWD, texture, xl * 16, xh * 16, zl * 16, zh * 16, tintIndex));
   quads.add(createQuad(SWU, SWD, NWD, NWU, texture, xl * 16, xh * 16, 16 - yh * 16, 16 - yl * 16, tintIndex));
   quads.add(createQuad(NEU, NED, SED, SEU, texture, xl * 16, xh * 16, 16 - yh * 16, 16 - yl * 16, tintIndex));
   quads.add(createQuad(NWU, NWD, NED, NEU, texture, zl * 16, zh * 16, 16 - yh * 16, 16 - yl * 16, tintIndex));
   quads.add(createQuad(SEU, SED, SWD, SWU, texture, zl * 16, zh * 16, 16 - yh * 16, 16 - yl * 16, tintIndex));
   return quads;
}

The createQuad(...)-method:

private static BakedQuad createQuad(Vec3d v1, Vec3d v2, Vec3d v3, Vec3d v4, TextureAtlasSprite sprite, float ulow, float uhigh, float vlow, float vhigh, int tintIndex) {    
    //normal vector for vertices and orientation
    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));
    //I've tried adding diffuse lighting but it didn't change much
    builder.setApplyDiffuseLighting(true);
    //only for tintable blocks like grass
    if (tintIndex > -1) {
        builder.setQuadTint(tintIndex);
    }
    //constructing vertices for the quad
    putVertex(builder, normal, v1.x, v1.y, v1.z, ulow, vlow, sprite, 1.0f, 1.0f, 1.0f);
    putVertex(builder, normal, v2.x, v2.y, v2.z, ulow, vhigh, sprite, 1.0f, 1.0f, 1.0f);
    putVertex(builder, normal, v3.x, v3.y, v3.z, uhigh, vhigh, sprite, 1.0f, 1.0f, 1.0f);
    putVertex(builder, normal, v4.x, v4.y, v4.z, uhigh, vlow, sprite, 1.0f, 1.0f, 1.0f);
    return builder.build();
}

And the putVertex(...)-method:

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

    //lift of all vertexFormatElements saved in the builder and created in the makeQuads(...)-method
    ImmutableList<VertexFormatElement> elements = builder.getVertexFormat().getElements().asList();
    for (int j = 0; j < elements.size(); j++) {
        //iterate through all elements and get the usage, add the corresponding values
        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);
                        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;
        }
    }
}

For this method, I've got some help from a tutorial by TurtyWurty

 

Now as I said, I'm trying to get transparent quads. How would I achieve that?

Thanks in advance, Manu

Edited by PianoManu
Format
Link to comment
Share on other sites

28 minutes ago, PianoManu said:

builder.put(j, r, g, b, 1.0f);

1.0f sets the alpha channel if I'm not mistaken. However, if the block is in the solid render type, it will render through the entire ground. You would need to put it in the correct render layer as well (in this case the ice would be in RenderType#TRANSLUCENT).

  • Thanks 1
Link to comment
Share on other sites

I'm so stupid, you're right. Thank you so much! It works for glass, but the ice fence is still not translucent... I've changed the alpha value to 0.0f and it's working fine for glass.

2020-08-28_16_11_11.png.b3038ed38722012f8915055f804b8fcb.png

I also changed the render layer as you said:

public static void setup() {
    RenderTypeLookup.setRenderLayer(Registration.FENCE_FRAMEBLOCK.get(), RenderType.getTranslucent());
}

This method is called when the FMLClientSetupEvent is fired. Did I forget something concerning the ice block? As I wrote in the first post, it only needs to be translucent for ice and glass blocks and it is already very nice, that it works for glass. Thank you so much!

Regards, Manu

Edited by PianoManu
Added screenshot
Link to comment
Share on other sites

Glass is rendered in a different layer than ice by default. It probably works for glass since the pixel is either completely completely opaque or transparent. Ice works differently since it has variable opacity. However, your pixels seem to be only grabbing the pixel colors and not the alpha. Another scenario is that you are grabbing the alpha; however, setRenderLayer was not set. The fix I showed uses the tint index alpha channel to set pixels. It could be that this value must be 1.0f to be multiplied with the current texture alpha channel if the render layer is set. However, this is mainly speculation.

  • Like 1
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.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Hello everyone, I'm making this post to seek help for my modded block, It's a special block called FrozenBlock supposed to take the place of an old block, then after a set amount of ticks, it's supposed to revert its Block State, Entity, data... to the old block like this :  The problem I have is that the system breaks when handling multi blocks (I tried some fix but none of them worked) :  The bug I have identified is that the function "setOldBlockFields" in the item's "setFrozenBlock" function gets called once for the 1st block of multiblock getting frozen (as it should), but gets called a second time BEFORE creating the first FrozenBlock with the data of the 1st block, hence giving the same data to the two FrozenBlock :   Old Block Fields set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=head] BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@73681674 BlockEntityData : id:"minecraft:bed",x:3,y:-60,z:-6} Old Block Fields set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=foot] BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@6d1aa3da BlockEntityData : {id:"minecraft:bed",x:2,y:-60,z:-6} Frozen Block Entity set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=foot] BlockPos{x=3, y=-60, z=-6} BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@6d1aa3da BlockEntityData : {id:"minecraft:bed",x:2,y:-60,z:-6} Frozen Block Entity set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=foot] BlockPos{x=2, y=-60, z=-6} BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@6d1aa3da BlockEntityData : {id:"minecraft:bed",x:2,y:-60,z:-6} here is the code inside my custom "freeze" item :    @Override     public @NotNull InteractionResult useOn(@NotNull UseOnContext pContext) {         if (!pContext.getLevel().isClientSide() && pContext.getHand() == InteractionHand.MAIN_HAND) {             BlockPos blockPos = pContext.getClickedPos();             BlockPos secondBlockPos = getMultiblockPos(blockPos, pContext.getLevel().getBlockState(blockPos));             if (secondBlockPos != null) {                 createFrozenBlock(pContext, secondBlockPos);             }             createFrozenBlock(pContext, blockPos);             return InteractionResult.SUCCESS;         }         return super.useOn(pContext);     }     public static void createFrozenBlock(UseOnContext pContext, BlockPos blockPos) {         BlockState oldState = pContext.getLevel().getBlockState(blockPos);         BlockEntity oldBlockEntity = oldState.hasBlockEntity() ? pContext.getLevel().getBlockEntity(blockPos) : null;         CompoundTag oldBlockEntityData = oldState.hasBlockEntity() ? oldBlockEntity.serializeNBT() : null;         if (oldBlockEntity != null) {             pContext.getLevel().removeBlockEntity(blockPos);         }         BlockState FrozenBlock = setFrozenBlock(oldState, oldBlockEntity, oldBlockEntityData);         pContext.getLevel().setBlockAndUpdate(blockPos, FrozenBlock);     }     public static BlockState setFrozenBlock(BlockState blockState, @Nullable BlockEntity blockEntity, @Nullable CompoundTag blockEntityData) {         BlockState FrozenBlock = BlockRegister.FROZEN_BLOCK.get().defaultBlockState();         ((FrozenBlock) FrozenBlock.getBlock()).setOldBlockFields(blockState, blockEntity, blockEntityData);         return FrozenBlock;     }  
    • It is an issue with quark - update it to this build: https://www.curseforge.com/minecraft/mc-mods/quark/files/3642325
    • Remove Instant Massive Structures Mod from your server     Add new crash-reports with sites like https://paste.ee/  
    • Update your drivers: https://www.amd.com/en/support/graphics/amd-radeon-r9-series/amd-radeon-r9-200-series/amd-radeon-r9-280x
  • Topics

×
×
  • Create New...

Important Information

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