Jump to content

ISBRH Alpha Blending Inconsistencies


Reika

Recommended Posts

I am having a problem with my ISBRH (ISimpleBlockRenderingHandler) pipe renders, in that the alpha of the liquid inside visibly flickers between two values as the camera moves, leading to a very broken appearance.

The liquid renders on pass 1, while the body of the pipe (which is rendering fine) renders on pass 0.

 

I have checked for things like multiple calls, lighting, blend mode, and everything else I can think of, and nothing has worked.

I used to have the Tessellator "reboot" with a .draw() and .startDrawingQuads() before doing my rendering (and doing it again after), and did not experience the issue. As of 1.7, however, the rewrites to the tessellator mean that such an approach immediately crashes:

 

 

java.lang.IllegalArgumentException
at java.util.PriorityQueue.<init>(Unknown Source)
at net.minecraft.client.renderer.Tessellator.getVertexState(Tessellator.java:203)
at net.minecraft.client.renderer.WorldRenderer.postRenderBlocks(WorldRenderer.java:274)
at net.minecraft.client.renderer.WorldRenderer.updateRenderer(WorldRenderer.java:230)
at net.minecraft.client.renderer.RenderGlobal.updateRenderers(RenderGlobal.java:1624)
at net.minecraft.client.renderer.EntityRenderer.renderWorld(EntityRenderer.java:1271)

 

 

 

Removing the .draw() and .startDrawing() calls fixes the crash, but introduces the alpha problems. Any ideas?

 

My code:

@Override
public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) {
	RenderableDuct tile = (RenderableDuct)world.getTileEntity(x, y, z);
	for (int i = 0; i < 6; i++) {
		if (renderPass == 0)
			this.renderFace(tile, world, x, y, z, dirs[i]);
		else {
			//Icon ico = tile.getOverlayIcon();
			//if (ico != null)
			//this.renderOverlay(tile, world, x, y, z, dirs[i], ico);
			if (tile.isFluidPipe()) {
				this.renderLiquid(tile, x, y, z, dirs[i]);
			}
		}
	}
	return true;
}

private void renderLiquid(RenderableDuct tile, int x, int y, int z, ForgeDirection dir) {
	Fluid f = tile.getFluidType();
	if (f == null)
		return;
	Tessellator v5 = Tessellator.instance;
	//v5.draw();

	float size = 0.75F/2F;
	float window = 0.5F/2F;
	float dl = size-window;
	float dd = 0.5F-size;
	double in = 0.5+size-0.01;
	double in2 = 0.5-size+0.01;
	double dd2 = in-in2;

	IIcon ico = f.getIcon();
	float u = ico.getMinU();
	float v = ico.getMinV();
	float u2 = ico.getMaxU();
	float v2 = ico.getMaxV();
	double du = dd2*(u2-u)/4D;

	GL11.glColor4f(1, 1, 1, 1);
	GL11.glEnable(GL11.GL_BLEND);
	GL11.glEnable(GL11.GL_CULL_FACE);
	GL11.glEnable(GL12.GL_RESCALE_NORMAL);
	//v5.startDrawingQuads();
	v5.addTranslation(x, y, z);
	int mix = tile.getPipeBlockType().getMixedBrightnessForBlock(Minecraft.getMinecraft().theWorld, x, y, z);
	ReikaLiquidRenderer.bindFluidTexture(f);
	v5.setColorOpaque(255, 255, 255);
	if (f.getLuminosity() > 0) {
		v5.setBrightness(240);
		//ReikaRenderHelper.disableLighting();
	}
	else {
		v5.setBrightness(mix);
	}

	v5.setNormal(dir.offsetX, -dir.offsetY, -dir.offsetZ);

--- lots of .addVertexWithUV ---

	v5.addTranslation(-x, -y, -z);
	//v5.draw();
	GL11.glDisable(GL11.GL_CULL_FACE);
	//v5.startDrawingQuads();

	//GL11.glEnable(GL11.GL_BLEND);
	//GL11.glEnable(GL12.GL_RESCALE_NORMAL);

 

 

Sample images:

x6TUhWQ.png

uzvXH2Z.png

Link to comment
Share on other sites

I faced the similar problem with rendering my items, and I fixed it by using:

 

GL11.glEnable(GL11.GL_BLEND);

GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);

 

So, maybe have something to do with Blending Function?

 

I. Stellarium for Minecraft: Configurable Universe for Minecraft! (WIP)

II. Stellar Sky, Better Star Rendering&Sky Utility mod, had separated from Stellarium.

Link to comment
Share on other sites

Hi

 

