mirror of
https://github.com/Sollace/Unicopia.git
synced 2025-02-21 12:24:22 +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.disableCull();
|
||||||
RenderSystem.enableBlend();
|
RenderSystem.enableBlend();
|
||||||
RenderSystem.enableDepthTest();
|
RenderSystem.enableDepthTest();
|
||||||
|
RenderSystem.defaultBlendFunc();
|
||||||
|
|
||||||
Vec3d cam = camera.getPos();
|
Vec3d cam = camera.getPos();
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,16 @@
|
||||||
package com.minelittlepony.unicopia.client.particle;
|
package com.minelittlepony.unicopia.client.particle;
|
||||||
|
|
||||||
|
import org.joml.Vector4f;
|
||||||
|
|
||||||
import com.minelittlepony.common.util.Color;
|
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.block.Blocks;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.client.render.BufferBuilder;
|
import net.minecraft.client.render.BufferBuilder;
|
||||||
import net.minecraft.client.render.Tessellator;
|
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.texture.Sprite;
|
||||||
import net.minecraft.client.util.math.MatrixStack;
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
import net.minecraft.client.world.ClientWorld;
|
import net.minecraft.client.world.ClientWorld;
|
||||||
|
@ -16,15 +21,15 @@ import net.minecraft.util.math.MathHelper;
|
||||||
import net.minecraft.util.math.RotationAxis;
|
import net.minecraft.util.math.RotationAxis;
|
||||||
|
|
||||||
public class DustCloudParticle extends AbstractBillboardParticle {
|
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 SEGMENTS = 20;
|
||||||
protected static final int SEPARATION = 270 / SEGMENTS;
|
protected static final int SEPARATION = 270 / SEGMENTS;
|
||||||
|
|
||||||
private float scaleFactor;
|
private float scaleFactor;
|
||||||
|
|
||||||
protected Sprite sprite;
|
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) {
|
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);
|
super(world, x, y, z, velocityX, velocityY, velocityZ);
|
||||||
|
@ -33,14 +38,15 @@ public class DustCloudParticle extends AbstractBillboardParticle {
|
||||||
red = 0.6F;
|
red = 0.6F;
|
||||||
green = 0.6F;
|
green = 0.6F;
|
||||||
blue = 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);
|
scaleFactor = (float)world.getRandom().nextTriangular(2, 1.2);
|
||||||
sprite = MinecraftClient.getInstance().getBlockRenderManager().getModels().getModelParticleSprite(effect.getBlockState());
|
sprite = MinecraftClient.getInstance().getBlockRenderManager().getModels().getModelParticleSprite(effect.getBlockState());
|
||||||
vertices = new RenderUtil.Vertex[]{
|
lightSource = new VertexLightSource(world);
|
||||||
new RenderUtil.Vertex(-1, -1, 0, sprite.getMinU(), sprite.getMinV()),
|
model = new FanModel(sprite) {
|
||||||
new RenderUtil.Vertex(-1, 1, 0, sprite.getMaxU(), sprite.getMinV()),
|
@Override
|
||||||
new RenderUtil.Vertex( 1, 1, 0, sprite.getMaxU(), sprite.getMaxV()),
|
protected int getLightAt(Vector4f pos, int light) {
|
||||||
new RenderUtil.Vertex( 1, -1, 0, sprite.getMinU(), sprite.getMaxV())
|
return lightSource.getLight(pos, light);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
if (!effect.getBlockState().isOf(Blocks.GRASS_BLOCK)) {
|
if (!effect.getBlockState().isOf(Blocks.GRASS_BLOCK)) {
|
||||||
int i = MinecraftClient.getInstance().getBlockColors().getColor(effect.getBlockState(), world, BlockPos.ofFloored(x, y, z), 0);
|
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();
|
super.tick();
|
||||||
scaleFactor += 0.001F;
|
scaleFactor += 0.001F;
|
||||||
scale(MathHelper.clamp(age / 5F, 0, 1) * scaleFactor);
|
scale(MathHelper.clamp(age / 5F, 0, 1) * scaleFactor);
|
||||||
|
lightSource.tick();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void renderQuads(Tessellator te, BufferBuilder buffer, float x, float y, float z, float tickDelta) {
|
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));
|
float alpha = this.alpha * (1 - ((float)age / maxAge));
|
||||||
MatrixStack matrices = new MatrixStack();
|
MatrixStack matrices = new MatrixStack();
|
||||||
matrices.translate(x, y, z);
|
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++) {
|
for (int i = 0; i < SEGMENTS; i++) {
|
||||||
matrices.push();
|
matrices.push();
|
||||||
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees((i * angle) % 360));
|
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees((i * angle)));
|
||||||
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees((SEPARATION * i + angle) % 360));
|
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees((SEPARATION * i - angle)));
|
||||||
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees((SEPARATION * i + angle) % 360));
|
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees((SEPARATION * i + angle)));
|
||||||
float ringScale = 1 + MathHelper.sin(((i * 10) + age + tickDelta) * 0.05F) * 0.1F;
|
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();
|
matrices.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ public class BakedModel {
|
||||||
textureMatrix.identity();
|
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);
|
scale = Math.abs(scale);
|
||||||
if (scale < 0.001F) {
|
if (scale < 0.001F) {
|
||||||
return;
|
return;
|
||||||
|
@ -62,9 +62,13 @@ public class BakedModel {
|
||||||
for (RenderUtil.Vertex vertex : vertices) {
|
for (RenderUtil.Vertex vertex : vertices) {
|
||||||
Vector4f pos = vertex.position(positionmatrix);
|
Vector4f pos = vertex.position(positionmatrix);
|
||||||
Vector4f tex = vertex.texture(textureMatrix);
|
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();
|
matrices.pop();
|
||||||
textureMatrix.identity();
|
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.concurrent.atomic.AtomicReference;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.Unicopia;
|
import com.minelittlepony.unicopia.Unicopia;
|
||||||
import net.fabricmc.fabric.api.client.rendering.v1.CoreShaderRegistrationCallback;
|
import net.fabricmc.fabric.api.client.rendering.v1.CoreShaderRegistrationCallback;
|
||||||
import net.minecraft.client.gl.ShaderProgram;
|
import net.minecraft.client.gl.ShaderProgram;
|
||||||
import net.minecraft.client.render.VertexFormat;
|
import net.minecraft.client.render.VertexFormat;
|
||||||
import net.minecraft.client.render.VertexFormats;
|
import net.minecraft.client.render.VertexFormats;
|
||||||
|
|
||||||
public final class UShaders {
|
public interface UShaders {
|
||||||
@Nullable
|
Supplier<ShaderProgram> RENDER_TYPE_PORTAL_SURFACE = register("rendertype_portal_surface", VertexFormats.POSITION_COLOR);
|
||||||
private static Supplier<ShaderProgram> renderTypePortalSurfaceProgram = register("rendertype_portal_surface", VertexFormats.POSITION_COLOR);
|
|
||||||
|
|
||||||
public static ShaderProgram getRenderTypePortalSurfaceProgram() {
|
static void bootstrap() { }
|
||||||
return renderTypePortalSurfaceProgram.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void bootstrap() { }
|
|
||||||
|
|
||||||
static Supplier<ShaderProgram> register(String name, VertexFormat format) {
|
static Supplier<ShaderProgram> register(String name, VertexFormat format) {
|
||||||
AtomicReference<ShaderProgram> holder = new AtomicReference<>();
|
AtomicReference<ShaderProgram> holder = new AtomicReference<>();
|
||||||
|
|
|
@ -94,14 +94,14 @@ class PortalFrameBuffer implements AutoCloseable {
|
||||||
BufferBuilder buffer = tessellator.getBuffer();
|
BufferBuilder buffer = tessellator.getBuffer();
|
||||||
float uScale = (float)framebuffer.viewportWidth / (float)framebuffer.textureWidth;
|
float uScale = (float)framebuffer.viewportWidth / (float)framebuffer.textureWidth;
|
||||||
float vScale = (float)framebuffer.viewportHeight / (float)framebuffer.textureHeight;
|
float vScale = (float)framebuffer.viewportHeight / (float)framebuffer.textureHeight;
|
||||||
RenderSystem.setShader(UShaders::getRenderTypePortalSurfaceProgram);
|
RenderSystem.setShader(UShaders.RENDER_TYPE_PORTAL_SURFACE);
|
||||||
//RenderSystem.setShader(GameRenderer::getPositionTexColorProgram);
|
//RenderSystem.setShader(GameRenderer::getPositionTexColorProgram);
|
||||||
RenderSystem._setShaderTexture(0, framebuffer.getColorAttachment());
|
RenderSystem._setShaderTexture(0, framebuffer.getColorAttachment());
|
||||||
buffer.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR);
|
buffer.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR);
|
||||||
SphereModel.DISK.scaleUV(uScale, vScale);
|
SphereModel.DISK.scaleUV(uScale, vScale);
|
||||||
|
|
||||||
RenderSystem.setTextureMatrix(SphereModel.DISK.getTextureMatrix());
|
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();
|
tessellator.draw();
|
||||||
|
|
||||||
client.getTextureManager().bindTexture(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE);
|
client.getTextureManager().bindTexture(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE);
|
||||||
|
|
|
@ -567,7 +567,7 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
||||||
if (entity.isOnGround() || !force) {
|
if (entity.isOnGround() || !force) {
|
||||||
BlockState steppingState = pony.asEntity().getSteppingBlockState();
|
BlockState steppingState = pony.asEntity().getSteppingBlockState();
|
||||||
if (steppingState.isIn(UTags.KICKS_UP_DUST)) {
|
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 {
|
} else {
|
||||||
Supplier<Vec3d> pos = VecHelper.sphere(pony.asWorld().getRandom(), 0.5D);
|
Supplier<Vec3d> pos = VecHelper.sphere(pony.asWorld().getRandom(), 0.5D);
|
||||||
Supplier<Vec3d> vel = VecHelper.sphere(pony.asWorld().getRandom(), 0.015D);
|
Supplier<Vec3d> vel = VecHelper.sphere(pony.asWorld().getRandom(), 0.015D);
|
||||||
|
|
Loading…
Reference in a new issue