mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 15:17:59 +01:00
Improve portal rendering
This commit is contained in:
parent
da3aec8d83
commit
80500a74c8
11 changed files with 169 additions and 42 deletions
|
@ -23,6 +23,7 @@ import com.minelittlepony.unicopia.client.particle.ShockwaveParticle;
|
|||
import com.minelittlepony.unicopia.client.particle.SphereParticle;
|
||||
import com.minelittlepony.unicopia.client.render.*;
|
||||
import com.minelittlepony.unicopia.client.render.entity.*;
|
||||
import com.minelittlepony.unicopia.client.render.shader.UShaders;
|
||||
import com.minelittlepony.unicopia.client.render.spell.SpellRendererFactory;
|
||||
import com.minelittlepony.unicopia.entity.mob.UEntities;
|
||||
import com.minelittlepony.unicopia.item.ChameleonItem;
|
||||
|
@ -128,6 +129,7 @@ public interface URenderers {
|
|||
TerraformBoatClientHelper.registerModelLayers(Unicopia.id("palm"), false);
|
||||
|
||||
SpellRendererFactory.bootstrap();
|
||||
UShaders.bootstrap();
|
||||
}
|
||||
|
||||
private static void register(DynamicItemRenderer renderer, ItemConvertible...items) {
|
||||
|
|
|
@ -42,7 +42,7 @@ public abstract class AbstractGeometryBasedParticle extends Particle {
|
|||
int light = getBrightness(tickDelta);
|
||||
buffer.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR_LIGHT);
|
||||
for (RenderUtil.Vertex corner : corners) {
|
||||
buffer.vertex(corner.position().x, corner.position().y, corner.position().z).texture(corner.u(), corner.v()).color(red, green, blue, alpha).light(light).next();
|
||||
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).next();
|
||||
}
|
||||
te.draw();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.minelittlepony.unicopia.client.render;
|
||||
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Vector4f;
|
||||
|
||||
|
@ -11,17 +12,18 @@ import net.minecraft.client.util.math.MatrixStack;
|
|||
|
||||
public class RenderUtil {
|
||||
public static final Vector4f TEMP_VECTOR = new Vector4f();
|
||||
private static final Vector4f TEMP_UV_VECTOR = new Vector4f();
|
||||
public static final Vertex[] UNIT_FACE = new Vertex[] {
|
||||
new Vertex(new Vector3f(0, 0, 0), 1, 1),
|
||||
new Vertex(new Vector3f(0, 1, 0), 1, 0),
|
||||
new Vertex(new Vector3f(1, 1, 0), 0, 0),
|
||||
new Vertex(new Vector3f(1, 0, 0), 0, 1)
|
||||
new Vertex(0, 0, 0, 1, 1),
|
||||
new Vertex(0, 1, 0, 1, 0),
|
||||
new Vertex(1, 1, 0, 0, 0),
|
||||
new Vertex(1, 0, 0, 0, 1)
|
||||
};
|
||||
public static final Vertex[] FRAME_BUFFER_VERTICES = new Vertex[] {
|
||||
new Vertex(new Vector3f(0, 1, 0), 0, 0),
|
||||
new Vertex(new Vector3f(1, 1, 0), 1, 0),
|
||||
new Vertex(new Vector3f(1, 0, 0), 1, 1),
|
||||
new Vertex(new Vector3f(0, 0, 0), 0, 1)
|
||||
new Vertex(0, 1, 0, 0, 0),
|
||||
new Vertex(1, 1, 0, 1, 0),
|
||||
new Vertex(1, 0, 0, 1, 1),
|
||||
new Vertex(0, 0, 0, 0, 1)
|
||||
};
|
||||
|
||||
public static void renderFace(MatrixStack matrices, Tessellator te, BufferBuilder buffer, float r, float g, float b, float a, int light) {
|
||||
|
@ -30,17 +32,25 @@ public class RenderUtil {
|
|||
|
||||
public static void renderFace(MatrixStack matrices, Tessellator te, BufferBuilder buffer, float r, float g, float b, float a, int light, float uScale, float vScale) {
|
||||
buffer.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR_LIGHT);
|
||||
Matrix4f positionmatrix = matrices.peek().getPositionMatrix();
|
||||
for (Vertex vertex : UNIT_FACE) {
|
||||
Vector4f position = vertex.position(matrices);
|
||||
buffer.vertex(position.x, position.y, position.z).texture(vertex.u() * uScale, vertex.v() * vScale).color(r, g, b, a).light(light).next();
|
||||
Vector4f position = vertex.position(positionmatrix);
|
||||
buffer.vertex(position.x, position.y, position.z).texture(vertex.texture().x * uScale, vertex.texture().y * vScale).color(r, g, b, a).light(light).next();
|
||||
}
|
||||
te.draw();
|
||||
}
|
||||
|
||||
public record Vertex(Vector3f position, float u, float v) {
|
||||
public Vector4f position(MatrixStack matrices) {
|
||||
matrices.peek().getPositionMatrix().transform(TEMP_VECTOR.set(position, 1));
|
||||
return TEMP_VECTOR;
|
||||
public record Vertex(Vector3f position, Vector3f texture) {
|
||||
public Vertex(float x, float y, float z, float u, float v) {
|
||||
this(new Vector3f(x, y, z), new Vector3f(u, v, 1));
|
||||
}
|
||||
|
||||
public Vector4f position(Matrix4f mat) {
|
||||
return mat.transform(TEMP_VECTOR.set(position, 1));
|
||||
}
|
||||
|
||||
public Vector4f texture(Matrix4f mat) {
|
||||
return mat.transform(TEMP_UV_VECTOR.set(texture, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,10 +12,10 @@ public record BezierSegment(
|
|||
|
||||
public BezierSegment(Vector3f from, Vector3f to, float height) {
|
||||
this(new RenderUtil.Vertex[] {
|
||||
new RenderUtil.Vertex(new Vector3f(from.x, from.y - height/2F, from.z), 0, 0), // bottom left
|
||||
new RenderUtil.Vertex(new Vector3f(from.x, from.y + height/2F, from.z), 1, 0), // top left
|
||||
new RenderUtil.Vertex(new Vector3f(to.x, to.y + height/2F, to.z), 1, 1), // top right
|
||||
new RenderUtil.Vertex(new Vector3f(to.x, to.y - height/2F, to.z), 0, 1) // bottom right
|
||||
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
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,25 +1,35 @@
|
|||
package com.minelittlepony.unicopia.client.render.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector4f;
|
||||
|
||||
import com.minelittlepony.unicopia.client.render.RenderUtil;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import net.minecraft.client.render.VertexConsumer;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
|
||||
public class BakedModel {
|
||||
protected final List<RenderUtil.Vertex> vertices = new ArrayList<>();
|
||||
protected final List<RenderUtil.Vertex> vertices = new ObjectArrayList<>();
|
||||
|
||||
private final Matrix4f textureMatrix = new Matrix4f();
|
||||
|
||||
public Matrix4f getTextureMatrix() {
|
||||
return textureMatrix;
|
||||
}
|
||||
|
||||
public void scaleUV(float uScale, float vScale) {
|
||||
getTextureMatrix().scale(uScale, vScale, 1);
|
||||
}
|
||||
|
||||
protected void addVertex(Vector4f vertex) {
|
||||
addVertex(vertex.x, vertex.y, vertex.z, (vertex.x + 1) * 0.5F, (vertex.z + 1) * 0.5F);
|
||||
}
|
||||
|
||||
protected void addVertex(float x, float y, float z, float u, float v) {
|
||||
vertices.add(new RenderUtil.Vertex(new Vector3f(x, y, z), u, v));
|
||||
vertices.add(new RenderUtil.Vertex(x, y, z, u, v));
|
||||
}
|
||||
|
||||
public final void render(MatrixStack matrices, VertexConsumer buffer, int light, int overlay, float scale, float r, float g, float b, float a) {
|
||||
|
@ -30,14 +40,17 @@ public class BakedModel {
|
|||
|
||||
matrices.push();
|
||||
matrices.scale(scale, scale, scale);
|
||||
Matrix4f positionmatrix = matrices.peek().getPositionMatrix();
|
||||
for (RenderUtil.Vertex vertex : vertices) {
|
||||
Vector4f pos = vertex.position(matrices);
|
||||
buffer.vertex(pos.x, pos.y, pos.z, r, g, b, a, vertex.u(), vertex.v(), overlay, light, 0, 0, 0);
|
||||
Vector4f pos = vertex.position(positionmatrix);
|
||||
Vector4f tex = vertex.texture(textureMatrix);
|
||||
buffer.vertex(pos.x, pos.y, pos.z, r, g, b, a, tex.x, tex.y, overlay, light, 0, 0, 0);
|
||||
}
|
||||
matrices.pop();
|
||||
textureMatrix.identity();
|
||||
}
|
||||
|
||||
public final void render(MatrixStack matrices, VertexConsumer buffer, float scale, float r, float g, float b, float a, float uScale, float vScale) {
|
||||
public final void render(MatrixStack matrices, VertexConsumer buffer, float scale, float r, float g, float b, float a) {
|
||||
scale = Math.abs(scale);
|
||||
if (scale < 0.001F) {
|
||||
return;
|
||||
|
@ -45,10 +58,13 @@ public class BakedModel {
|
|||
|
||||
matrices.push();
|
||||
matrices.scale(scale, scale, scale);
|
||||
Matrix4f positionmatrix = matrices.peek().getPositionMatrix();
|
||||
for (RenderUtil.Vertex vertex : vertices) {
|
||||
Vector4f pos = vertex.position(matrices);
|
||||
buffer.vertex(pos.x, pos.y, pos.z).texture(vertex.u() * uScale, vertex.v() * vScale).color(r, g, b, a).next();
|
||||
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();
|
||||
}
|
||||
matrices.pop();
|
||||
textureMatrix.identity();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
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 static ShaderProgram getRenderTypePortalSurfaceProgram() {
|
||||
return renderTypePortalSurfaceProgram.get();
|
||||
}
|
||||
|
||||
public static void bootstrap() { }
|
||||
|
||||
static Supplier<ShaderProgram> register(String name, VertexFormat format) {
|
||||
AtomicReference<ShaderProgram> holder = new AtomicReference<>();
|
||||
CoreShaderRegistrationCallback.EVENT.register(context -> context.register(Unicopia.id(name), format, holder::set));
|
||||
return holder::get;
|
||||
}
|
||||
}
|
|
@ -15,6 +15,7 @@ import com.minelittlepony.unicopia.ability.magic.Caster;
|
|||
import com.minelittlepony.unicopia.ability.magic.spell.effect.PortalSpell;
|
||||
import com.minelittlepony.unicopia.client.render.RenderLayers;
|
||||
import com.minelittlepony.unicopia.client.render.model.SphereModel;
|
||||
import com.minelittlepony.unicopia.client.render.shader.UShaders;
|
||||
import com.minelittlepony.unicopia.entity.EntityReference;
|
||||
import com.minelittlepony.unicopia.entity.mob.UEntities;
|
||||
import com.minelittlepony.unicopia.mixin.client.MixinMinecraftClient;
|
||||
|
@ -30,7 +31,6 @@ import net.minecraft.client.render.BackgroundRenderer;
|
|||
import net.minecraft.client.render.BufferBuilder;
|
||||
import net.minecraft.client.render.Camera;
|
||||
import net.minecraft.client.render.Frustum;
|
||||
import net.minecraft.client.render.GameRenderer;
|
||||
import net.minecraft.client.render.Tessellator;
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.minecraft.client.render.VertexFormat;
|
||||
|
@ -41,6 +41,7 @@ import net.minecraft.client.util.math.MatrixStack;
|
|||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.screen.PlayerScreenHandler;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
class PortalFrameBuffer implements AutoCloseable {
|
||||
|
@ -92,10 +93,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(GameRenderer::getPositionTexColorProgram);
|
||||
RenderSystem.setShader(UShaders::getRenderTypePortalSurfaceProgram);
|
||||
//RenderSystem.setShader(GameRenderer::getPositionTexColorProgram);
|
||||
RenderSystem._setShaderTexture(0, framebuffer.getColorAttachment());
|
||||
buffer.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR);
|
||||
SphereModel.DISK.render(matrices, buffer, 2F, 1, 1, 1, 1, uScale, vScale);
|
||||
SphereModel.DISK.scaleUV(uScale, vScale);
|
||||
|
||||
RenderSystem.setTextureMatrix(SphereModel.DISK.getTextureMatrix());
|
||||
SphereModel.DISK.render(matrices, buffer, 2F, 1, 1, 1, 1);
|
||||
tessellator.draw();
|
||||
|
||||
client.getTextureManager().bindTexture(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE);
|
||||
|
@ -110,11 +115,11 @@ class PortalFrameBuffer implements AutoCloseable {
|
|||
|
||||
public void build(PortalSpell spell, Caster<?> caster, EntityReference.EntityValues<Entity> target) {
|
||||
|
||||
if (framebuffer != null && System.currentTimeMillis() % 100 != 0) {
|
||||
if (framebuffer != null && System.currentTimeMillis() % 1 != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pendingDraw && recursionCount > 0) {
|
||||
if (pendingDraw && recursionCount > 2) {
|
||||
innerBuild(spell, caster, target);
|
||||
return;
|
||||
}
|
||||
|
@ -134,7 +139,7 @@ class PortalFrameBuffer implements AutoCloseable {
|
|||
synchronized (client) {
|
||||
pendingDraw = false;
|
||||
|
||||
if (recursionCount > 2) {
|
||||
if (recursionCount > 0) {
|
||||
return;
|
||||
}
|
||||
recursionCount++;
|
||||
|
@ -149,10 +154,17 @@ class PortalFrameBuffer implements AutoCloseable {
|
|||
int originalFov = fov.getValue();
|
||||
fov.setValue(110);
|
||||
|
||||
Camera camera = client.gameRenderer.getCamera();
|
||||
|
||||
Entity cameraEntity = UEntities.CAST_SPELL.create(caster.asWorld());
|
||||
cameraEntity.setPosition(target.pos());
|
||||
cameraEntity.setPitch(spell.getTargetPitch());
|
||||
cameraEntity.setYaw(spell.getTargetYaw() + 180);
|
||||
Vec3d offset = new Vec3d(0, -0.2F, -0.2F).rotateY(-spell.getTargetYaw() * MathHelper.RADIANS_PER_DEGREE);
|
||||
|
||||
float yaw = spell.getTargetYaw() + camera.getYaw() - spell.getYaw() + 180;
|
||||
float pitch = spell.getTargetPitch() + (camera.getPitch() - spell.getPitch()) * 1.65F;
|
||||
|
||||
cameraEntity.setPosition(target.pos().add(offset));
|
||||
cameraEntity.setPitch(pitch);
|
||||
cameraEntity.setYaw(yaw);
|
||||
|
||||
drawWorld(cameraEntity, 400, 400);
|
||||
|
||||
|
@ -220,11 +232,8 @@ class PortalFrameBuffer implements AutoCloseable {
|
|||
renderer.scheduleBlockRenders((int)cameraEntity.getX() / 16, (int)cameraEntity.getY() / 16, (int)cameraEntity.getZ() / 16);
|
||||
|
||||
client.gameRenderer.setRenderHand(false);
|
||||
MatrixStack matrices = new MatrixStack();
|
||||
|
||||
matrices.scale((float)width / height, 1, 1);
|
||||
|
||||
client.gameRenderer.renderWorld(1, 0, matrices);
|
||||
client.gameRenderer.renderWorld(1, 0, new MatrixStack());
|
||||
|
||||
// Strip transparency
|
||||
RenderSystem.colorMask(false, false, false, true);
|
||||
|
|
|
@ -5,7 +5,6 @@ import com.minelittlepony.unicopia.ability.magic.spell.effect.PortalSpell;
|
|||
import com.minelittlepony.unicopia.client.render.RenderLayers;
|
||||
import com.minelittlepony.unicopia.client.render.model.SphereModel;
|
||||
import com.minelittlepony.unicopia.entity.EntityReference;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.render.Frustum;
|
||||
|
@ -49,6 +48,9 @@ public class PortalSpellRenderer extends SpellRenderer<PortalSpell> {
|
|||
if (caster.asEntity().distanceTo(client.cameraEntity) > 50) {
|
||||
return; // don't bother rendering if too far away
|
||||
}
|
||||
if (client.cameraEntity == caster.asEntity()) {
|
||||
return;
|
||||
}
|
||||
|
||||
matrices.push();
|
||||
matrices.scale(strength, strength, strength);
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
#version 150
|
||||
|
||||
#moj_import <matrix.glsl>
|
||||
|
||||
uniform sampler2D Sampler0;
|
||||
uniform sampler2D Sampler1;
|
||||
|
||||
uniform vec4 ColorModulator;
|
||||
uniform float GameTime;
|
||||
uniform int EndPortalLayers;
|
||||
|
||||
in vec4 texProj0;
|
||||
in vec4 vertexColor;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
vec4 scale = vec4(0.25, 0.25, 0.25, 0.25);
|
||||
fragColor = textureProj(Sampler0, texProj0 * scale);
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"blend": {
|
||||
"func": "add",
|
||||
"srcrgb": "srcalpha",
|
||||
"dstrgb": "1-srcalpha"
|
||||
},
|
||||
"vertex": "unicopia:rendertype_portal_surface",
|
||||
"fragment": "unicopia:rendertype_portal_surface",
|
||||
"attributes": [],
|
||||
"samplers": [
|
||||
{ "name": "Sampler0" },
|
||||
{ "name": "Sampler1" }
|
||||
],
|
||||
"uniforms": [
|
||||
{ "name": "ModelViewMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] },
|
||||
{ "name": "ProjMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] },
|
||||
{ "name": "GameTime", "type": "float", "count": 1, "values": [ 0.0 ] },
|
||||
{ "name": "EndPortalLayers", "type": "int", "count": 1, "values": [ 15 ] }
|
||||
]
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
#version 150
|
||||
|
||||
#moj_import <projection.glsl>
|
||||
|
||||
in vec3 Position;
|
||||
in vec4 Color;
|
||||
|
||||
uniform mat4 ModelViewMat;
|
||||
uniform mat4 ProjMat;
|
||||
|
||||
out vec4 texProj0;
|
||||
out vec4 vertexColor;
|
||||
|
||||
void main() {
|
||||
gl_Position = ProjMat * ModelViewMat * vec4(Position, 1.0);
|
||||
|
||||
vertexColor = Color;
|
||||
texProj0 = projection_from_position(gl_Position);
|
||||
}
|
Loading…
Reference in a new issue