I haven't encountered the Tessellator stop-start problem yet, haven't tried it on 1.7.10 yet.  I would be surprised if there weren't a way around it (even though I don't know what it is :P)

 

The utility jabelar mentioned is

https://github.com/TheGreyGhost/SpeedyTools/blob/Working/src/speedytools/common/Utilities/OpenGLdebugging.java

 

I've used it in the past to check what the OpenGL settings are; it's not complete, but dumpAllIsEnabled() works and has showed up problems for me before- dump for a good render, dump for a bad render, and spot the difference.  Not sure it is likely to help you in this case, but it might be worth a go.

 

A general comment about alpha blending is that the order of rendering the faces is very important.  If you render the rear pane alpha first, then the front pane alpha next, it will look different to rendering the front pane alpha first and the back pane alpha second.  This is because of the effects of depth testing, and additionally the way alpha blending calculates the final colour.  You could try rendering just one pane and see if the problem persists.

 

Apart from that nothing is springing to mind unless you're doing something accidental like rendering the same pane twice directly on top of itself.

 

-TGG

 

 

 

 

 

 

 

Link to comment
Share on other sites

Hi

 

I haven't encountered the Tessellator stop-start problem yet, haven't tried it on 1.7.10 yet.  I would be surprised if there weren't a way around it (even though I don't know what it is :P)

 

The utility jabelar mentioned is

https://github.com/TheGreyGhost/SpeedyTools/blob/Working/src/speedytools/common/Utilities/OpenGLdebugging.java

 

I've used it in the past to check what the OpenGL settings are; it's not complete, but dumpAllIsEnabled() works and has showed up problems for me before- dump for a good render, dump for a bad render, and spot the difference.  Not sure it is likely to help you in this case, but it might be worth a go.

 

A general comment about alpha blending is that the order of rendering the faces is very important.  If you render the rear pane alpha first, then the front pane alpha next, it will look different to rendering the front pane alpha first and the back pane alpha second.  This is because of the effects of depth testing, and additionally the way alpha blending calculates the final colour.  You could try rendering just one pane and see if the problem persists.

 

Apart from that nothing is springing to mind unless you're doing something accidental like rendering the same pane twice directly on top of itself.

 

-TGG

I faced the similar problem with rendering my items, and I fixed it by using:

 

GL11.glEnable(GL11.GL_BLEND);

GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);

 

So, maybe have something to do with Blending Function?

As is stated in the first post, I have already checked for these. Blending is enabled and in default blend (alpha-on-background) mode. Nothing is being rendered twice per call. Positions are unchanged from code which has worked since 1.2.5.

 

Also, your link is broken.

 

EDIT:

Oh, this is just perfect. Now I get that TessellatorVertexState crash even when not rebooting the tessellator. No, I have not changed the code since making my first post, and until five minutes ago, it was working, because that pipe block is still in the world and always has been.

EDIT 2:

It even crashes no matter what, with no code running, as long as renderWorldBlock returns true (which if false prevents any rendering from even being done)!

Link to comment
Share on other sites

OK, an update:

I have found a hacky-though-harmless fix for the crash. Simply dump in four "scrap" vertices (I do it at 0,0,0) and then the TesselatorState creation will not crash. It also allowed me to run my normal tessellator reboot code, which allowed me to discover something:

 

When the reboot code is not active, the behavior described in my original post is observed. Turn the reboot code on, and then the flickering is between the correct alpha value and complete transparency.

 

This is a strong indicator of something running twice, or of some alpha threshold application, but I can again confirm that the code and vertices are NOT being called more than once per render cycle.

 

Also, the "flicker" is in fact as follows:

While the player is accelerating (velocity is changing in magnitude or direction), the "low alpha" state is rendered. When the player is standing still, or moving at a constant velocity, the "high alpha" state is rendered.

What the hell is going on here?

Link to comment
Share on other sites

Hi

 

Well that's confusing.  I'm out of ideas.

 

This link should work for that utility if you are still keen to try it.

https://github.com/TheGreyGhost/SpeedyTools/blob/master/src/speedytools/common/utilities/OpenGLdebugging.java

 

-TGG

