Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hand Rendering #909

Merged
merged 60 commits into from
Nov 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
cd94a21
Add In Level Hand Renderering
maximumpower55 Oct 2, 2021
c46cb75
Disable Vanilla Hand Rendering
maximumpower55 Oct 2, 2021
9c35b4f
Fix major issues
maximumpower55 Oct 2, 2021
efc2999
Change Mixin
maximumpower55 Oct 2, 2021
1aada4c
Use Redirect
maximumpower55 Oct 2, 2021
52281af
Use a instance
maximumpower55 Oct 3, 2021
5a5c932
oops!
maximumpower55 Oct 3, 2021
315f986
Use a Accessor
maximumpower55 Oct 3, 2021
fbd2845
more fixes
maximumpower55 Oct 3, 2021
de4a0ee
Fix gbuffers_hand not applying on the held item
maximumpower55 Oct 4, 2021
ac6814e
texturedLit
maximumpower55 Oct 6, 2021
bf1f276
fix some issues with continuum
maximumpower55 Oct 9, 2021
276a514
rework fix some issues with continuum
maximumpower55 Oct 10, 2021
61aa1da
refactor
maximumpower55 Oct 17, 2021
1944fd0
rename setupProjectionMatrix to setupGlState
maximumpower55 Oct 17, 2021
d75b8b1
cleanup
maximumpower55 Oct 24, 2021
4fe1a78
Merge branch 'IrisShaders:trunk' into hand-rendering
maximumpower55 Oct 25, 2021
127b01d
better mixins
maximumpower55 Oct 25, 2021
7925c23
Resolve conflicts
maximumpower55 Oct 27, 2021
4330c1e
Resolve conflicts try 2
maximumpower55 Oct 27, 2021
e6076e5
Resolve conflicts
maximumpower55 Oct 27, 2021
2f9f0ee
Merge pull request #1 from IrisShaders/trunk
maximumpower55 Oct 27, 2021
9ece6fa
Disable Vanilla Hand Rendering Again
maximumpower55 Oct 27, 2021
a2281e2
Merge branch 'IrisShaders:trunk' into hand-rendering
maximumpower55 Nov 1, 2021
b8f894b
some changes
maximumpower55 Nov 2, 2021
dab75fa
better hand clipping (Thanks Ims)
maximumpower55 Nov 3, 2021
bbfed1d
Reset projection matrix after hand rendering
Nov 3, 2021
34b4946
Move hand rendering to right before translucents
Nov 3, 2021
1dd7a36
Initial support for hand_water, encapsulate
Nov 3, 2021
945a9df
fix rendertypes
maximumpower55 Nov 3, 2021
8ae0e4f
fix rendertypes 2
maximumpower55 Nov 3, 2021
5a10bff
Initial depthtex2 support
Nov 3, 2021
2d14bcd
Add stub comment
Nov 3, 2021
1c223a3
Resize and destroy no-hand depth texture when needed
Nov 3, 2021
9ab7611
cleanup
maximumpower55 Nov 4, 2021
a4ab7cb
Make a comment about the projection matrix, force hand program
Nov 5, 2021
09af08c
remove redundant code
maximumpower55 Nov 5, 2021
d6fe168
Simple hand translucent rendering
Nov 6, 2021
a75f310
Merge pull request #5 from IMS212/hand-rendering-redo
maximumpower55 Nov 6, 2021
2b4f03f
bit of renaming
maximumpower55 Nov 6, 2021
3d68cb8
fix render types this time i hope
maximumpower55 Nov 7, 2021
d000284
fix render bugs
maximumpower55 Nov 7, 2021
a959e4c
fix render bug with multi layered skins
maximumpower55 Nov 7, 2021
2c40afb
Fix block entities not having the hand shader
Nov 7, 2021
b6bf2b8
Fix block entities not having the hand shader, part 2
Nov 8, 2021
a18400a
Fix many review issues
Nov 15, 2021
2321d80
More changes
Nov 15, 2021
c411c82
Even more changes
Nov 15, 2021
9883f21
Reset draw calls as part of finalizing world pipeline
Nov 15, 2021
8bf9a35
Reset draw calls as part of starting world pipeline
Nov 15, 2021
f3785d1
Fix last review issues
maximumpower55 Nov 15, 2021
cf05524
Merge branch 'IrisShaders:trunk' into hand-rendering
maximumpower55 Nov 15, 2021
2cba3b5
Add ENTITIES_TRANSLUCENT
Nov 15, 2021
7a2ec9e
Merge remote-tracking branch 'max/hand-rendering' into hand-rendering
Nov 15, 2021
8a36472
Remove MixinItemBlockRenderTypes.java
Nov 15, 2021
68bbf94
Only apply ENTITY_TRANSLUCENT to entityTranslucentCull
Nov 15, 2021
9a884f6
Fix translucent hand rendering
Nov 15, 2021
4a2b9df
Merge branch 'IrisShaders:trunk' into hand-rendering
maximumpower55 Nov 16, 2021
d915f61
Remove leftover code
maximumpower55 Nov 16, 2021
d147d11
Put renderingSolide = false after ending batch
Nov 16, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/main/java/net/coderbot/iris/layer/GbufferProgram.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ public enum GbufferProgram {
ARMOR_GLINT,
EYES,
HAND,
HAND_TRANSLUCENT,
WEATHER
}
5 changes: 4 additions & 1 deletion src/main/java/net/coderbot/iris/layer/GbufferPrograms.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package net.coderbot.iris.layer;

