mirror of
https://github.com/Sollace/Unicopia.git
synced 2025-02-21 20:33:10 +01:00
Improve efficiency and fix some texture glitches when rendering wind and rainbow trail particles
This commit is contained in:
parent
14685d80fa
commit
ed15923f28
6 changed files with 82 additions and 19 deletions
|
@ -3,11 +3,13 @@ package com.minelittlepony.unicopia.client.particle;
|
|||
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;
|
||||
|
@ -42,6 +44,7 @@ public abstract class AbstractGeometryBasedParticle extends Particle {
|
|||
|
||||
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());
|
||||
|
@ -52,11 +55,16 @@ public abstract class AbstractGeometryBasedParticle extends Particle {
|
|||
|
||||
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) {
|
||||
|
|
|
@ -9,8 +9,14 @@ import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
|||
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;
|
||||
|
@ -20,6 +26,8 @@ import net.minecraft.util.math.Vec3d;
|
|||
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
|
||||
|
@ -55,18 +63,31 @@ public class RainbowTrailParticle extends AbstractBillboardParticle {
|
|||
@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);
|
||||
});
|
||||
}
|
||||
|
||||
renderQuad(te, corners.corners(), segments.get(i).getAlpha() * alpha, tickDelta);
|
||||
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);
|
||||
}
|
||||
|
||||
if (buffer != null) {
|
||||
BufferRenderer.drawWithGlobalProgram(buffer.end());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,9 +7,15 @@ import com.minelittlepony.unicopia.Unicopia;
|
|||
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;
|
||||
|
@ -19,6 +25,8 @@ import net.minecraft.util.math.Vec3d;
|
|||
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
|
||||
|
@ -60,18 +68,31 @@ public class WindParticle extends AbstractBillboardParticle {
|
|||
@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);
|
||||
});
|
||||
}
|
||||
|
||||
renderQuad(te, corners.corners(), segments.get(i).getAlpha() * alpha, tickDelta);
|
||||
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);
|
||||
}
|
||||
|
||||
if (buffer != null) {
|
||||
BufferRenderer.drawWithGlobalProgram(buffer.end());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -47,6 +47,15 @@ public class RenderUtil {
|
|||
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));
|
||||
}
|
||||
|
|
|
@ -9,16 +9,20 @@ import com.minelittlepony.unicopia.client.render.RenderUtil;
|
|||
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);
|
||||
|
|
|
@ -63,8 +63,8 @@ public class Trail {
|
|||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue