XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

MyDimension

【Java】我的维度模组

公开
关注 0 Fork 0 Star 0
返回提交历史

XFEstudio/MyDimension

实现 Mind Portal 全新自定义渲染与 Shader 特效

重构 Portal 渲染器与屏幕特效,移除原版 Nether Portal 贴图,新增并注册自定义 RenderType 和 GLSL Shader,支持动态粒子、流动、渐变等视觉效果。调整方块形状与粒子特效,优化 animateTick 逻辑。资源包新增/替换相关贴图与模型,Shader 配置 json 补充 uniform 和混合模式。整体提升性能与视觉一致性,效果更梦幻科幻,贴合 Mod 主题。

9e11272
XFE工作室室长 <mail@xfegzs.com>
提交于

代码差异

18 个文件 +464 -166
Modified gradle.properties +1 -1
@@ -11,7 +11,7 @@ loader_version_range=[47,)
11 11 mod_id=mydimension
12 12 mod_name=\u6211\u7684\u7ef4\u5ea6
13 13 mod_license=CC0-1.0
14 mod_version=2.4.0
14 mod_version=2.4.1
15 15 mod_group_id=com.xfestudio.mydimension
16 16 maven_group=com.xfestudio
17 17 archives_base_name=mydimension
Modified src/main/java/com/xfestudio/mydimension/client/MindPortalOverlay.java +22 -15
@@ -1,20 +1,17 @@
1 1 package com.xfestudio.mydimension.client;
2 2
3 import com.mojang.blaze3d.systems.RenderSystem;
3 import com.mojang.blaze3d.vertex.VertexConsumer;
4 4 import com.xfestudio.mydimension.registry.ModBlocks;
5 5 import net.minecraft.client.Minecraft;
6 6 import net.minecraft.client.gui.GuiGraphics;
7 import net.minecraft.client.renderer.texture.TextureAtlas;
8 import net.minecraft.client.renderer.texture.TextureAtlasSprite;
9 7 import net.minecraft.core.BlockPos;
10 import net.minecraft.resources.ResourceLocation;
11 8 import net.minecraft.util.Mth;
12 9 import net.minecraft.world.entity.player.Player;
13 10 import net.minecraft.world.phys.AABB;
14 11 import net.minecraftforge.client.gui.overlay.IGuiOverlay;
12 import org.joml.Matrix4f;
15 13
16 14 public final class MindPortalOverlay {
17 private static final ResourceLocation PORTAL_SPRITE = new ResourceLocation("minecraft", "block/nether_portal");
18 15 private static final float CHARGE_STEP = 1.0F / 40.0F;
19 16 private static final float FADE_STEP = 0.1F;
20 17
@@ -84,15 +81,25 @@ public final class MindPortalOverlay {
84 81 }
85 82 alpha = Mth.clamp(alpha * pulse, 0.0F, 1.0F);
86 83
87 TextureAtlasSprite sprite = minecraft.getTextureAtlas(TextureAtlas.LOCATION_BLOCKS).apply(PORTAL_SPRITE);
88 RenderSystem.disableDepthTest();
89 RenderSystem.depthMask(false);
90 RenderSystem.enableBlend();
91 RenderSystem.defaultBlendFunc();
92 graphics.setColor(0.76F, 0.9F, 1.0F, alpha);
93 graphics.blit(0, 0, -90, screenWidth, screenHeight, sprite);
94 graphics.setColor(1.0F, 1.0F, 1.0F, 1.0F);
95 RenderSystem.depthMask(true);
96 RenderSystem.enableDepthTest();
84 drawDynamicOverlay(graphics, screenWidth, screenHeight, alpha * 0.88F);
85 }
86
87 private static void drawDynamicOverlay(GuiGraphics graphics, int screenWidth, int screenHeight, float alpha) {
88 graphics.flush();
89 if (!MindPortalRenderType.setOverlayState(alpha)) {
90 return;
91 }
92
93 try {
94 Matrix4f matrix = graphics.pose().last().pose();
95 VertexConsumer consumer = graphics.bufferSource().getBuffer(MindPortalRenderType.overlay());
96 consumer.vertex(matrix, 0.0F, 0.0F, 0.0F).endVertex();
97 consumer.vertex(matrix, 0.0F, screenHeight, 0.0F).endVertex();
98 consumer.vertex(matrix, screenWidth, screenHeight, 0.0F).endVertex();
99 consumer.vertex(matrix, screenWidth, 0.0F, 0.0F).endVertex();
100 graphics.flush();
101 } finally {
102 MindPortalRenderType.resetOverlayAlpha();
103 }
97 104 }
98 105 }
Added src/main/java/com/xfestudio/mydimension/client/MindPortalRenderType.java +117 -0
@@ -0,0 +1,117 @@
1 package com.xfestudio.mydimension.client;
2
3 import com.mojang.blaze3d.shaders.Uniform;
4 import com.mojang.blaze3d.systems.RenderSystem;
5 import com.mojang.blaze3d.vertex.DefaultVertexFormat;
6 import com.mojang.blaze3d.vertex.VertexFormat;
7 import com.xfestudio.mydimension.MyDimension;
8 import net.minecraft.client.renderer.RenderStateShard;
9 import net.minecraft.client.renderer.RenderType;
10 import net.minecraft.client.renderer.ShaderInstance;
11 import net.minecraft.resources.ResourceLocation;
12 import net.minecraftforge.client.event.RegisterShadersEvent;
13 import org.lwjgl.opengl.GL11;
14
15 import java.io.IOException;
16
17 public final class MindPortalRenderType {
18 private static final ResourceLocation SHADER = ResourceLocation.fromNamespaceAndPath(
19 MyDimension.MOD_ID, "mind_portal");
20 private static final ResourceLocation OVERLAY_SHADER = ResourceLocation.fromNamespaceAndPath(
21 MyDimension.MOD_ID, "mind_portal_overlay");
22 private static final ResourceLocation VOID_TEXTURE = ResourceLocation.fromNamespaceAndPath(
23 MyDimension.MOD_ID, "textures/entity/mind_portal_void.png");
24 private static final long OVERLAY_TIME_ORIGIN = System.nanoTime();
25
26 private static ShaderInstance shaderInstance;
27 private static ShaderInstance overlayShaderInstance;
28
29 private static final RenderStateShard.MultiTextureStateShard PORTAL_TEXTURES =
30 RenderStateShard.MultiTextureStateShard.builder()
31 .add(VOID_TEXTURE, false, false)
32 .add(VOID_TEXTURE, false, false)
33 .build();
34
35 private static final RenderType PORTAL = RenderType.create(
36 "mydimension_mind_portal",
37 DefaultVertexFormat.POSITION,
38 VertexFormat.Mode.QUADS,
39 256,
40 false,
41 false,
42 RenderType.CompositeState.builder()
43 .setShaderState(new RenderStateShard.ShaderStateShard(() -> shaderInstance))
44 .setTextureState(PORTAL_TEXTURES)
45 .createCompositeState(false));
46
47 private static final RenderType OVERLAY = RenderType.create(
48 "mydimension_mind_portal_overlay",
49 DefaultVertexFormat.POSITION,
50 VertexFormat.Mode.QUADS,
51 256,
52 false,
53 false,
54 RenderType.CompositeState.builder()
55 .setShaderState(new RenderStateShard.ShaderStateShard(() -> overlayShaderInstance))
56 .setTextureState(PORTAL_TEXTURES)
57 .setTransparencyState(new RenderStateShard.TransparencyStateShard(
58 "mydimension_mind_portal_overlay_transparency",
59 () -> {
60 RenderSystem.enableBlend();
61 RenderSystem.defaultBlendFunc();
62 },
63 () -> {
64 RenderSystem.disableBlend();
65 RenderSystem.defaultBlendFunc();
66 }))
67 .setDepthTestState(new RenderStateShard.DepthTestStateShard(
68 "mydimension_mind_portal_overlay_depth", GL11.GL_ALWAYS))
69 .setCullState(new RenderStateShard.CullStateShard(false))
70 .setWriteMaskState(new RenderStateShard.WriteMaskStateShard(true, false))
71 .createCompositeState(false));
72
73 private MindPortalRenderType() {
74 }
75
76 public static RenderType get() {
77 return PORTAL;
78 }
79
80 public static RenderType overlay() {
81 return OVERLAY;
82 }
83
84 public static boolean setOverlayState(float alpha) {
85 if (overlayShaderInstance == null) {
86 return false;
87 }
88 Uniform alphaUniform = overlayShaderInstance.getUniform("PortalAlpha");
89 Uniform timeUniform = overlayShaderInstance.getUniform("PortalTime");
90 if (alphaUniform == null || timeUniform == null) {
91 return false;
92 }
93 alphaUniform.set(alpha);
94 float elapsedSeconds = (System.nanoTime() - OVERLAY_TIME_ORIGIN) / 1_000_000_000.0F;
95 timeUniform.set(elapsedSeconds);
96 return true;
97 }
98
99 public static void resetOverlayAlpha() {
100 if (overlayShaderInstance == null) {
101 return;
102 }
103 Uniform uniform = overlayShaderInstance.getUniform("PortalAlpha");
104 if (uniform != null) {
105 uniform.set(1.0F);
106 }
107 }
108
109 public static void registerShader(RegisterShadersEvent event) throws IOException {
110 event.registerShader(
111 new ShaderInstance(event.getResourceProvider(), SHADER, DefaultVertexFormat.POSITION),
112 shader -> shaderInstance = shader);
113 event.registerShader(
114 new ShaderInstance(event.getResourceProvider(), OVERLAY_SHADER, DefaultVertexFormat.POSITION),
115 shader -> overlayShaderInstance = shader);
116 }
117 }
Modified src/main/java/com/xfestudio/mydimension/client/MindPortalRenderer.java +32 -74
@@ -4,22 +4,18 @@ import com.mojang.blaze3d.vertex.PoseStack;
4 4 import com.mojang.blaze3d.vertex.VertexConsumer;
5 5 import com.xfestudio.mydimension.world.block.MindPortalBlock;
6 6 import com.xfestudio.mydimension.world.block.entity.MindPortalBlockEntity;
7 import net.minecraft.client.Minecraft;
8 import net.minecraft.client.renderer.LightTexture;
9 7 import net.minecraft.client.renderer.MultiBufferSource;
10 import net.minecraft.client.renderer.RenderType;
11 8 import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
12 9 import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
13 import net.minecraft.client.renderer.texture.OverlayTexture;
14 import net.minecraft.client.renderer.texture.TextureAtlas;
15 import net.minecraft.client.renderer.texture.TextureAtlasSprite;
16 10 import net.minecraft.core.Direction;
17 import net.minecraft.resources.ResourceLocation;
18 import org.joml.Matrix3f;
19 11 import org.joml.Matrix4f;
20 12
13 /**
14 * Renders every portal block as one continuous projection-driven surface. The custom shader
15 * follows the End Portal rendering approach, so moving the camera reveals real parallax depth.
16 */
21 17 public class MindPortalRenderer implements BlockEntityRenderer<MindPortalBlockEntity> {
22 private static final ResourceLocation PORTAL_SPRITE = new ResourceLocation("minecraft", "block/nether_portal");
18 private static final float SURFACE_DEPTH = 0.5F;
23 19
24 20 public MindPortalRenderer(BlockEntityRendererProvider.Context context) {
25 21 }
@@ -27,80 +23,42 @@ public class MindPortalRenderer implements BlockEntityRenderer<MindPortalBlockEn
27 23 @Override
28 24 public void render(MindPortalBlockEntity blockEntity, float partialTick, PoseStack poseStack,
29 25 MultiBufferSource buffer, int packedLight, int packedOverlay) {
30 if (blockEntity.linkId() == null || !blockEntity.getBlockState().getValue(MindPortalBlock.CORE)) {
31 return;
32 }
33
34 TextureAtlasSprite sprite = Minecraft.getInstance()
35 .getTextureAtlas(TextureAtlas.LOCATION_BLOCKS)
36 .apply(PORTAL_SPRITE);
37 VertexConsumer consumer = buffer.getBuffer(RenderType.entityTranslucent(TextureAtlas.LOCATION_BLOCKS));
38 long gameTime = blockEntity.getLevel() == null ? 0L : blockEntity.getLevel().getGameTime();
39 float pulse = (float) Math.sin((gameTime + partialTick) * 0.055D);
26 Matrix4f matrix = poseStack.last().pose();
27 VertexConsumer consumer = buffer.getBuffer(MindPortalRenderType.get());
40 28 Direction.Axis axis = blockEntity.getBlockState().getValue(MindPortalBlock.AXIS);
41 29
42 poseStack.pushPose();
43 renderLayer(poseStack, consumer, sprite, axis, 0.486F + pulse * 0.012F,
44 82, 214, 255, 205, false);
45 renderLayer(poseStack, consumer, sprite, axis, 0.514F - pulse * 0.009F,
46 160, 92, 255, 135, true);
47 poseStack.popPose();
30 if (axis == Direction.Axis.X) {
31 renderAxisX(matrix, consumer);
32 } else {
33 renderAxisZ(matrix, consumer);
34 }
48 35 }
49 36
50 @Override
51 public boolean shouldRenderOffScreen(MindPortalBlockEntity blockEntity) {
52 return true;
53 }
37 private static void renderAxisX(Matrix4f matrix, VertexConsumer consumer) {
38 vertex(consumer, matrix, 0.0F, 0.0F, SURFACE_DEPTH);
39 vertex(consumer, matrix, 1.0F, 0.0F, SURFACE_DEPTH);
40 vertex(consumer, matrix, 1.0F, 1.0F, SURFACE_DEPTH);
41 vertex(consumer, matrix, 0.0F, 1.0F, SURFACE_DEPTH);
54 42
55 @Override
56 public int getViewDistance() {
57 return 128;
43 vertex(consumer, matrix, 0.0F, 1.0F, SURFACE_DEPTH);
44 vertex(consumer, matrix, 1.0F, 1.0F, SURFACE_DEPTH);
45 vertex(consumer, matrix, 1.0F, 0.0F, SURFACE_DEPTH);
46 vertex(consumer, matrix, 0.0F, 0.0F, SURFACE_DEPTH);
58 47 }
59 48
60 private static void renderLayer(PoseStack poseStack, VertexConsumer consumer, TextureAtlasSprite sprite,
61 Direction.Axis axis, float depth, int red, int green, int blue, int alpha,
62 boolean flipUv) {
63 PoseStack.Pose pose = poseStack.last();
64 Matrix4f matrix = pose.pose();
65 Matrix3f normal = pose.normal();
66 float u0 = flipUv ? sprite.getU1() : sprite.getU0();
67 float u1 = flipUv ? sprite.getU0() : sprite.getU1();
68 float v0 = sprite.getV0();
69 float v1 = sprite.getV1();
70
71 if (axis == Direction.Axis.X) {
72 vertex(consumer, matrix, normal, 0.0F, 0.0F, depth, u0, v1, red, green, blue, alpha, 0.0F, 0.0F, 1.0F);
73 vertex(consumer, matrix, normal, 3.0F, 0.0F, depth, u1, v1, red, green, blue, alpha, 0.0F, 0.0F, 1.0F);
74 vertex(consumer, matrix, normal, 3.0F, 4.0F, depth, u1, v0, red, green, blue, alpha, 0.0F, 0.0F, 1.0F);
75 vertex(consumer, matrix, normal, 0.0F, 4.0F, depth, u0, v0, red, green, blue, alpha, 0.0F, 0.0F, 1.0F);
76
77 vertex(consumer, matrix, normal, 0.0F, 4.0F, depth, u0, v0, red, green, blue, alpha, 0.0F, 0.0F, -1.0F);
78 vertex(consumer, matrix, normal, 3.0F, 4.0F, depth, u1, v0, red, green, blue, alpha, 0.0F, 0.0F, -1.0F);
79 vertex(consumer, matrix, normal, 3.0F, 0.0F, depth, u1, v1, red, green, blue, alpha, 0.0F, 0.0F, -1.0F);
80 vertex(consumer, matrix, normal, 0.0F, 0.0F, depth, u0, v1, red, green, blue, alpha, 0.0F, 0.0F, -1.0F);
81 } else {
82 vertex(consumer, matrix, normal, depth, 0.0F, 0.0F, u0, v1, red, green, blue, alpha, 1.0F, 0.0F, 0.0F);
83 vertex(consumer, matrix, normal, depth, 4.0F, 0.0F, u0, v0, red, green, blue, alpha, 1.0F, 0.0F, 0.0F);
84 vertex(consumer, matrix, normal, depth, 4.0F, 3.0F, u1, v0, red, green, blue, alpha, 1.0F, 0.0F, 0.0F);
85 vertex(consumer, matrix, normal, depth, 0.0F, 3.0F, u1, v1, red, green, blue, alpha, 1.0F, 0.0F, 0.0F);
49 private static void renderAxisZ(Matrix4f matrix, VertexConsumer consumer) {
50 vertex(consumer, matrix, SURFACE_DEPTH, 0.0F, 0.0F);
51 vertex(consumer, matrix, SURFACE_DEPTH, 1.0F, 0.0F);
52 vertex(consumer, matrix, SURFACE_DEPTH, 1.0F, 1.0F);
53 vertex(consumer, matrix, SURFACE_DEPTH, 0.0F, 1.0F);
86 54
87 vertex(consumer, matrix, normal, depth, 0.0F, 3.0F, u1, v1, red, green, blue, alpha, -1.0F, 0.0F, 0.0F);
88 vertex(consumer, matrix, normal, depth, 4.0F, 3.0F, u1, v0, red, green, blue, alpha, -1.0F, 0.0F, 0.0F);
89 vertex(consumer, matrix, normal, depth, 4.0F, 0.0F, u0, v0, red, green, blue, alpha, -1.0F, 0.0F, 0.0F);
90 vertex(consumer, matrix, normal, depth, 0.0F, 0.0F, u0, v1, red, green, blue, alpha, -1.0F, 0.0F, 0.0F);
91 }
55 vertex(consumer, matrix, SURFACE_DEPTH, 0.0F, 1.0F);
56 vertex(consumer, matrix, SURFACE_DEPTH, 1.0F, 1.0F);
57 vertex(consumer, matrix, SURFACE_DEPTH, 1.0F, 0.0F);
58 vertex(consumer, matrix, SURFACE_DEPTH, 0.0F, 0.0F);
92 59 }
93 60
94 private static void vertex(VertexConsumer consumer, Matrix4f matrix, Matrix3f normal,
95 float x, float y, float z, float u, float v,
96 int red, int green, int blue, int alpha,
97 float normalX, float normalY, float normalZ) {
98 consumer.vertex(matrix, x, y, z)
99 .color(red, green, blue, alpha)
100 .uv(u, v)
101 .overlayCoords(OverlayTexture.NO_OVERLAY)
102 .uv2(LightTexture.FULL_BRIGHT)
103 .normal(normal, normalX, normalY, normalZ)
104 .endVertex();
61 private static void vertex(VertexConsumer consumer, Matrix4f matrix, float x, float y, float z) {
62 consumer.vertex(matrix, x, y, z).endVertex();
105 63 }
106 64 }
Modified src/main/java/com/xfestudio/mydimension/client/ModClientEvents.java +8 -0
@@ -6,10 +6,13 @@ import com.xfestudio.mydimension.registry.ModBlockEntities;
6 6 import net.minecraftforge.api.distmarker.Dist;
7 7 import net.minecraftforge.client.event.EntityRenderersEvent;
8 8 import net.minecraftforge.client.event.RegisterGuiOverlaysEvent;
9 import net.minecraftforge.client.event.RegisterShadersEvent;
9 10 import net.minecraftforge.client.gui.overlay.VanillaGuiOverlay;
10 11 import net.minecraftforge.eventbus.api.SubscribeEvent;
11 12 import net.minecraftforge.fml.common.Mod;
12 13
14 import java.io.IOException;
15
13 16 @Mod.EventBusSubscriber(modid = MyDimension.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD, value = Dist.CLIENT)
14 17 public class ModClientEvents {
15 18 @SubscribeEvent
@@ -18,6 +21,11 @@ public class ModClientEvents {
18 21 event.registerBlockEntityRenderer(ModBlockEntities.MIND_PORTAL.get(), MindPortalRenderer::new);
19 22 }
20 23
24 @SubscribeEvent
25 public static void registerShaders(RegisterShadersEvent event) throws IOException {
26 MindPortalRenderType.registerShader(event);
27 }
28
21 29 @SubscribeEvent
22 30 public static void registerOverlays(RegisterGuiOverlaysEvent event) {
23 31 event.registerAbove(VanillaGuiOverlay.PORTAL.id(), "mind_portal", MindPortalOverlay.OVERLAY);
Modified src/main/java/com/xfestudio/mydimension/world/block/MindPortalBlock.java +22 -15
@@ -4,7 +4,7 @@ import com.xfestudio.mydimension.world.block.entity.MindPortalBlockEntity;
4 4 import com.xfestudio.mydimension.world.portal.MindPortalManager;
5 5 import net.minecraft.core.BlockPos;
6 6 import net.minecraft.core.Direction;
7 import net.minecraft.core.particles.ParticleTypes;
7 import net.minecraft.core.particles.DustColorTransitionOptions;
8 8 import net.minecraft.server.level.ServerPlayer;
9 9 import net.minecraft.sounds.SoundEvents;
10 10 import net.minecraft.sounds.SoundSource;
@@ -13,6 +13,7 @@ import net.minecraft.world.entity.Entity;
13 13 import net.minecraft.world.level.BlockGetter;
14 14 import net.minecraft.world.level.Level;
15 15 import net.minecraft.world.level.block.BaseEntityBlock;
16 import net.minecraft.world.level.block.Block;
16 17 import net.minecraft.world.level.block.RenderShape;
17 18 import net.minecraft.world.level.block.entity.BlockEntity;
18 19 import net.minecraft.world.level.block.state.BlockState;
@@ -21,13 +22,17 @@ import net.minecraft.world.level.block.state.properties.BlockStateProperties;
21 22 import net.minecraft.world.level.block.state.properties.BooleanProperty;
22 23 import net.minecraft.world.level.block.state.properties.EnumProperty;
23 24 import net.minecraft.world.phys.shapes.CollisionContext;
24 import net.minecraft.world.phys.shapes.Shapes;
25 25 import net.minecraft.world.phys.shapes.VoxelShape;
26 26 import org.jetbrains.annotations.Nullable;
27 import org.joml.Vector3f;
27 28
28 29 public class MindPortalBlock extends BaseEntityBlock {
29 30 public static final EnumProperty<Direction.Axis> AXIS = BlockStateProperties.HORIZONTAL_AXIS;
30 31 public static final BooleanProperty CORE = BooleanProperty.create("core");
32 private static final VoxelShape X_SHAPE = Block.box(0.0D, 0.0D, 6.0D, 16.0D, 16.0D, 10.0D);
33 private static final VoxelShape Z_SHAPE = Block.box(6.0D, 0.0D, 0.0D, 10.0D, 16.0D, 16.0D);
34 private static final DustColorTransitionOptions MIND_DUST = new DustColorTransitionOptions(
35 new Vector3f(0.08F, 0.82F, 1.0F), new Vector3f(0.76F, 0.18F, 1.0F), 0.85F);
31 36
32 37 public MindPortalBlock(Properties properties) {
33 38 super(properties);
@@ -46,7 +51,7 @@ public class MindPortalBlock extends BaseEntityBlock {
46 51
47 52 @Override
48 53 public VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) {
49 return Shapes.empty();
54 return state.getValue(AXIS) == Direction.Axis.X ? X_SHAPE : Z_SHAPE;
50 55 }
51 56
52 57 @Override
@@ -58,22 +63,24 @@ public class MindPortalBlock extends BaseEntityBlock {
58 63
59 64 @Override
60 65 public void animateTick(BlockState state, Level level, BlockPos pos, RandomSource random) {
61 if (random.nextInt(36) == 0) {
66 if (state.getValue(CORE) && random.nextInt(36) == 0) {
62 67 level.playLocalSound(pos.getX() + 0.5D, pos.getY() + 0.5D, pos.getZ() + 0.5D,
63 68 SoundEvents.PORTAL_AMBIENT, SoundSource.BLOCKS, 0.35F, 0.8F + random.nextFloat() * 0.4F, false);
64 69 }
65 70
66 for (int i = 0; i < 2; i++) {
67 double x = pos.getX() + random.nextDouble();
68 double y = pos.getY() + random.nextDouble();
69 double z = pos.getZ() + random.nextDouble();
70 double normalSpeed = (random.nextDouble() - 0.5D) * 0.12D;
71 double verticalSpeed = (random.nextDouble() - 0.5D) * 0.04D;
72 if (state.getValue(AXIS) == Direction.Axis.X) {
73 level.addParticle(ParticleTypes.REVERSE_PORTAL, x, y, z, 0.0D, verticalSpeed, normalSpeed);
74 } else {
75 level.addParticle(ParticleTypes.REVERSE_PORTAL, x, y, z, normalSpeed, verticalSpeed, 0.0D);
76 }
71 if (random.nextInt(3) != 0) {
72 return;
73 }
74
75 double x = pos.getX() + random.nextDouble();
76 double y = pos.getY() + random.nextDouble();
77 double z = pos.getZ() + random.nextDouble();
78 double normalSpeed = (random.nextDouble() - 0.5D) * 0.055D;
79 double verticalSpeed = (random.nextDouble() - 0.5D) * 0.02D;
80 if (state.getValue(AXIS) == Direction.Axis.X) {
81 level.addParticle(MIND_DUST, x, y, z, 0.0D, verticalSpeed, normalSpeed);
82 } else {
83 level.addParticle(MIND_DUST, x, y, z, normalSpeed, verticalSpeed, 0.0D);
77 84 }
78 85 }
79 86
Modified src/main/java/com/xfestudio/mydimension/world/block/entity/MindPortalBlockEntity.java +6 -0
@@ -4,6 +4,7 @@ import com.xfestudio.mydimension.registry.ModBlockEntities;
4 4 import net.minecraft.core.BlockPos;
5 5 import net.minecraft.nbt.CompoundTag;
6 6 import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
7 import net.minecraft.world.phys.AABB;
7 8 import net.minecraft.world.level.block.entity.BlockEntity;
8 9 import net.minecraft.world.level.block.state.BlockState;
9 10
@@ -62,4 +63,9 @@ public class MindPortalBlockEntity extends BlockEntity {
62 63 public ClientboundBlockEntityDataPacket getUpdatePacket() {
63 64 return ClientboundBlockEntityDataPacket.create(this);
64 65 }
66
67 @Override
68 public AABB getRenderBoundingBox() {
69 return new AABB(worldPosition);
70 }
65 71 }
Modified src/main/resources/assets/mydimension/models/block/mind_portal.json +1 -1
@@ -1,7 +1,7 @@
1 1 {
2 2 "parent": "minecraft:block/block",
3 3 "textures": {
4 "particle": "minecraft:block/nether_portal"
4 "particle": "mydimension:block/mind_portal"
5 5 },
6 6 "elements": []
7 7 }
Modified src/main/resources/assets/mydimension/models/block/mind_portal_frame.json +3 -60
@@ -1,63 +1,6 @@
1 1 {
2 "parent": "minecraft:block/block",
3 "ambientocclusion": true,
2 "parent": "minecraft:block/cube_all",
4 3 "textures": {
5 "base": "minecraft:block/polished_blackstone_bricks",
6 "accent": "minecraft:block/amethyst_block",
7 "particle": "minecraft:block/polished_blackstone_bricks"
8 },
9 "elements": [
10 {
11 "from": [0, 0, 0],
12 "to": [16, 16, 16],
13 "faces": {
14 "down": { "texture": "#base", "cullface": "down" },
15 "up": { "texture": "#base", "cullface": "up" },
16 "north": { "texture": "#base", "cullface": "north" },
17 "south": { "texture": "#base", "cullface": "south" },
18 "west": { "texture": "#base", "cullface": "west" },
19 "east": { "texture": "#base", "cullface": "east" }
20 }
21 },
22 {
23 "from": [7, 2, -0.02],
24 "to": [9, 14, 0.02],
25 "faces": { "north": { "texture": "#accent" } }
26 },
27 {
28 "from": [2, 7, -0.03],
29 "to": [14, 9, 0.03],
30 "faces": { "north": { "texture": "#accent" } }
31 },
32 {
33 "from": [7, 2, 15.98],
34 "to": [9, 14, 16.02],
35 "faces": { "south": { "texture": "#accent" } }
36 },
37 {
38 "from": [2, 7, 15.97],
39 "to": [14, 9, 16.03],
40 "faces": { "south": { "texture": "#accent" } }
41 },
42 {
43 "from": [-0.02, 2, 7],
44 "to": [0.02, 14, 9],
45 "faces": { "west": { "texture": "#accent" } }
46 },
47 {
48 "from": [-0.03, 7, 2],
49 "to": [0.03, 9, 14],
50 "faces": { "west": { "texture": "#accent" } }
51 },
52 {
53 "from": [15.98, 2, 7],
54 "to": [16.02, 14, 9],
55 "faces": { "east": { "texture": "#accent" } }
56 },
57 {
58 "from": [15.97, 7, 2],
59 "to": [16.03, 9, 14],
60 "faces": { "east": { "texture": "#accent" } }
61 }
62 ]
4 "all": "mydimension:block/mind_portal_frame"
5 }
63 6 }
Added src/main/resources/assets/mydimension/shaders/core/mind_portal.fsh +120 -0
@@ -0,0 +1,120 @@
1 #version 150
2
3 #moj_import <matrix.glsl>
4
5 uniform sampler2D Sampler0;
6 uniform sampler2D Sampler1;
7
8 uniform float GameTime;
9 uniform int EndPortalLayers;
10
11 in vec4 texProj0;
12
13 const vec3[] PARTICLE_COLORS = vec3[](
14 vec3(0.42, 0.08, 0.96),
15 vec3(0.82, 0.16, 1.00),
16 vec3(0.06, 0.70, 1.00),
17 vec3(0.54, 0.10, 0.80),
18 vec3(0.95, 0.30, 0.84),
19 vec3(0.16, 0.32, 0.92)
20 );
21
22 const mat4 SCALE_TRANSLATE = mat4(
23 0.5, 0.0, 0.0, 0.25,
24 0.0, 0.5, 0.0, 0.25,
25 0.0, 0.0, 1.0, 0.0,
26 0.0, 0.0, 0.0, 1.0
27 );
28
29 float hash21(vec2 value) {
30 value = fract(value * vec2(123.34, 456.21));
31 value += dot(value, value + 45.32);
32 return fract(value.x * value.y);
33 }
34
35 mat4 mind_portal_layer(float layer) {
36 mat4 translate = mat4(
37 1.0, 0.0, 0.0, 11.0 / layer,
38 0.0, 1.0, 0.0, 7.0 / layer,
39 0.0, 0.0, 1.0, 0.0,
40 0.0, 0.0, 0.0, 1.0
41 );
42
43 mat2 rotate = mat2_rotate_z(radians((layer * layer * 137.0 + layer * 29.0) * 1.35));
44 mat2 scale = mat2(2.2 + layer * 0.42);
45
46 return mat4(scale * rotate) * translate * SCALE_TRANSLATE;
47 }
48
49 float particle_field(vec2 uv, float density, float seed, float size,
50 float threshold, float time) {
51 vec2 grid = uv * density;
52 vec2 cell = floor(grid);
53 vec2 local = fract(grid) - 0.5;
54
55 float random = hash21(cell + vec2(seed, seed * 1.73));
56 vec2 offset = vec2(
57 hash21(cell + vec2(seed * 2.31, 17.17)),
58 hash21(cell + vec2(31.71, seed * 3.13))
59 );
60 offset = (offset - 0.5) * 0.54;
61
62 vec2 delta = local - offset;
63 float squareDistance = max(abs(delta.x), abs(delta.y));
64 float radialDistance = length(delta);
65 float core = 1.0 - smoothstep(size * 0.38, size, squareDistance);
66 float halo = 1.0 - smoothstep(size, size * 3.0, radialDistance);
67
68 float verticalFlare = (1.0 - smoothstep(size * 0.20, size * 0.52, abs(delta.x)))
69 * (1.0 - smoothstep(size * 1.2, size * 3.8, abs(delta.y)));
70 float horizontalFlare = (1.0 - smoothstep(size * 0.20, size * 0.52, abs(delta.y)))
71 * (1.0 - smoothstep(size * 1.2, size * 3.8, abs(delta.x)));
72 float flare = (verticalFlare + horizontalFlare) * step(0.965, random) * 0.28;
73
74 float twinkle = 0.68 + 0.32 * sin(time * (1.6 + seed * 0.11) + random * 6.2831853);
75 return step(threshold, random) * (core + halo * 0.22 + flare) * twinkle;
76 }
77
78 out vec4 fragColor;
79
80 void main() {
81 float time = GameTime * 400.0;
82
83 vec4 backgroundCoords = texProj0;
84 backgroundCoords.xy += vec2(time * 0.004, -time * 0.0025) * backgroundCoords.w;
85 vec3 background = textureProj(Sampler0, backgroundCoords).rgb
86 * vec3(0.28, 0.18, 0.42) * 0.34;
87
88 vec4 hazeCoords = texProj0 * mind_portal_layer(7.0);
89 hazeCoords.xy += vec2(-time * 0.0015, time * 0.0020) * hazeCoords.w;
90 vec3 haze = textureProj(Sampler1, hazeCoords).rgb
91 * vec3(0.22, 0.05, 0.34) * 0.10;
92
93 vec3 color = vec3(0.0015, 0.0005, 0.0080) + background + haze;
94 for (int i = 0; i < EndPortalLayers && i < 6; i++) {
95 float layer = float(i + 1);
96 vec4 projected = texProj0 * mind_portal_layer(layer);
97 vec2 uv = projected.xy / projected.w;
98 vec2 direction = normalize(vec2(
99 cos(layer * 2.13 + 0.35),
100 sin(layer * 1.77 + 0.80)
101 ));
102 uv += direction * time * (0.030 + layer * 0.0045);
103
104 float depth = float(i) / max(float(EndPortalLayers - 1), 1.0);
105 float density = mix(9.0, 24.0, depth);
106 float size = mix(0.115, 0.052, depth);
107 float threshold = 0.80 + depth * 0.055;
108 if (i == 2) {
109 threshold += 0.07;
110 }
111
112 float particle = particle_field(
113 uv, density, layer * 4.71, size, threshold, time
114 );
115 float depthBrightness = mix(0.82, 0.42, depth);
116 color += PARTICLE_COLORS[i] * particle * depthBrightness;
117 }
118
119 fragColor = vec4(min(color, vec3(1.0)), 1.0);
120 }
Added src/main/resources/assets/mydimension/shaders/core/mind_portal.json +20 -0
@@ -0,0 +1,20 @@
1 {
2 "blend": {
3 "func": "add",
4 "srcrgb": "srcalpha",
5 "dstrgb": "1-srcalpha"
6 },
7 "vertex": "mydimension:mind_portal",
8 "fragment": "mydimension:mind_portal",
9 "attributes": [],
10 "samplers": [
11 { "name": "Sampler0" },
12 { "name": "Sampler1" }
13 ],
14 "uniforms": [
15 { "name": "ModelViewMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] },
16 { "name": "ProjMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] },
17 { "name": "GameTime", "type": "float", "count": 1, "values": [ 0.0 ] },
18 { "name": "EndPortalLayers", "type": "int", "count": 1, "values": [ 6 ] }
19 ]
20 }
Added src/main/resources/assets/mydimension/shaders/core/mind_portal.vsh +15 -0
@@ -0,0 +1,15 @@
1 #version 150
2
3 #moj_import <projection.glsl>
4
5 in vec3 Position;
6
7 uniform mat4 ModelViewMat;
8 uniform mat4 ProjMat;
9
10 out vec4 texProj0;
11
12 void main() {
13 gl_Position = ProjMat * ModelViewMat * vec4(Position, 1.0);
14 texProj0 = projection_from_position(gl_Position);
15 }
Added src/main/resources/assets/mydimension/shaders/core/mind_portal_overlay.fsh +62 -0
Added src/main/resources/assets/mydimension/shaders/core/mind_portal_overlay.json +20 -0
Added src/main/resources/assets/mydimension/shaders/core/mind_portal_overlay.vsh +15 -0
Added src/main/resources/assets/mydimension/textures/block/mind_portal.png +0 -0
二进制文件已变更,无法进行逐行预览。
Added src/main/resources/assets/mydimension/textures/block/mind_portal_frame.png +0 -0
二进制文件已变更,无法进行逐行预览。
Added src/main/resources/assets/mydimension/textures/entity/mind_portal_void.png +0 -0
二进制文件已变更,无法进行逐行预览。