The link works now, but I kind of need to fix my pipe renders. Does anyone else commonly use ISBRHs?

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

    • The error still remains. For additional information, I can send you some more code,  main class Afraid.java:  package org.mymod.afraid; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.MobCategory; import net.minecraft.world.entity.monster.Zombie; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.entity.EntityAttributeCreationEvent; import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.ForgeRegistries; import net.minecraftforge.registries.RegistryObject; @Mod("afraid") public class Afraid { public static final String MODID = "afraid"; public static final DeferredRegister<EntityType<?>> ENTITY_TYPES = DeferredRegister.create(ForgeRegistries.ENTITY_TYPES, MODID); public static final RegistryObject<EntityType<AfraidBoss>> AFRAID_BOSS = ENTITY_TYPES.register("afraid_boss", () -> EntityType.Builder.of(AfraidBoss::new, MobCategory.MONSTER) .sized(0.6F, 1.95F) // Size of the entity .build(new ResourceLocation(MODID, "afraid_boss").toString())); public Afraid() { IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus(); ENTITY_TYPES.register(modEventBus); modEventBus.addListener(this::commonSetup); MinecraftForge.EVENT_BUS.register(this); } private void commonSetup(final FMLCommonSetupEvent event) { // Additional common setup if needed } @Mod.EventBusSubscriber(modid = MODID, bus = Mod.EventBusSubscriber.Bus.MOD) public static class ModEvents { @SubscribeEvent public static void onRegisterAttributes(EntityAttributeCreationEvent event) { event.put(Afraid.AFRAID_BOSS.get(), AfraidBoss.createAttributes().build()); } } } EntityEvents.java:  package org.mymod.afraid; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.MobCategory; import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.ForgeRegistries; import net.minecraftforge.registries.RegistryObject; public class EntityEvents { public static final DeferredRegister<EntityType<?>> ENTITY_TYPES = DeferredRegister.create(ForgeRegistries.ENTITY_TYPES, Afraid.MODID); public static final RegistryObject<EntityType<AfraidBoss>> AFRAID_BOSS = ENTITY_TYPES.register("afraid_boss", () -> EntityType.Builder.of(AfraidBoss::new, MobCategory.MONSTER) .sized(0.6F, 1.95F) .build("afraid_boss")); } As for attributes, they are only in the boss class itself.
    • Hello, new coder and first time posting, sorry if I get stuff wrong Been having a really difficult time trying to figure out this potion effect. I want to give a potion effect that denies the wither effect on the player. I've looked over a lot of different tutorials, and through some other mods and made something that sort of works but it was based on applyEffectTick and the players would still take a tick of damage before the potion effect kicked in. When looking up other ways to do this I saw there was like the PotionEvent but whenever I try to use it, I get errors of how it cannot be defined. This is my code right now that doesn't work package io.github.AndroPups.tsmp_models.effect; import net.minecraft.world.effect.MobEffect; import net.minecraft.world.effect.MobEffectCategory; import net.minecraft.world.effect.MobEffects; import net.minecraft.world.entity.LivingEntity; public class NoWitherEffect extends MobEffect { public NoWitherEffect(MobEffectCategory mobEffectCategory, int color) { super(mobEffectCategory.BENEFICIAL, color); } public static void onPotionAdded(PotionEvent.PotionAddedEvent event) { LivingEntity entity = event.getEntityLiving(); MobEffect potionEffect = event.getPotionEffect().getEffect(); if (potionEffect == MobEffects.WITHER); { entity.removeEffect(MobEffects.WITHER); } } @Override public boolean isDurationEffectTick(int duration, int amplifier) { return true; } } And this code works but occasionally still applies damage because of ticking effect.   package io.github.AndroPups.tsmp_models.effect; import net.minecraft.world.effect.MobEffect; import net.minecraft.world.effect.MobEffectCategory; import net.minecraft.world.effect.MobEffects; import net.minecraft.world.entity.LivingEntity; public class NoWitherEffect extends MobEffect { public NoWitherEffect(MobEffectCategory mobEffectCategory, int color) { super(mobEffectCategory.BENEFICIAL, color); } @Override public void applyEffectTick(LivingEntity pLivingEntity, int pAmplifier) { if (!pLivingEntity.level().isClientSide()) { if (pLivingEntity.hasEffect(MobEffects.WITHER)); { pLivingEntity.getEffect(MobEffects.WITHER); } } } @Override public boolean isDurationEffectTick(int duration, int amplifier) { return true; } } I've tried to see if PotionEvent was removed from recent Forge updates but can't really find any information on it. Any information at all would be helpful! Thanks!
    • Right after "private final Item item;" you will need "private final float chance;" Then you will need to add that variable to your constructor the same way you did for Item. It should work after that.
    • I am playing on Mac, tried to install a mod to the Forge mod folder, restarted Minecraft to activate it and now the game is crashing on launch with error code 1. Because I'm on Mac, I can't remotely access the mods folder without having to get into the Minecraft title screen to click the mods tab. Is there any way I can extract the file remotely, or is there a way to uninstall Forge so I can reinstall it with no mods?
  • Topics

×
×
  • Create New...

Important Information

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