Skip to content

Commit

Permalink
Improve efficiency and fix some texture glitches when rendering wind …
Browse files Browse the repository at this point in the history
…and rainbow trail particles
  • Loading branch information
Sollace committed Dec 20, 2024
1 parent 14685d8 commit ed15923
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
import org.joml.Vector3f;

import com.minelittlepony.unicopia.client.render.RenderUtil;
import com.mojang.blaze3d.systems.RenderSystem;

import net.minecraft.client.particle.Particle;
import net.minecraft.client.particle.ParticleTextureSheet;
import net.minecraft.client.render.BufferBuilder;
import net.minecraft.client.render.BufferRenderer;
import net.minecraft.client.render.GameRenderer;
import net.minecraft.client.render.Tessellator;
import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.render.VertexFormat;
Expand Down Expand Up @@ -42,6 +44,7 @@ protected final void renderQuad(Tessellator te, Vector3f[] corners, float alpha,

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

protected final void renderQuad(Tessellator te, RenderUtil.Vertex[] corners, float alpha, float tickDelta) {
int light = getBrightness(tickDelta);
RenderSystem.setShader(GameRenderer::getPositionTexColorProgram);
BufferBuilder buffer = te.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR_LIGHT);
quad(buffer, corners, alpha, tickDelta, light);
BufferRenderer.drawWithGlobalProgram(buffer.end());
}

protected final void quad(BufferBuilder buffer, RenderUtil.Vertex[] corners, float alpha, float tickDelta, int light) {
for (RenderUtil.Vertex corner : corners) {
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);
}
BufferRenderer.drawWithGlobalProgram(buffer.end());
}

protected final void renderQuad(VertexConsumer buffer, Vector3f[] corners, float alpha, float tickDelta) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,14 @@
import com.minelittlepony.unicopia.client.render.bezier.BezierSegment;
import com.minelittlepony.unicopia.client.render.bezier.Trail;
import com.minelittlepony.unicopia.particle.TargetBoundParticleEffect;
import com.mojang.blaze3d.systems.RenderSystem;

import net.minecraft.client.render.BufferBuilder;
import net.minecraft.client.render.BufferRenderer;
import net.minecraft.client.render.GameRenderer;
import net.minecraft.client.render.Tessellator;
import net.minecraft.client.render.VertexFormat;
import net.minecraft.client.render.VertexFormats;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.entity.Entity;
import net.minecraft.util.Identifier;
Expand All @@ -20,6 +26,8 @@
public class RainbowTrailParticle extends AbstractBillboardParticle {
private static final Identifier TEXTURE = Unicopia.id("textures/particles/rainboom_trail.png");

private final BezierSegment bezier = new BezierSegment();

private final Trail trail;

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

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

@Nullable
BufferBuilder buffer = null;

for (int i = 0; i < segments.size() - 1; i++) {
BezierSegment corners = segments.get(i).getPlane(segments.get(i + 1));
float scale = getScale(tickDelta);
segments.get(i).getPlane(segments.get(i + 1), bezier);

corners.forEachCorner(corner -> {
for (var corner : bezier.corners()) {
corner.position().mul(scale).add(x, y, z);
});
}

if (buffer == null) {
RenderSystem.setShader(GameRenderer::getPositionTexColorProgram);
buffer = te.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR_LIGHT);
}

quad(buffer, bezier.corners(), segments.get(i).getAlpha() * alpha, tickDelta, light);
}

renderQuad(te, corners.corners(), segments.get(i).getAlpha() * alpha, tickDelta);
if (buffer != null) {
BufferRenderer.drawWithGlobalProgram(buffer.end());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,15 @@
import com.minelittlepony.unicopia.client.render.bezier.BezierSegment;
import com.minelittlepony.unicopia.client.render.bezier.Trail;
import com.minelittlepony.unicopia.particle.TargetBoundParticleEffect;
import com.mojang.blaze3d.systems.RenderSystem;

import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.BufferBuilder;
import net.minecraft.client.render.BufferRenderer;
import net.minecraft.client.render.GameRenderer;
import net.minecraft.client.render.Tessellator;
import net.minecraft.client.render.VertexFormat;
import net.minecraft.client.render.VertexFormats;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.entity.Entity;
import net.minecraft.util.Identifier;
Expand All @@ -19,6 +25,8 @@
public class WindParticle extends AbstractBillboardParticle {
private static final Identifier TEXTURE = Unicopia.id("textures/particle/wind.png");

private final BezierSegment bezier = new BezierSegment();

private final Trail trail;

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

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

@Nullable
BufferBuilder buffer = null;

for (int i = 0; i < segments.size() - 1; i++) {
BezierSegment corners = segments.get(i).getPlane(segments.get(i + 1));
float scale = getScale(tickDelta);
segments.get(i).getPlane(segments.get(i + 1), bezier);

corners.forEachCorner(corner -> {
for (var corner : bezier.corners()) {
corner.position().mul(scale).add(x, y, z);
});
}

if (buffer == null) {
RenderSystem.setShader(GameRenderer::getPositionTexColorProgram);
buffer = te.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR_LIGHT);
}

quad(buffer, bezier.corners(), segments.get(i).getAlpha() * alpha, tickDelta, light);
}

renderQuad(te, corners.corners(), segments.get(i).getAlpha() * alpha, tickDelta);
if (buffer != null) {
BufferRenderer.drawWithGlobalProgram(buffer.end());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@ public Vertex(float x, float y, float z, float u, float v) {
this(new Vector3f(x, y, z), new Vector3f(u, v, 1));
}

public Vertex() {
this(new Vector3f(), new Vector3f());
}

public void set(float x, float y, float z, float u, float v) {
position.set(x, y, z);
texture.set(u, v, 1);
}

public Vector4f position(Matrix4f mat) {
return mat.transform(TEMP_VECTOR.set(position, 1));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,20 @@
public record BezierSegment(
RenderUtil.Vertex[] corners
) {

public BezierSegment(Vector3f from, Vector3f to, float height) {
public BezierSegment() {
this(new RenderUtil.Vertex[] {
new RenderUtil.Vertex(from.x, from.y - height/2F, from.z, 0, 0), // bottom left
new RenderUtil.Vertex(from.x, from.y + height/2F, from.z, 1, 0), // top left
new RenderUtil.Vertex(to.x, to.y + height/2F, to.z, 1, 1), // top right
new RenderUtil.Vertex(to.x, to.y - height/2F, to.z, 0, 1) // bottom right
new RenderUtil.Vertex(), new RenderUtil.Vertex(),
new RenderUtil.Vertex(), new RenderUtil.Vertex()
});
}

public void set(Vector3f from, Vector3f to, float height) {
corners[0].set(from.x, from.y - height/2F, from.z, 0, 0); // bottom left
corners[1].set(from.x, from.y + height/2F, from.z, 1, 0); // top left
corners[2].set(to.x, to.y + height/2F, to.z, 1, 1); // top right
corners[3].set(to.x, to.y - height/2F, to.z, 0, 1); // bottom right
}

public void forEachCorner(Consumer<RenderUtil.Vertex> transformer) {
for (var corner : corners) {
transformer.accept(corner);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ boolean tick() {
return segments.indexOf(this) < segments.size() - 1 && age++ >= maxAge;
}

public BezierSegment getPlane(Segment to) {
return new BezierSegment(offset, to.offset, height);
public void getPlane(Segment to, BezierSegment segment) {
segment.set(offset, to.offset, height);
}
}
}

0 comments on commit ed15923

Please sign in to comment.