-
Notifications
You must be signed in to change notification settings - Fork 789
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move particle vertex processing to the GPU
- Loading branch information
Showing
12 changed files
with
548 additions
and
72 deletions.
There are no files selected for viewing
56 changes: 56 additions & 0 deletions
56
...ava/me/jellysquid/mods/sodium/client/render/particle/ShaderBillboardParticleRenderer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package me.jellysquid.mods.sodium.client.render.particle; | ||
|
||
import me.jellysquid.mods.sodium.client.gl.shader.*; | ||
import me.jellysquid.mods.sodium.client.render.particle.shader.ParticleShaderBindingPoints; | ||
import me.jellysquid.mods.sodium.client.render.particle.shader.ParticleShaderInterface; | ||
import net.minecraft.util.Identifier; | ||
|
||
public class ShaderBillboardParticleRenderer { | ||
protected GlProgram<ParticleShaderInterface> activeProgram; | ||
|
||
public ShaderBillboardParticleRenderer() { | ||
this.activeProgram = createShader("particles/particle"); | ||
} | ||
|
||
public GlProgram<ParticleShaderInterface> getActiveProgram() { | ||
return activeProgram; | ||
} | ||
|
||
private GlProgram<ParticleShaderInterface> createShader(String path) { | ||
ShaderConstants constants = ShaderConstants.builder().build(); | ||
|
||
GlShader vertShader = ShaderLoader.loadShader(ShaderType.VERTEX, | ||
new Identifier("sodium", path + ".vsh"), constants); | ||
|
||
GlShader fragShader = ShaderLoader.loadShader(ShaderType.FRAGMENT, | ||
new Identifier("sodium", path + ".fsh"), constants); | ||
|
||
try { | ||
return GlProgram.builder(new Identifier("sodium", "billboard_particle_shader")) | ||
.attachShader(vertShader) | ||
.attachShader(fragShader) | ||
.bindAttribute("in_Position", ParticleShaderBindingPoints.ATTRIBUTE_POSITION) | ||
.bindAttribute("in_Size", ParticleShaderBindingPoints.ATTRIBUTE_SIZE) | ||
.bindAttribute("in_TexCoord", ParticleShaderBindingPoints.ATTRIBUTE_TEXTURE) | ||
.bindAttribute("in_Color", ParticleShaderBindingPoints.ATTRIBUTE_COLOR) | ||
.bindAttribute("in_Light", ParticleShaderBindingPoints.ATTRIBUTE_LIGHT_TEXTURE) | ||
.bindAttribute("in_Angle", ParticleShaderBindingPoints.ATTRIBUTE_ANGLE) | ||
.bindFragmentData("out_FragColor", ParticleShaderBindingPoints.FRAG_COLOR) | ||
.link(ParticleShaderInterface::new); | ||
} finally { | ||
vertShader.delete(); | ||
fragShader.delete(); | ||
} | ||
} | ||
|
||
public void begin() { | ||
// pass.startDrawing(); .. Do I need a pass? | ||
|
||
this.activeProgram.bind(); | ||
this.activeProgram.getInterface().setupState(); | ||
} | ||
|
||
public void end() { | ||
this.activeProgram.unbind(); | ||
} | ||
} |
103 changes: 103 additions & 0 deletions
103
...java/me/jellysquid/mods/sodium/client/render/particle/shader/BillboardParticleVertex.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
package me.jellysquid.mods.sodium.client.render.particle.shader; | ||
|
||
import com.google.common.collect.ImmutableMap; | ||
import me.jellysquid.mods.sodium.client.gl.attribute.GlVertexAttributeBinding; | ||
import me.jellysquid.mods.sodium.client.gl.attribute.GlVertexAttributeFormat; | ||
import me.jellysquid.mods.sodium.client.gl.attribute.GlVertexFormat; | ||
import me.jellysquid.mods.sodium.client.render.chunk.shader.ChunkShaderBindingPoints; | ||
import me.jellysquid.mods.sodium.client.render.chunk.vertex.format.ChunkMeshAttribute; | ||
import net.caffeinemc.mods.sodium.api.vertex.attributes.CommonVertexAttribute; | ||
import net.caffeinemc.mods.sodium.api.vertex.attributes.common.ColorAttribute; | ||
import net.caffeinemc.mods.sodium.api.vertex.attributes.common.LightAttribute; | ||
import net.caffeinemc.mods.sodium.api.vertex.attributes.common.PositionAttribute; | ||
import net.caffeinemc.mods.sodium.api.vertex.attributes.common.TextureAttribute; | ||
import net.caffeinemc.mods.sodium.api.vertex.format.VertexFormatDescription; | ||
import net.caffeinemc.mods.sodium.api.vertex.format.VertexFormatRegistry; | ||
import net.minecraft.client.render.VertexFormat; | ||
import net.minecraft.client.render.VertexFormatElement; | ||
import org.lwjgl.opengl.GL20C; | ||
import org.lwjgl.opengl.GL30C; | ||
import org.lwjgl.system.MemoryUtil; | ||
|
||
import java.util.Map; | ||
|
||
import static net.minecraft.client.render.VertexFormats.*; | ||
|
||
public class BillboardParticleVertex { | ||
public static final int POSITION_OFFSET = 0; | ||
public static final int SIZE_OFFSET = 12; | ||
public static final int TEX_UV_OFFSET = 16; | ||
public static final int COLOR_OFFSET = 24; | ||
public static final int LIGHT_UV_OFFSET = 28; | ||
public static final int ANGLE_OFFSET = 32; | ||
public static final int STRIDE = 36; | ||
|
||
public static final GlVertexFormat<ParticleMeshAttribute> VERTEX_FORMAT = GlVertexFormat.builder(ParticleMeshAttribute.class, STRIDE) | ||
.addElement(ParticleMeshAttribute.POSITION, POSITION_OFFSET, GlVertexAttributeFormat.FLOAT, 3, false, false) | ||
.addElement(ParticleMeshAttribute.SIZE, SIZE_OFFSET, GlVertexAttributeFormat.FLOAT, 1, false, false) | ||
.addElement(ParticleMeshAttribute.TEX_COORD, TEX_UV_OFFSET, GlVertexAttributeFormat.FLOAT, 2, false, false) | ||
.addElement(ParticleMeshAttribute.COLOR, COLOR_OFFSET, GlVertexAttributeFormat.UNSIGNED_BYTE, 4, true, false) | ||
.addElement(ParticleMeshAttribute.LIGHT_UV, LIGHT_UV_OFFSET, GlVertexAttributeFormat.UNSIGNED_SHORT, 2, false, true) | ||
.addElement(ParticleMeshAttribute.ANGLE, ANGLE_OFFSET, GlVertexAttributeFormat.FLOAT, 1, false, false) | ||
.build(); | ||
|
||
public static final VertexFormat MC_VERTEX_FORMAT = new VertexFormat(ImmutableMap.ofEntries( | ||
Map.entry("in_Position", POSITION_ELEMENT), | ||
Map.entry("in_Size", new VertexFormatElement( | ||
0, | ||
VertexFormatElement.ComponentType.FLOAT, | ||
VertexFormatElement.Type.GENERIC, | ||
1 | ||
)), | ||
Map.entry("in_TexCoord", TEXTURE_ELEMENT), | ||
Map.entry("in_Color", COLOR_ELEMENT), | ||
Map.entry("in_Light", LIGHT_ELEMENT), | ||
Map.entry("in_Angle", new VertexFormatElement( | ||
0, | ||
VertexFormatElement.ComponentType.FLOAT, | ||
VertexFormatElement.Type.GENERIC, | ||
1 | ||
)) | ||
)); | ||
|
||
public static final GlVertexAttributeBinding[] ATTRIBUTE_BINDINGS = new GlVertexAttributeBinding[] { | ||
new GlVertexAttributeBinding(ParticleShaderBindingPoints.ATTRIBUTE_POSITION, | ||
VERTEX_FORMAT.getAttribute(ParticleMeshAttribute.POSITION)), | ||
new GlVertexAttributeBinding(ParticleShaderBindingPoints.ATTRIBUTE_SIZE, | ||
VERTEX_FORMAT.getAttribute(ParticleMeshAttribute.SIZE)), | ||
new GlVertexAttributeBinding(ParticleShaderBindingPoints.ATTRIBUTE_TEXTURE, | ||
VERTEX_FORMAT.getAttribute(ParticleMeshAttribute.TEX_COORD)), | ||
new GlVertexAttributeBinding(ParticleShaderBindingPoints.ATTRIBUTE_COLOR, | ||
VERTEX_FORMAT.getAttribute(ParticleMeshAttribute.COLOR)), | ||
new GlVertexAttributeBinding(ParticleShaderBindingPoints.ATTRIBUTE_LIGHT_TEXTURE, | ||
VERTEX_FORMAT.getAttribute(ParticleMeshAttribute.LIGHT_UV)), | ||
new GlVertexAttributeBinding(ParticleShaderBindingPoints.ATTRIBUTE_ANGLE, | ||
VERTEX_FORMAT.getAttribute(ParticleMeshAttribute.ANGLE)), | ||
}; | ||
|
||
public static final VertexFormatDescription VERTEX_FORMAT_DESCRIPTION = VertexFormatRegistry.instance() | ||
.get(MC_VERTEX_FORMAT); | ||
|
||
public static void put(long ptr, float x, float y, float z, | ||
float u, float v, int color, int light, float size, float angle) { | ||
PositionAttribute.put(ptr + POSITION_OFFSET, x, y, z); | ||
MemoryUtil.memPutFloat(ptr + SIZE_OFFSET, size); | ||
TextureAttribute.put(ptr + TEX_UV_OFFSET, u, v); | ||
ColorAttribute.set(ptr + COLOR_OFFSET, color); | ||
LightAttribute.set(ptr + LIGHT_UV_OFFSET, light); | ||
MemoryUtil.memPutFloat(ptr + ANGLE_OFFSET, angle); | ||
} | ||
|
||
public static void bindVertexFormat() { | ||
for (GlVertexAttributeBinding attrib : ATTRIBUTE_BINDINGS) { | ||
if (attrib.isIntType()) { | ||
GL30C.glVertexAttribIPointer(attrib.getIndex(), attrib.getCount(), attrib.getFormat(), | ||
attrib.getStride(), attrib.getPointer()); | ||
} else { | ||
GL20C.glVertexAttribPointer(attrib.getIndex(), attrib.getCount(), attrib.getFormat(), attrib.isNormalized(), | ||
attrib.getStride(), attrib.getPointer()); | ||
} | ||
GL20C.glEnableVertexAttribArray(attrib.getIndex()); | ||
} | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
...n/java/me/jellysquid/mods/sodium/client/render/particle/shader/ParticleMeshAttribute.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package me.jellysquid.mods.sodium.client.render.particle.shader; | ||
|
||
public enum ParticleMeshAttribute { | ||
POSITION, | ||
SIZE, | ||
TEX_COORD, | ||
COLOR, | ||
LIGHT_UV, | ||
ANGLE, | ||
} |
12 changes: 12 additions & 0 deletions
12
.../me/jellysquid/mods/sodium/client/render/particle/shader/ParticleShaderBindingPoints.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package me.jellysquid.mods.sodium.client.render.particle.shader; | ||
|
||
public class ParticleShaderBindingPoints { | ||
public static final int ATTRIBUTE_POSITION = 1; | ||
public static final int ATTRIBUTE_SIZE = 2; | ||
public static final int ATTRIBUTE_TEXTURE = 3; | ||
public static final int ATTRIBUTE_COLOR = 4; | ||
public static final int ATTRIBUTE_LIGHT_TEXTURE = 5; | ||
public static final int ATTRIBUTE_ANGLE = 6; | ||
|
||
public static final int FRAG_COLOR = 0; | ||
} |
68 changes: 68 additions & 0 deletions
68
...java/me/jellysquid/mods/sodium/client/render/particle/shader/ParticleShaderInterface.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package me.jellysquid.mods.sodium.client.render.particle.shader; | ||
|
||
import com.mojang.blaze3d.platform.GlStateManager; | ||
import me.jellysquid.mods.sodium.client.gl.shader.uniform.GlUniformFloat4v; | ||
import me.jellysquid.mods.sodium.client.gl.shader.uniform.GlUniformInt; | ||
import me.jellysquid.mods.sodium.client.gl.shader.uniform.GlUniformMatrix4f; | ||
import me.jellysquid.mods.sodium.client.render.chunk.shader.ChunkShaderTextureSlot; | ||
import me.jellysquid.mods.sodium.client.render.chunk.shader.ShaderBindingContext; | ||
import me.jellysquid.mods.sodium.client.util.TextureUtil; | ||
import org.joml.*; | ||
import org.lwjgl.opengl.GL32C; | ||
|
||
public class ParticleShaderInterface { | ||
private final GlUniformInt uniformParticleTexture; | ||
private final GlUniformInt uniformLightTexture; | ||
private final GlUniformMatrix4f uniformModelViewMatrix; | ||
private final GlUniformMatrix4f uniformProjectionMatrix; | ||
private final GlUniformFloat4v uniformCameraRotation; | ||
|
||
public ParticleShaderInterface(ShaderBindingContext context) { | ||
this.uniformParticleTexture = context.bindUniform("u_ParticleTex", GlUniformInt::new); | ||
this.uniformLightTexture = context.bindUniform("u_LightTex", GlUniformInt::new); | ||
this.uniformModelViewMatrix = context.bindUniform("u_ModelViewMatrix", GlUniformMatrix4f::new); | ||
this.uniformProjectionMatrix = context.bindUniform("u_ProjectionMatrix", GlUniformMatrix4f::new); | ||
this.uniformCameraRotation = context.bindUniform("u_CameraRotation", GlUniformFloat4v::new); | ||
} | ||
|
||
public void setProjectionMatrix(Matrix4fc matrix) { | ||
this.uniformProjectionMatrix.set(matrix); | ||
} | ||
|
||
public void setModelViewMatrix(Matrix4fc matrix) { | ||
this.uniformModelViewMatrix.set(matrix); | ||
} | ||
public void setCameraRotation(Quaternionfc quaternion) { | ||
this.uniformCameraRotation.set(new float[] { | ||
quaternion.x(), | ||
quaternion.y(), | ||
quaternion.z(), | ||
quaternion.w(), | ||
}); | ||
} | ||
|
||
public void setupState() { | ||
// "BlockTexture" should represent the particle textures if bound correctly | ||
this.bindParticleTexture(ParticleShaderTextureSlot.TEXTURE, TextureUtil.getBlockTextureId()); | ||
this.bindLightTexture(ParticleShaderTextureSlot.LIGHT, TextureUtil.getLightTextureId()); | ||
} | ||
|
||
private void bindParticleTexture(ParticleShaderTextureSlot slot, int textureId) { | ||
GlStateManager._activeTexture(GL32C.GL_TEXTURE0 + slot.ordinal()); | ||
GlStateManager._bindTexture(textureId); | ||
|
||
uniformParticleTexture.setInt(slot.ordinal()); | ||
} | ||
|
||
private void bindLightTexture(ParticleShaderTextureSlot slot, int textureId) { | ||
GlStateManager._activeTexture(GL32C.GL_TEXTURE0 + slot.ordinal()); | ||
GlStateManager._bindTexture(textureId); | ||
|
||
uniformLightTexture.setInt(slot.ordinal()); | ||
} | ||
|
||
private enum ParticleShaderTextureSlot { | ||
TEXTURE, | ||
LIGHT, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.