Skip to content

Commit ed15923

Browse files
committed
Improve efficiency and fix some texture glitches when rendering wind and rainbow trail particles
1 parent 14685d8 commit ed15923

File tree

6 files changed

+82
-19
lines changed

6 files changed

+82
-19
lines changed

src/main/java/com/minelittlepony/unicopia/client/particle/AbstractGeometryBasedParticle.java

+9-1
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33
import org.joml.Vector3f;
44

55
import com.minelittlepony.unicopia.client.render.RenderUtil;
6+
import com.mojang.blaze3d.systems.RenderSystem;
67

78
import net.minecraft.client.particle.Particle;
89
import net.minecraft.client.particle.ParticleTextureSheet;
910
import net.minecraft.client.render.BufferBuilder;
1011
import net.minecraft.client.render.BufferRenderer;
12+
import net.minecraft.client.render.GameRenderer;
1113
import net.minecraft.client.render.Tessellator;
1214
import net.minecraft.client.render.VertexConsumer;
1315
import net.minecraft.client.render.VertexFormat;
@@ -42,6 +44,7 @@ protected final void renderQuad(Tessellator te, Vector3f[] corners, float alpha,
4244

4345
protected final void renderQuad(MatrixStack matrices, Tessellator te, RenderUtil.Vertex[] corners, float alpha, float tickDelta) {
4446
int light = getBrightness(tickDelta);
47+
RenderSystem.setShader(GameRenderer::getPositionTexColorProgram);
4548
BufferBuilder buffer = te.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR_LIGHT);
4649
for (RenderUtil.Vertex corner : corners) {
4750
var position = corner.position(matrices.peek().getPositionMatrix());
@@ -52,11 +55,16 @@ protected final void renderQuad(MatrixStack matrices, Tessellator te, RenderUtil
5255

5356
protected final void renderQuad(Tessellator te, RenderUtil.Vertex[] corners, float alpha, float tickDelta) {
5457
int light = getBrightness(tickDelta);
58+
RenderSystem.setShader(GameRenderer::getPositionTexColorProgram);
5559
BufferBuilder buffer = te.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR_LIGHT);
60+
quad(buffer, corners, alpha, tickDelta, light);
61+
BufferRenderer.drawWithGlobalProgram(buffer.end());
62+
}
63+
64+
protected final void quad(BufferBuilder buffer, RenderUtil.Vertex[] corners, float alpha, float tickDelta, int light) {
5665
for (RenderUtil.Vertex corner : corners) {
5766
buffer.vertex(corner.position().x, corner.position().y, corner.position().z).texture(corner.texture().x, corner.texture().y).color(red, green, blue, alpha).light(light);
5867
}
59-
BufferRenderer.drawWithGlobalProgram(buffer.end());
6068
}
6169

6270
protected final void renderQuad(VertexConsumer buffer, Vector3f[] corners, float alpha, float tickDelta) {

src/main/java/com/minelittlepony/unicopia/client/particle/RainbowTrailParticle.java

+26-5
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,14 @@
99
import com.minelittlepony.unicopia.client.render.bezier.BezierSegment;
1010
import com.minelittlepony.unicopia.client.render.bezier.Trail;
1111
import com.minelittlepony.unicopia.particle.TargetBoundParticleEffect;
12+
import com.mojang.blaze3d.systems.RenderSystem;
1213

14+
import net.minecraft.client.render.BufferBuilder;
15+
import net.minecraft.client.render.BufferRenderer;
16+
import net.minecraft.client.render.GameRenderer;
1317
import net.minecraft.client.render.Tessellator;
18+
import net.minecraft.client.render.VertexFormat;
19+
import net.minecraft.client.render.VertexFormats;
1420
import net.minecraft.client.world.ClientWorld;
1521
import net.minecraft.entity.Entity;
1622
import net.minecraft.util.Identifier;
@@ -20,6 +26,8 @@
2026
public class RainbowTrailParticle extends AbstractBillboardParticle {
2127
private static final Identifier TEXTURE = Unicopia.id("textures/particles/rainboom_trail.png");
2228

29+
private final BezierSegment bezier = new BezierSegment();
30+
2331
private final Trail trail;
2432

2533
@Nullable
@@ -55,18 +63,31 @@ public boolean isAlive() {
5563
@Override
5664
protected void renderQuads(Tessellator te, float x, float y, float z, float tickDelta) {
5765
float alpha = this.alpha * (1 - (float)age / maxAge);
66+
int light = getBrightness(tickDelta);
67+
float scale = getScale(tickDelta);
5868

5969
List<Trail.Segment> segments = trail.getSegments();
6070

71+
@Nullable
72+
BufferBuilder buffer = null;
73+
6174
for (int i = 0; i < segments.size() - 1; i++) {
62-
BezierSegment corners = segments.get(i).getPlane(segments.get(i + 1));
63-
float scale = getScale(tickDelta);
75+
segments.get(i).getPlane(segments.get(i + 1), bezier);
6476

65-
corners.forEachCorner(corner -> {
77+
for (var corner : bezier.corners()) {
6678
corner.position().mul(scale).add(x, y, z);
67-
});
79+
}
80+
81+
if (buffer == null) {
82+
RenderSystem.setShader(GameRenderer::getPositionTexColorProgram);
83+
buffer = te.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR_LIGHT);
84+
}
85+
86+
quad(buffer, bezier.corners(), segments.get(i).getAlpha() * alpha, tickDelta, light);
87+
}
6888

69-
renderQuad(te, corners.corners(), segments.get(i).getAlpha() * alpha, tickDelta);
89+
if (buffer != null) {
90+
BufferRenderer.drawWithGlobalProgram(buffer.end());
7091
}
7192
}
7293

src/main/java/com/minelittlepony/unicopia/client/particle/WindParticle.java

+26-5
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,15 @@
77
import com.minelittlepony.unicopia.client.render.bezier.BezierSegment;
88
import com.minelittlepony.unicopia.client.render.bezier.Trail;
99
import com.minelittlepony.unicopia.particle.TargetBoundParticleEffect;
10+
import com.mojang.blaze3d.systems.RenderSystem;
1011

1112
import net.minecraft.client.MinecraftClient;
13+
import net.minecraft.client.render.BufferBuilder;
14+
import net.minecraft.client.render.BufferRenderer;
15+
import net.minecraft.client.render.GameRenderer;
1216
import net.minecraft.client.render.Tessellator;
17+
import net.minecraft.client.render.VertexFormat;
18+
import net.minecraft.client.render.VertexFormats;
1319
import net.minecraft.client.world.ClientWorld;
1420
import net.minecraft.entity.Entity;
1521
import net.minecraft.util.Identifier;
@@ -19,6 +25,8 @@
1925
public class WindParticle extends AbstractBillboardParticle {
2026
private static final Identifier TEXTURE = Unicopia.id("textures/particle/wind.png");
2127

28+
private final BezierSegment bezier = new BezierSegment();
29+
2230
private final Trail trail;
2331

2432
@Nullable
@@ -60,18 +68,31 @@ public boolean isAlive() {
6068
@Override
6169
protected void renderQuads(Tessellator te, float x, float y, float z, float tickDelta) {
6270
float alpha = this.alpha * (1 - (float)age / maxAge);
71+
int light = getBrightness(tickDelta);
72+
float scale = getScale(tickDelta);
6373

6474
List<Trail.Segment> segments = trail.getSegments();
6575

76+
@Nullable
77+
BufferBuilder buffer = null;
78+
6679
for (int i = 0; i < segments.size() - 1; i++) {
67-
BezierSegment corners = segments.get(i).getPlane(segments.get(i + 1));
68-
float scale = getScale(tickDelta);
80+
segments.get(i).getPlane(segments.get(i + 1), bezier);
6981

70-
corners.forEachCorner(corner -> {
82+
for (var corner : bezier.corners()) {
7183
corner.position().mul(scale).add(x, y, z);
72-
});
84+
}
85+
86+
if (buffer == null) {
87+
RenderSystem.setShader(GameRenderer::getPositionTexColorProgram);
88+
buffer = te.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR_LIGHT);
89+
}
90+
91+
quad(buffer, bezier.corners(), segments.get(i).getAlpha() * alpha, tickDelta, light);
92+
}
7393

74-
renderQuad(te, corners.corners(), segments.get(i).getAlpha() * alpha, tickDelta);
94+
if (buffer != null) {
95+
BufferRenderer.drawWithGlobalProgram(buffer.end());
7596
}
7697
}
7798

src/main/java/com/minelittlepony/unicopia/client/render/RenderUtil.java

+9
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,15 @@ public Vertex(float x, float y, float z, float u, float v) {
4747
this(new Vector3f(x, y, z), new Vector3f(u, v, 1));
4848
}
4949

50+
public Vertex() {
51+
this(new Vector3f(), new Vector3f());
52+
}
53+
54+
public void set(float x, float y, float z, float u, float v) {
55+
position.set(x, y, z);
56+
texture.set(u, v, 1);
57+
}
58+
5059
public Vector4f position(Matrix4f mat) {
5160
return mat.transform(TEMP_VECTOR.set(position, 1));
5261
}

src/main/java/com/minelittlepony/unicopia/client/render/bezier/BezierSegment.java

+10-6
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,20 @@
99
public record BezierSegment(
1010
RenderUtil.Vertex[] corners
1111
) {
12-
13-
public BezierSegment(Vector3f from, Vector3f to, float height) {
12+
public BezierSegment() {
1413
this(new RenderUtil.Vertex[] {
15-
new RenderUtil.Vertex(from.x, from.y - height/2F, from.z, 0, 0), // bottom left
16-
new RenderUtil.Vertex(from.x, from.y + height/2F, from.z, 1, 0), // top left
17-
new RenderUtil.Vertex(to.x, to.y + height/2F, to.z, 1, 1), // top right
18-
new RenderUtil.Vertex(to.x, to.y - height/2F, to.z, 0, 1) // bottom right
14+
new RenderUtil.Vertex(), new RenderUtil.Vertex(),
15+
new RenderUtil.Vertex(), new RenderUtil.Vertex()
1916
});
2017
}
2118

19+
public void set(Vector3f from, Vector3f to, float height) {
20+
corners[0].set(from.x, from.y - height/2F, from.z, 0, 0); // bottom left
21+
corners[1].set(from.x, from.y + height/2F, from.z, 1, 0); // top left
22+
corners[2].set(to.x, to.y + height/2F, to.z, 1, 1); // top right
23+
corners[3].set(to.x, to.y - height/2F, to.z, 0, 1); // bottom right
24+
}
25+
2226
public void forEachCorner(Consumer<RenderUtil.Vertex> transformer) {
2327
for (var corner : corners) {
2428
transformer.accept(corner);

src/main/java/com/minelittlepony/unicopia/client/render/bezier/Trail.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ boolean tick() {
6363
return segments.indexOf(this) < segments.size() - 1 && age++ >= maxAge;
6464
}
6565

66-
public BezierSegment getPlane(Segment to) {
67-
return new BezierSegment(offset, to.offset, height);
66+
public void getPlane(Segment to, BezierSegment segment) {
67+
segment.set(offset, to.offset, height);
6868
}
6969
}
7070
}

0 commit comments

Comments
 (0)