import net.coderbot.iris.Iris;
import net.coderbot.iris.pipeline.HandRenderer;
import net.coderbot.iris.pipeline.WorldRenderingPipeline;

public class GbufferPrograms {
Expand All @@ -12,7 +13,9 @@ public class GbufferPrograms {
*/
private static GbufferProgram refine(GbufferProgram program) {
if (program == GbufferProgram.ENTITIES || program == GbufferProgram.TERRAIN || program == GbufferProgram.TRANSLUCENT_TERRAIN) {
if (entities) {
if (HandRenderer.INSTANCE.isActive()) {
return HandRenderer.INSTANCE.isRenderingSolid() ? GbufferProgram.HAND : GbufferProgram.HAND_TRANSLUCENT;
} else if (entities) {
return GbufferProgram.ENTITIES;
} else if (blockEntities) {
return GbufferProgram.BLOCK_ENTITIES;
Expand Down
25 changes: 25 additions & 0 deletions src/main/java/net/coderbot/iris/mixin/GameRendererAccessor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package net.coderbot.iris.mixin;

import com.mojang.blaze3d.vertex.PoseStack;

import net.minecraft.client.Camera;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.gen.Invoker;

import net.minecraft.client.renderer.GameRenderer;

@Mixin(GameRenderer.class)
public interface GameRendererAccessor {
@Accessor
boolean getPanoramicMode();

@Invoker
void invokeBobView(PoseStack poseStack, float tickDelta);

@Invoker
void invokeBobHurt(PoseStack poseStack, float tickDelta);

@Invoker
double invokeGetFov(Camera camera, float tickDelta, boolean bobView);
}
10 changes: 10 additions & 0 deletions src/main/java/net/coderbot/iris/mixin/MixinGameRenderer.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
package net.coderbot.iris.mixin;

import com.mojang.blaze3d.platform.GlUtil;

import net.coderbot.iris.Iris;
import net.coderbot.iris.pipeline.FixedFunctionWorldRenderingPipeline;

import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.Minecraft;
Expand All @@ -24,4 +29,9 @@ public class MixinGameRenderer {
Iris.logger.info("GPU: " + GlUtil.getRenderer() + " (Supports OpenGL " + GlUtil.getOpenGLVersion() + ")");
Iris.logger.info("OS: " + System.getProperty("os.name"));
}

@Redirect(method = "renderLevel", at = @At(value = "FIELD", target = "Lnet/minecraft/client/renderer/GameRenderer;renderHand:Z"))
private boolean disableVanillaHandRendering(GameRenderer gameRenderer) {
return Iris.getPipelineManager().getPipeline() instanceof FixedFunctionWorldRenderingPipeline;
}
}
25 changes: 25 additions & 0 deletions src/main/java/net/coderbot/iris/mixin/MixinItemInHandRenderer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package net.coderbot.iris.mixin;

import com.mojang.blaze3d.vertex.PoseStack;
import net.coderbot.iris.pipeline.HandRenderer;
import net.minecraft.client.player.AbstractClientPlayer;
import net.minecraft.client.renderer.ItemInHandRenderer;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.item.ItemStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(ItemInHandRenderer.class)
public class MixinItemInHandRenderer {
@Inject(method = "renderArmWithItem", at = @At("HEAD"), cancellable = true)
private void skipTranslucentHands(AbstractClientPlayer abstractClientPlayer, float f, float g, InteractionHand interactionHand, float h, ItemStack itemStack, float i, PoseStack poseStack, MultiBufferSource multiBufferSource, int j, CallbackInfo ci) {
if (HandRenderer.INSTANCE.isRenderingSolid() && HandRenderer.INSTANCE.isHandTranslucent(interactionHand)) {
ci.cancel();
} else if (!HandRenderer.INSTANCE.isRenderingSolid() && !HandRenderer.INSTANCE.isHandTranslucent(interactionHand)) {
ci.cancel();
}
}
}
7 changes: 7 additions & 0 deletions src/main/java/net/coderbot/iris/mixin/MixinLevelRenderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import net.coderbot.iris.Iris;
import net.coderbot.iris.gl.program.Program;
import net.coderbot.iris.layer.GbufferProgram;
import net.coderbot.iris.pipeline.HandRenderer;
import net.coderbot.iris.pipeline.WorldRenderingPipeline;
import net.coderbot.iris.uniforms.CapturedRenderingState;
import net.coderbot.iris.uniforms.SystemTimeUniforms;
Expand All @@ -16,7 +17,10 @@
import net.minecraft.client.Options;
import net.minecraft.client.renderer.*;
import net.minecraft.world.phys.Vec3;

import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
Expand Down Expand Up @@ -75,6 +79,7 @@ public class MixinLevelRenderer {
// render their waypoint beams.
@Inject(method = RENDER_LEVEL, at = @At(value = "RETURN", shift = At.Shift.BEFORE))
private void iris$endLevelRender(PoseStack poseStack, float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f projection, CallbackInfo callback) {
HandRenderer.INSTANCE.renderTranslucent(poseStack, tickDelta, camera, gameRenderer, pipeline);
Minecraft.getInstance().getProfiler().popPush("iris_final");
pipeline.finalizeLevelRendering();
pipeline = null;
Expand Down Expand Up @@ -209,6 +214,8 @@ public class MixinLevelRenderer {
boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer,
LightTexture lightTexture, Matrix4f projection,
CallbackInfo ci) {
pipeline.beginHand();
HandRenderer.INSTANCE.renderSolid(poseStack, tickDelta, camera, gameRenderer, pipeline);
Minecraft.getInstance().getProfiler().popPush("iris_pre_translucent");
pipeline.beginTranslucents();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package net.coderbot.iris.mixin.rendertype;

import net.coderbot.iris.layer.GbufferProgram;
import net.coderbot.iris.layer.GbufferPrograms;
import net.coderbot.iris.layer.IrisRenderTypeWrapper;
import net.coderbot.iris.layer.UseProgramRenderStateShard;

import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
Expand Down Expand Up @@ -138,12 +140,12 @@ private static RenderType wrap(RenderType wrapped, GbufferProgram program) {
"armorCutoutNoCull",
"entitySolid",
"entityCutout",
"itemEntityTranslucentCull",
"entityTranslucentCull",
"entitySmoothCutout",
"entityDecal",
"entityNoOutline",
"entityShadow",
"entityTranslucentCull",
"itemEntityTranslucentCull",
"text",
"textSeeThrough",
}, cancellable = true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ public class DeferredWorldRenderingPipeline implements WorldRenderingPipeline {
@Nullable
private final Pass blockEntities;
@Nullable
private final Pass hand;
@Nullable
private final Pass handTranslucent;
@Nullable
private final Pass glowingEntities;
@Nullable
private final Pass glint;
Expand Down Expand Up @@ -259,6 +263,8 @@ public DeferredWorldRenderingPipeline(ProgramSet programs) {
this.beaconBeam = programs.getGbuffersBeaconBeam().map(this::createPass).orElse(textured);
this.entities = programs.getGbuffersEntities().map(this::createPass).orElse(texturedLit);
this.blockEntities = programs.getGbuffersBlock().map(this::createPass).orElse(terrain);
this.hand = programs.getGbuffersHand().map(this::createPass).orElse(texturedLit);
this.handTranslucent = programs.getGbuffersHandWater().map(this::createPass).orElse(hand);
this.glowingEntities = programs.getGbuffersEntitiesGlowing().map(this::createPass).orElse(entities);
this.glint = programs.getGbuffersGlint().map(this::createPass).orElse(textured);
this.eyes = programs.getGbuffersEntityEyes().map(this::createPass).orElse(textured);
Expand Down Expand Up @@ -385,6 +391,9 @@ private Pass getPass(GbufferProgram program) {
case WEATHER:
return weather;
case HAND:
return hand;
case HAND_TRANSLUCENT:
return handTranslucent;
default:
// TODO
throw new UnsupportedOperationException("TODO: Unsupported gbuffer program: " + program);
Expand Down Expand Up @@ -654,11 +663,21 @@ private void prepareRenderTargets() {
}
}

@Override
public void beginHand() {
// We need to copy the current depth texture so that depthtex2 can contain the depth values for
// all non-translucent content without the hand, as required.
baseline.bindAsReadBuffer();
GlStateManager._bindTexture(renderTargets.getDepthTextureNoHand().getTextureId());
GL20C.glCopyTexImage2D(GL20C.GL_TEXTURE_2D, 0, GL20C.GL_DEPTH_COMPONENT, 0, 0, renderTargets.getCurrentWidth(), renderTargets.getCurrentHeight(), 0);
GlStateManager._bindTexture(0);
}

@Override
public void beginTranslucents() {
isBeforeTranslucent = false;

// We need to copy the current depth texture so that depthtex1 and depthtex2 can contain the depth values for
// We need to copy the current depth texture so that depthtex1 can contain the depth values for
// all non-translucent content, as required.
baseline.bindAsReadBuffer();
GlStateManager._bindTexture(renderTargets.getDepthTextureNoTranslucents().getTextureId());
Expand Down Expand Up @@ -709,6 +728,7 @@ public OptionalInt getForcedShadowRenderDistanceChunksForDisplay() {
public void beginLevelRendering() {
isRenderingWorld = true;
isBeforeTranslucent = true;
HandRenderer.INSTANCE.getBufferSource().resetDrawCalls();

checkWorld();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ public void endShadowRender() {
// stub: nothing to do here
}

@Override
public void beginHand() {
// stub: nothing to do here
}

@Override
public void beginTranslucents() {
// stub: nothing to do here
Expand Down
137 changes: 137 additions & 0 deletions src/main/java/net/coderbot/iris/pipeline/HandRenderer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
package net.coderbot.iris.pipeline;

import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;

import com.mojang.math.Matrix4f;
import net.coderbot.batchedentityrendering.impl.FullyBufferedMultiBufferSource;
import net.coderbot.iris.layer.GbufferProgram;
import net.coderbot.iris.mixin.GameRendererAccessor;
import net.coderbot.iris.uniforms.CapturedRenderingState;
import net.minecraft.client.Camera;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.*;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.GameType;

public class HandRenderer {
public static final HandRenderer INSTANCE = new HandRenderer();

private boolean ACTIVE;
private boolean renderingSolid;
private FullyBufferedMultiBufferSource bufferSource = new FullyBufferedMultiBufferSource();

private void setupGlState(GameRenderer gameRenderer, Camera camera, PoseStack poseStack, float tickDelta) {
final PoseStack.Pose pose = poseStack.last();

// We need to scale the matrix by 0.125 so the hand doesn't clip through blocks.
Matrix4f scaleMatrix = Matrix4f.createScaleMatrix(1F, 1F, 0.125F);
scaleMatrix.multiply(gameRenderer.getProjectionMatrix(camera, tickDelta, false));
gameRenderer.resetProjectionMatrix(scaleMatrix);

pose.pose().setIdentity();
pose.normal().setIdentity();

((GameRendererAccessor) gameRenderer).invokeBobHurt(poseStack, tickDelta);

if(Minecraft.getInstance().options.bobView) {
((GameRendererAccessor) gameRenderer).invokeBobView(poseStack, tickDelta);
}
}

private boolean canRender(Camera camera, GameRenderer gameRenderer) {
return !(camera.isDetached()
|| !(camera.getEntity() instanceof Player)
|| ((GameRendererAccessor)gameRenderer).getPanoramicMode()
|| Minecraft.getInstance().options.hideGui
|| (camera.getEntity() instanceof LivingEntity && ((LivingEntity)camera.getEntity()).isSleeping())
|| Minecraft.getInstance().gameMode.getPlayerMode() == GameType.SPECTATOR);
}

public boolean isHandTranslucent(InteractionHand hand) {
Item item = Minecraft.getInstance().player.getItemBySlot(hand == InteractionHand.OFF_HAND ? EquipmentSlot.OFFHAND : EquipmentSlot.MAINHAND).getItem();

if (item instanceof BlockItem) {
return ItemBlockRenderTypes.getChunkRenderType(((BlockItem) item).getBlock().defaultBlockState()) == RenderType.translucent();
}

return false;
}

public boolean isAnyHandTranslucent() {
return isHandTranslucent(InteractionHand.MAIN_HAND) || isHandTranslucent(InteractionHand.OFF_HAND);
}

public void renderSolid(PoseStack poseStack, float tickDelta, Camera camera, GameRenderer gameRenderer, WorldRenderingPipeline pipeline) {
if(!canRender(camera, gameRenderer) || pipeline instanceof FixedFunctionWorldRenderingPipeline) {
return;
}

ACTIVE = true;

poseStack.pushPose();

Minecraft.getInstance().getProfiler().push("iris_hand");

setupGlState(gameRenderer, camera, poseStack, tickDelta);

renderingSolid = true;

Minecraft.getInstance().getItemInHandRenderer().renderHandsWithItems(tickDelta, poseStack, bufferSource, Minecraft.getInstance().player, Minecraft.getInstance().getEntityRenderDispatcher().getPackedLightCoords(camera.getEntity(), tickDelta));

Minecraft.getInstance().getProfiler().pop();

gameRenderer.resetProjectionMatrix(CapturedRenderingState.INSTANCE.getGbufferProjection());

poseStack.popPose();

bufferSource.endBatch();

renderingSolid = false;

ACTIVE = false;
}

public void renderTranslucent(PoseStack poseStack, float tickDelta, Camera camera, GameRenderer gameRenderer, WorldRenderingPipeline pipeline) {
if(!canRender(camera, gameRenderer) || !isAnyHandTranslucent() || pipeline instanceof FixedFunctionWorldRenderingPipeline) {
return;
}

ACTIVE = true;

poseStack.pushPose();

Minecraft.getInstance().getProfiler().push("iris_hand_translucent");

setupGlState(gameRenderer, camera, poseStack, tickDelta);

Minecraft.getInstance().getItemInHandRenderer().renderHandsWithItems(tickDelta, poseStack, bufferSource, Minecraft.getInstance().player, Minecraft.getInstance().getEntityRenderDispatcher().getPackedLightCoords(camera.getEntity(), tickDelta));

poseStack.popPose();

Minecraft.getInstance().getProfiler().pop();

gameRenderer.resetProjectionMatrix(CapturedRenderingState.INSTANCE.getGbufferProjection());

bufferSource.endBatch();

ACTIVE = false;
}

public boolean isActive() {
return ACTIVE;
}

public boolean isRenderingSolid() {
return renderingSolid;
}

public FullyBufferedMultiBufferSource getBufferSource() {
return bufferSource;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ public interface WorldRenderingPipeline {
OptionalInt getForcedShadowRenderDistanceChunksForDisplay();
void beginShadowRender();
void endShadowRender();

void beginHand();

void beginTranslucents();
void pushProgram(GbufferProgram program);
void popProgram(GbufferProgram program);
Expand Down
Loading