Relativistic crumbling

- Apply crumbling texture based on model space coordinates, not world
  space.
- Discard based both on crumbling alpha and diffuse alpha.
This commit is contained in:
Jozufozu 2023-11-26 19:24:04 -08:00
parent 24aa5b1795
commit be74a5a21b
8 changed files with 89 additions and 40 deletions

View file

@ -94,11 +94,24 @@ public class InstancingEngine extends AbstractEngine {
} }
try (var state = GlStateTracker.getRestoreState()) { try (var state = GlStateTracker.getRestoreState()) {
ModelBakery.DESTROY_TYPES.get(progress) var crumblingType = ModelBakery.DESTROY_TYPES.get(progress);
.setupRenderState();
for (var entry : drawMap.entrySet()) { for (var entry : drawMap.entrySet()) {
setup(entry.getKey(), Contexts.CRUMBLING); var shader = entry.getKey();
setup(shader, Contexts.CRUMBLING);
shader.material().setup();
int renderTex = RenderSystem.getShaderTexture(0);
shader.material().clear();
crumblingType.setupRenderState();
RenderSystem.setShaderTexture(1, renderTex);
GlTextureUnit.T1.makeActive();
RenderSystem.bindTexture(renderTex);
for (Runnable draw : entry.getValue()) { for (Runnable draw : entry.getValue()) {
draw.run(); draw.run();

View file

@ -17,10 +17,10 @@ public final class Contexts {
GlProgram.unbind(); GlProgram.unbind();
})); }));
// TODO: can we make crumbling a fragment material? public static final SimpleContext CRUMBLING = Context.REGISTRY.registerAndGet(new SimpleContext(Files.CRUMBLING_VERTEX, Files.CRUMBLING_FRAGMENT, program -> {
public static final SimpleContext CRUMBLING = Context.REGISTRY.registerAndGet(new SimpleContext(Files.WORLD_VERTEX, Files.CRUMBLING_FRAGMENT, program -> {
program.bind(); program.bind();
program.setSamplerBinding("flw_diffuseTex", 0); program.setSamplerBinding("flw_crumblingTex", 0);
program.setSamplerBinding("flw_diffuseTex", 1);
GlProgram.unbind(); GlProgram.unbind();
})); }));

View file

@ -1,8 +0,0 @@
#include "flywheel:api/vertex.glsl"
#include "flywheel:util/fog.glsl"
void flw_contextVertex() {
flw_distance = fog_distance(flw_vertexPos.xyz, flywheel.cameraPos.xyz, flywheel.fogShape);
gl_Position = flywheel.viewProjection * flw_vertexPos;
flw_vertexNormal = normalize(flw_vertexNormal);
}

View file

@ -1,32 +1,27 @@
#include "flywheel:api/fragment.glsl" #include "flywheel:api/fragment.glsl"
// optimize discard usage
#ifdef ALPHA_DISCARD
#ifdef GL_ARB_conservative_depth
layout (depth_greater) out float gl_FragDepth;
#endif
#endif
uniform sampler2D flw_diffuseTex; uniform sampler2D flw_diffuseTex;
uniform sampler2D flw_crumblingTex;
in vec2 flw_crumblingTexCoord;
out vec4 fragColor; out vec4 fragColor;
vec2 flattenedPos(vec3 pos, vec3 normal) { vec4 flw_crumblingSampleColor;
pos -= floor(pos) + vec3(0.5);
float sinYRot = -normal.x;
vec2 XZ = normal.xz;
float sqLength = dot(XZ, XZ);
if (sqLength > 0) {
sinYRot *= inversesqrt(sqLength);
sinYRot = clamp(sinYRot, -1, 1);
}
vec3 tangent = vec3(sqrt(1 - sinYRot * sinYRot) * (normal.z < 0 ? -1 : 1), 0, sinYRot);
vec3 bitangent = cross(tangent, normal);
mat3 tbn = mat3(tangent, bitangent, normal);
// transpose is the same as inverse for orthonormal matrices
return (transpose(tbn) * pos).xy + vec2(0.5);
}
void flw_initFragment() { void flw_initFragment() {
flw_sampleColor = texture(flw_diffuseTex, flattenedPos(flw_vertexPos.xyz, flw_vertexNormal)); flw_crumblingSampleColor = texture(flw_crumblingTex, flw_crumblingTexCoord);
// Crumbling ignores vertex colors flw_sampleColor = texture(flw_diffuseTex, flw_vertexTexCoord);
flw_fragColor = flw_sampleColor;
// Let the other components modify the diffuse color as they normally would.
flw_fragColor = flw_vertexColor * flw_sampleColor;
flw_fragOverlay = flw_vertexOverlay; flw_fragOverlay = flw_vertexOverlay;
flw_fragLight = flw_vertexLight; flw_fragLight = flw_vertexLight;
} }
@ -34,10 +29,10 @@ void flw_initFragment() {
void flw_contextFragment() { void flw_contextFragment() {
vec4 color = flw_fragColor; vec4 color = flw_fragColor;
// Ignore the discard predicate since we control the texture. // Still need to discard based on the diffuse color so we don't crumble over empty space.
if (color.a < 0.01) { if (flw_discardPredicate(color) || flw_crumblingSampleColor.a < 0.01) {
discard; discard;
} }
fragColor = flw_fogFilter(color); fragColor = flw_fogFilter(flw_crumblingSampleColor);
} }

View file

@ -1 +1,37 @@
#include "flywheel:context/common.vert" #include "flywheel:api/vertex.glsl"
#include "flywheel:util/fog.glsl"
out vec2 flw_crumblingTexCoord;
vec3 tangent(vec3 normal) {
float sinYRot = -normal.x;
vec2 XZ = normal.xz;
float sqLength = dot(XZ, XZ);
if (sqLength > 0) {
sinYRot *= inversesqrt(sqLength);
sinYRot = clamp(sinYRot, -1, 1);
}
return vec3(sqrt(1 - sinYRot * sinYRot) * (normal.z < 0 ? -1 : 1), 0, sinYRot);
}
vec2 flattenedPos(vec3 pos, vec3 normal) {
pos -= vec3(0.5);
vec3 tangent = tangent(normal);
vec3 bitangent = cross(tangent, normal);
mat3 tbn = mat3(tangent, bitangent, normal);
// transpose is the same as inverse for orthonormal matrices
return (transpose(tbn) * pos).xy + vec2(0.5);
}
void flw_initVertex() {
flw_crumblingTexCoord = flattenedPos(flw_vertexPos.xyz, flw_vertexNormal);
}
void flw_contextVertex() {
flw_distance = fog_distance(flw_vertexPos.xyz, flywheel.cameraPos.xyz, flywheel.fogShape);
gl_Position = flywheel.viewProjection * flw_vertexPos;
flw_vertexNormal = normalize(flw_vertexNormal);
}

View file

@ -1 +1,12 @@
#include "flywheel:context/common.vert" #include "flywheel:api/vertex.glsl"
#include "flywheel:util/fog.glsl"
void flw_initVertex() {
// noop
}
void flw_contextVertex() {
flw_distance = fog_distance(flw_vertexPos.xyz, flywheel.cameraPos.xyz, flywheel.fogShape);
gl_Position = flywheel.viewProjection * flw_vertexPos;
flw_vertexNormal = normalize(flw_vertexNormal);
}

View file

@ -26,6 +26,7 @@ void main() {
_flw_materialFragmentID = drawCommands[batchID].fragmentMaterialID; _flw_materialFragmentID = drawCommands[batchID].fragmentMaterialID;
flw_layoutVertex(); flw_layoutVertex();
flw_initVertex();
flw_instanceVertex(i); flw_instanceVertex(i);
flw_materialVertex(); flw_materialVertex();
flw_contextVertex(); flw_contextVertex();

View file

@ -9,6 +9,7 @@ void main() {
FlwInstance i = _flw_unpackInstance(); FlwInstance i = _flw_unpackInstance();
flw_layoutVertex(); flw_layoutVertex();
flw_initVertex();
flw_instanceVertex(i); flw_instanceVertex(i);
flw_materialVertex(); flw_materialVertex();
flw_contextVertex(); flw_contextVertex();