返回提交历史
Modified
gradle.properties
+1
-1
Modified
src/main/java/com/xfestudio/mydimension/client/MindPortalOverlay.java
+22
-15
Added
src/main/java/com/xfestudio/mydimension/client/MindPortalRenderType.java
+117
-0
Modified
src/main/java/com/xfestudio/mydimension/client/MindPortalRenderer.java
+32
-74
Modified
src/main/java/com/xfestudio/mydimension/client/ModClientEvents.java
+8
-0
Modified
src/main/java/com/xfestudio/mydimension/world/block/MindPortalBlock.java
+22
-15
Modified
src/main/java/com/xfestudio/mydimension/world/block/entity/MindPortalBlockEntity.java
+6
-0
Modified
src/main/resources/assets/mydimension/models/block/mind_portal.json
+1
-1
Modified
src/main/resources/assets/mydimension/models/block/mind_portal_frame.json
+3
-60
Added
src/main/resources/assets/mydimension/shaders/core/mind_portal.fsh
+120
-0
Added
src/main/resources/assets/mydimension/shaders/core/mind_portal.json
+20
-0
Added
src/main/resources/assets/mydimension/shaders/core/mind_portal.vsh
+15
-0
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
XFEstudio/MyDimension
实现 Mind Portal 全新自定义渲染与 Shader 特效
重构 Portal 渲染器与屏幕特效,移除原版 Nether Portal 贴图,新增并注册自定义 RenderType 和 GLSL Shader,支持动态粒子、流动、渐变等视觉效果。调整方块形状与粒子特效,优化 animateTick 逻辑。资源包新增/替换相关贴图与模型,Shader 配置 json 补充 uniform 和混合模式。整体提升性能与视觉一致性,效果更梦幻科幻,贴合 Mod 主题。
9e11272
代码差异
18 个文件
+464
-166
@@ -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
@@ -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
}
@@ -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
}
@@ -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
}
@@ -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);
@@ -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
@@ -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
}
@@ -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
}
@@ -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
}
@@ -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
}
@@ -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
}
@@ -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
}
二进制文件已变更,无法进行逐行预览。
二进制文件已变更,无法进行逐行预览。
二进制文件已变更,无法进行逐行预览。