mirror of
https://github.com/Sollace/Unicopia.git
synced 2025-02-17 10:24:23 +01:00
Fix dust appearing in the ground and fix clouds appearing black (use per-vertex lighting)
This commit is contained in:
parent
e97adc8841
commit
2754d41ee9
8 changed files with 124 additions and 33 deletions
|
@ -27,6 +27,7 @@ public abstract class AbstractBillboardParticle extends AbstractGeometryBasedPar
|
|||
RenderSystem.disableCull();
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.enableDepthTest();
|
||||
RenderSystem.defaultBlendFunc();
|
||||
|
||||
Vec3d cam = camera.getPos();
|
||||
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
package com.minelittlepony.unicopia.client.particle;
|
||||
|
||||
import org.joml.Vector4f;
|
||||
|
||||
import com.minelittlepony.common.util.Color;
|
||||
import com.minelittlepony.unicopia.client.render.RenderUtil;
|
||||
import com.minelittlepony.unicopia.client.render.model.FanModel;
|
||||
import com.minelittlepony.unicopia.client.render.model.VertexLightSource;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.render.BufferBuilder;
|
||||
import net.minecraft.client.render.Tessellator;
|
||||
import net.minecraft.client.render.VertexFormat;
|
||||
import net.minecraft.client.render.VertexFormats;
|
||||
import net.minecraft.client.texture.Sprite;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
|
@ -16,15 +21,15 @@ import net.minecraft.util.math.MathHelper;
|
|||
import net.minecraft.util.math.RotationAxis;
|
||||
|
||||
public class DustCloudParticle extends AbstractBillboardParticle {
|
||||
//private static final Identifier TEXTURE = new Identifier("textures/particle/big_smoke_3.png");
|
||||
|
||||
protected static final int SEGMENTS = 20;
|
||||
protected static final int SEPARATION = 270 / SEGMENTS;
|
||||
|
||||
private float scaleFactor;
|
||||
|
||||
protected Sprite sprite;
|
||||
private final RenderUtil.Vertex[] vertices;
|
||||
private final FanModel model;
|
||||
|
||||
private final VertexLightSource lightSource;
|
||||
|
||||
public DustCloudParticle(BlockStateParticleEffect effect, ClientWorld world, double x, double y, double z, double velocityX, double velocityY, double velocityZ) {
|
||||
super(world, x, y, z, velocityX, velocityY, velocityZ);
|
||||
|
@ -33,14 +38,15 @@ public class DustCloudParticle extends AbstractBillboardParticle {
|
|||
red = 0.6F;
|
||||
green = 0.6F;
|
||||
blue = 0.6F;
|
||||
alpha = (float)world.getRandom().nextTriangular(0.6, 0.2);
|
||||
alpha = (float)world.getRandom().nextTriangular(0.6, 0.2) * 0.3F;
|
||||
scaleFactor = (float)world.getRandom().nextTriangular(2, 1.2);
|
||||
sprite = MinecraftClient.getInstance().getBlockRenderManager().getModels().getModelParticleSprite(effect.getBlockState());
|
||||
vertices = new RenderUtil.Vertex[]{
|
||||
new RenderUtil.Vertex(-1, -1, 0, sprite.getMinU(), sprite.getMinV()),
|
||||
new RenderUtil.Vertex(-1, 1, 0, sprite.getMaxU(), sprite.getMinV()),
|
||||
new RenderUtil.Vertex( 1, 1, 0, sprite.getMaxU(), sprite.getMaxV()),
|
||||
new RenderUtil.Vertex( 1, -1, 0, sprite.getMinU(), sprite.getMaxV())
|
||||
lightSource = new VertexLightSource(world);
|
||||
model = new FanModel(sprite) {
|
||||
@Override
|
||||
protected int getLightAt(Vector4f pos, int light) {
|
||||
return lightSource.getLight(pos, light);
|
||||
}
|
||||
};
|
||||
if (!effect.getBlockState().isOf(Blocks.GRASS_BLOCK)) {
|
||||
int i = MinecraftClient.getInstance().getBlockColors().getColor(effect.getBlockState(), world, BlockPos.ofFloored(x, y, z), 0);
|
||||
|
@ -60,26 +66,29 @@ public class DustCloudParticle extends AbstractBillboardParticle {
|
|||
super.tick();
|
||||
scaleFactor += 0.001F;
|
||||
scale(MathHelper.clamp(age / 5F, 0, 1) * scaleFactor);
|
||||
lightSource.tick();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderQuads(Tessellator te, BufferBuilder buffer, float x, float y, float z, float tickDelta) {
|
||||
float scale = getScale(tickDelta);
|
||||
float scale = getScale(tickDelta) * 0.5F;
|
||||
float alpha = this.alpha * (1 - ((float)age / maxAge));
|
||||
MatrixStack matrices = new MatrixStack();
|
||||
matrices.translate(x, y, z);
|
||||
matrices.scale(scale, scale * 0.5F, scale);
|
||||
matrices.scale(1, 0.5F, 1);
|
||||
|
||||
float angle = ((this.age + tickDelta) % 360) / SEGMENTS;
|
||||
float angle = (MathHelper.sin((this.age + tickDelta) / 100F) * 360) / SEGMENTS;
|
||||
|
||||
for (int i = 0; i < SEGMENTS; i++) {
|
||||
matrices.push();
|
||||
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees((i * angle) % 360));
|
||||
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees((SEPARATION * i + angle) % 360));
|
||||
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees((SEPARATION * i + angle) % 360));
|
||||
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees((i * angle)));
|
||||
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees((SEPARATION * i - angle)));
|
||||
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees((SEPARATION * i + angle)));
|
||||
float ringScale = 1 + MathHelper.sin(((i * 10) + age + tickDelta) * 0.05F) * 0.1F;
|
||||
matrices.scale(ringScale, ringScale, ringScale);
|
||||
renderQuad(matrices, te, buffer, vertices, alpha, tickDelta);
|
||||
|
||||
buffer.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR_LIGHT);
|
||||
model.render(matrices, buffer, 0, scale * ringScale, 1, 1, 1, alpha);
|
||||
te.draw();
|
||||
matrices.pop();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ public class BakedModel {
|
|||
textureMatrix.identity();
|
||||
}
|
||||
|
||||
public final void render(MatrixStack matrices, VertexConsumer buffer, float scale, float r, float g, float b, float a) {
|
||||
public final void render(MatrixStack matrices, VertexConsumer buffer, int light, float scale, float r, float g, float b, float a) {
|
||||
scale = Math.abs(scale);
|
||||
if (scale < 0.001F) {
|
||||
return;
|
||||
|
@ -62,9 +62,13 @@ public class BakedModel {
|
|||
for (RenderUtil.Vertex vertex : vertices) {
|
||||
Vector4f pos = vertex.position(positionmatrix);
|
||||
Vector4f tex = vertex.texture(textureMatrix);
|
||||
buffer.vertex(pos.x, pos.y, pos.z).texture(tex.x, tex.y).color(r, g, b, a).next();
|
||||
buffer.vertex(pos.x, pos.y, pos.z).texture(tex.x, tex.y).color(r, g, b, a).light(getLightAt(pos, light)).next();
|
||||
}
|
||||
matrices.pop();
|
||||
textureMatrix.identity();
|
||||
}
|
||||
|
||||
protected int getLightAt(Vector4f pos, int light) {
|
||||
return light;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
package com.minelittlepony.unicopia.client.render.model;
|
||||
|
||||
import com.minelittlepony.unicopia.client.render.RenderUtil;
|
||||
|
||||
import net.minecraft.client.texture.Sprite;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.util.math.RotationAxis;
|
||||
|
||||
public class FanModel extends BakedModel {
|
||||
|
||||
public FanModel(Sprite sprite) {
|
||||
RenderUtil.Vertex[] dorito = createDorito(sprite);
|
||||
MatrixStack matrices = new MatrixStack();
|
||||
for (int d = 0; d < 12; d++) {
|
||||
matrices.push();
|
||||
|
||||
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(30 * d));
|
||||
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(15));
|
||||
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(15 * d));
|
||||
matrices.translate(2.9F, 0, 0);
|
||||
for (RenderUtil.Vertex corner : dorito) {
|
||||
var position = corner.position(matrices.peek().getPositionMatrix());
|
||||
addVertex(position.x, position.y(), position.z(), corner.texture().x, corner.texture().y);
|
||||
}
|
||||
matrices.pop();
|
||||
}
|
||||
}
|
||||
|
||||
static RenderUtil.Vertex[] createDorito(Sprite sprite) {
|
||||
float chunkSize = 1F;
|
||||
float baseLength = 0.8F;
|
||||
float uLength = sprite.getMaxU() - sprite.getMinU();
|
||||
return new RenderUtil.Vertex[]{
|
||||
new RenderUtil.Vertex(-chunkSize, -chunkSize * baseLength, 0, sprite.getMinU() + uLength * baseLength, sprite.getMinV()),
|
||||
new RenderUtil.Vertex( chunkSize, 0, 0, sprite.getMaxU(), sprite.getMaxV()),
|
||||
new RenderUtil.Vertex(-chunkSize, chunkSize * baseLength, 0, sprite.getMinU(), sprite.getMinV()),
|
||||
new RenderUtil.Vertex(-chunkSize * 3, 0, 0, sprite.getMinU(), sprite.getMaxV())
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package com.minelittlepony.unicopia.client.render.model;
|
||||
|
||||
import org.joml.Vector4f;
|
||||
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.render.WorldRenderer;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
public class VertexLightSource {
|
||||
private final ClientWorld world;
|
||||
private final Long2ObjectMap<Integer> lightCache = new Long2ObjectOpenHashMap<>();
|
||||
|
||||
public VertexLightSource(ClientWorld world) {
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
lightCache.clear();
|
||||
}
|
||||
|
||||
public int getLight(Vector4f vertexPosition, int light) {
|
||||
return lightCache.computeIfAbsent(getBlockPosition(vertexPosition), this::getLight);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private int getLight(long p) {
|
||||
final BlockPos pos = BlockPos.fromLong(p);
|
||||
return world.isChunkLoaded(pos) ? WorldRenderer.getLightmapCoordinates(world, pos) : 0;
|
||||
}
|
||||
|
||||
private long getBlockPosition(Vector4f vertexPosition) {
|
||||
Vec3d cameraPos = MinecraftClient.getInstance().gameRenderer.getCamera().getPos();
|
||||
return BlockPos.asLong(
|
||||
MathHelper.floor(cameraPos.x + vertexPosition.x),
|
||||
MathHelper.floor(cameraPos.y + vertexPosition.y),
|
||||
MathHelper.floor(cameraPos.z + vertexPosition.z)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -3,23 +3,16 @@ package com.minelittlepony.unicopia.client.render.shader;
|
|||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import net.fabricmc.fabric.api.client.rendering.v1.CoreShaderRegistrationCallback;
|
||||
import net.minecraft.client.gl.ShaderProgram;
|
||||
import net.minecraft.client.render.VertexFormat;
|
||||
import net.minecraft.client.render.VertexFormats;
|
||||
|
||||
public final class UShaders {
|
||||
@Nullable
|
||||
private static Supplier<ShaderProgram> renderTypePortalSurfaceProgram = register("rendertype_portal_surface", VertexFormats.POSITION_COLOR);
|
||||
public interface UShaders {
|
||||
Supplier<ShaderProgram> RENDER_TYPE_PORTAL_SURFACE = register("rendertype_portal_surface", VertexFormats.POSITION_COLOR);
|
||||
|
||||
public static ShaderProgram getRenderTypePortalSurfaceProgram() {
|
||||
return renderTypePortalSurfaceProgram.get();
|
||||
}
|
||||
|
||||
public static void bootstrap() { }
|
||||
static void bootstrap() { }
|
||||
|
||||
static Supplier<ShaderProgram> register(String name, VertexFormat format) {
|
||||
AtomicReference<ShaderProgram> holder = new AtomicReference<>();
|
||||
|
|
|
@ -94,14 +94,14 @@ class PortalFrameBuffer implements AutoCloseable {
|
|||
BufferBuilder buffer = tessellator.getBuffer();
|
||||
float uScale = (float)framebuffer.viewportWidth / (float)framebuffer.textureWidth;
|
||||
float vScale = (float)framebuffer.viewportHeight / (float)framebuffer.textureHeight;
|
||||
RenderSystem.setShader(UShaders::getRenderTypePortalSurfaceProgram);
|
||||
RenderSystem.setShader(UShaders.RENDER_TYPE_PORTAL_SURFACE);
|
||||
//RenderSystem.setShader(GameRenderer::getPositionTexColorProgram);
|
||||
RenderSystem._setShaderTexture(0, framebuffer.getColorAttachment());
|
||||
buffer.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR);
|
||||
SphereModel.DISK.scaleUV(uScale, vScale);
|
||||
|
||||
RenderSystem.setTextureMatrix(SphereModel.DISK.getTextureMatrix());
|
||||
SphereModel.DISK.render(matrices, buffer, 2F, 1, 1, 1, 1);
|
||||
SphereModel.DISK.render(matrices, buffer, 1, 2F, 1, 1, 1, 1);
|
||||
tessellator.draw();
|
||||
|
||||
client.getTextureManager().bindTexture(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE);
|
||||
|
|
|
@ -567,7 +567,7 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
|||
if (entity.isOnGround() || !force) {
|
||||
BlockState steppingState = pony.asEntity().getSteppingBlockState();
|
||||
if (steppingState.isIn(UTags.KICKS_UP_DUST)) {
|
||||
pony.addParticle(new BlockStateParticleEffect(UParticles.DUST_CLOUD, steppingState), pony.getOrigin().down().toCenterPos(), Vec3d.ZERO);
|
||||
pony.addParticle(new BlockStateParticleEffect(UParticles.DUST_CLOUD, steppingState), pony.getOrigin().toCenterPos(), Vec3d.ZERO);
|
||||
} else {
|
||||
Supplier<Vec3d> pos = VecHelper.sphere(pony.asWorld().getRandom(), 0.5D);
|
||||
Supplier<Vec3d> vel = VecHelper.sphere(pony.asWorld().getRandom(), 0.015D);
|
||||
|
|
Loading…
Reference in a new issue