Embeddebug

- Simplify light invalidation api/impl
  - There are 2 use cases for invalidating collected light:
    - The embedding visual receives a light update
    - The embedding visual moves
  - In either case, it's in the visual's best interest to re-collect any
    light it might need, rather than relying on the impl to copy
    potentially outdated light.
  - Do not sample the light volume if no light is collected
- Improve debug modes
  - Calculate colors in the fragment shader to reflect any per-fragment
    material/embedding alterations to the vertex output
  - Fix light volume debug mode spewing rainbow seizure garbage
  - Add light color debug mode
This commit is contained in:
Jozufozu 2024-03-08 13:01:58 -08:00
parent 2b39b13744
commit e7a112d773
7 changed files with 63 additions and 96 deletions

View file

@ -35,19 +35,12 @@ public interface VisualEmbedding extends VisualizationContext {
* @param sizeY The size of the box in the y direction. * @param sizeY The size of the box in the y direction.
* @param sizeZ The size of the box in the z direction. * @param sizeZ The size of the box in the z direction.
*/ */
void light(BlockAndTintGetter level, int minX, int minY, int minZ, int sizeX, int sizeY, int sizeZ); void collectLight(BlockAndTintGetter level, int minX, int minY, int minZ, int sizeX, int sizeY, int sizeZ);
/** /**
* Reset any collected lighting information for the given box. * Reset any collected lighting information.
*
* @param minX The minimum x coordinate of the box.
* @param minY The minimum y coordinate of the box.
* @param minZ The minimum z coordinate of the box.
* @param sizeX The size of the box in the x direction.
* @param sizeY The size of the box in the y direction.
* @param sizeZ The size of the box in the z direction.
*/ */
void invalidateLight(int minX, int minY, int minZ, int sizeX, int sizeY, int sizeZ); void invalidateLight();
/** /**
* Delete this embedding. * Delete this embedding.

View file

@ -68,13 +68,13 @@ public class EmbeddedEnvironment extends AtomicReferenceCounted implements Envir
} }
@Override @Override
public void light(BlockAndTintGetter level, int minX, int minY, int minZ, int sizeX, int sizeY, int sizeZ) { public void collectLight(BlockAndTintGetter level, int minX, int minY, int minZ, int sizeX, int sizeY, int sizeZ) {
lightVolume.collect(level, minX, minY, minZ, sizeX, sizeY, sizeZ); lightVolume.collect(level, minX, minY, minZ, sizeX, sizeY, sizeZ);
} }
@Override @Override
public void invalidateLight(int minX, int minY, int minZ, int sizeX, int sizeY, int sizeZ) { public void invalidateLight() {
lightVolume.invalidate(minX, minY, minZ, sizeX, sizeY, sizeZ); lightVolume.delete();
} }
@Override @Override
@ -95,6 +95,9 @@ public class EmbeddedEnvironment extends AtomicReferenceCounted implements Envir
drawProgram.setVec3("_flw_oneOverLightBoxSize", oneOverSizeX, oneOverSizeY, oneOverSizeZ); drawProgram.setVec3("_flw_oneOverLightBoxSize", oneOverSizeX, oneOverSizeY, oneOverSizeZ);
drawProgram.setVec3("_flw_lightVolumeMin", lightVolume.x(), lightVolume.y(), lightVolume.z()); drawProgram.setVec3("_flw_lightVolumeMin", lightVolume.x(), lightVolume.y(), lightVolume.z());
drawProgram.setBool("_flw_useLightVolume", true);
} else {
drawProgram.setBool("_flw_useLightVolume", false);
} }
drawProgram.setMat4("_flw_model", pose); drawProgram.setMat4("_flw_model", pose);
drawProgram.setMat3("_flw_normal", normal); drawProgram.setMat3("_flw_normal", normal);

View file

@ -36,37 +36,6 @@ public class EmbeddedLightVolume {
} }
} }
public void invalidate(int minX, int minY, int minZ, int sizeX, int sizeY, int sizeZ) {
if (memoryBlock == null) {
return;
}
int oldMinX = wantedCoords.minX();
int oldMinY = wantedCoords.minY();
int oldMinZ = wantedCoords.minZ();
int oldSizeX = wantedCoords.sizeX();
int oldSizeY = wantedCoords.sizeY();
var shrank = wantedCoords.clear(minX, minY, minZ, sizeX, sizeY, sizeZ);
if (!shrank) {
return;
}
int newVolume = wantedCoords.volume();
MemoryBlock newBlock = MemoryBlock.malloc(newVolume * STRIDE);
int xOff = wantedCoords.minX() - oldMinX;
int yOff = wantedCoords.minY() - oldMinY;
int zOff = wantedCoords.minZ() - oldMinZ;
blit(memoryBlock, xOff, yOff, zOff, oldSizeX, oldSizeY, newBlock, 0, 0, 0, wantedCoords.sizeX(), wantedCoords.sizeY(), wantedCoords.sizeX(), wantedCoords.sizeY(), wantedCoords.sizeZ());
memoryBlock.free();
memoryBlock = newBlock;
}
private void paintLight(BlockAndTintGetter level, int x, int y, int z) { private void paintLight(BlockAndTintGetter level, int x, int y, int z) {
scratchPos.set(x, y, z); scratchPos.set(x, y, z);

View file

@ -4,7 +4,8 @@ public enum DebugMode {
OFF, OFF,
NORMALS, NORMALS,
INSTANCE_ID, INSTANCE_ID,
LIGHT, LIGHT_LEVEL,
LIGHT_COLOR,
OVERLAY, OVERLAY,
LIGHT_VOLUME, LIGHT_VOLUME,
} }

View file

@ -0,0 +1,20 @@
// https://stackoverflow.com/a/17479300
uint _flw_hash(in uint x) {
x += (x << 10u);
x ^= (x >> 6u);
x += (x << 3u);
x ^= (x >> 11u);
x += (x << 15u);
return x;
}
vec4 _flw_id2Color(in uint id) {
uint x = _flw_hash(id);
return vec4(
float(x & 0xFFu) / 255.0,
float((x >> 8u) & 0xFFu) / 255.0,
float((x >> 16u) & 0xFFu) / 255.0,
1.
);
}

View file

@ -1,5 +1,6 @@
#include "flywheel:internal/packed_material.glsl" #include "flywheel:internal/packed_material.glsl"
#include "flywheel:internal/diffuse.glsl" #include "flywheel:internal/diffuse.glsl"
#include "flywheel:internal/colorizer.glsl"
// optimize discard usage // optimize discard usage
#ifdef GL_ARB_conservative_depth #ifdef GL_ARB_conservative_depth
@ -15,11 +16,12 @@ in vec2 _flw_crumblingTexCoord;
#ifdef _FLW_EMBEDDED #ifdef _FLW_EMBEDDED
uniform sampler3D _flw_lightVolume; uniform sampler3D _flw_lightVolume;
in vec3 _flw_lightVolumeCoord; uniform bool _flw_useLightVolume;
in vec3 _flw_lightVolumeCoord;
#endif #endif
in vec4 _flw_debugColor; flat in uint _flw_instanceID;
out vec4 _flw_outputColor; out vec4 _flw_outputColor;
@ -30,7 +32,9 @@ void _flw_main() {
flw_fragLight = flw_vertexLight; flw_fragLight = flw_vertexLight;
#ifdef _FLW_EMBEDDED #ifdef _FLW_EMBEDDED
if (_flw_useLightVolume) {
flw_fragLight = max(flw_fragLight, texture(_flw_lightVolume, _flw_lightVolumeCoord).rg); flw_fragLight = max(flw_fragLight, texture(_flw_lightVolume, _flw_lightVolumeCoord).rg);
}
#endif #endif
flw_materialFragment(); flw_materialFragment();
@ -60,8 +64,9 @@ void _flw_main() {
color.rgb = mix(overlayColor.rgb, color.rgb, overlayColor.a); color.rgb = mix(overlayColor.rgb, color.rgb, overlayColor.a);
} }
vec4 lightColor = vec4(1.);
if (flw_material.useLight) { if (flw_material.useLight) {
vec4 lightColor = texture(flw_lightTex, clamp(flw_fragLight, 0.5 / 16.0, 15.5 / 16.0)); lightColor = texture(flw_lightTex, clamp(flw_fragLight, 0.5 / 16.0, 15.5 / 16.0));
color *= lightColor; color *= lightColor;
} }
@ -69,8 +74,27 @@ void _flw_main() {
discard; discard;
} }
if (_flw_debugMode != 0u) { switch (_flw_debugMode) {
color = _flw_debugColor; case 1u:
color = vec4(flw_vertexNormal * .5 + .5, 1.);
break;
case 2u:
color = _flw_id2Color(_flw_instanceID);
break;
case 3u:
color = vec4(vec2((flw_fragLight * 15.0 + 0.5) / 16.), 0., 1.);
break;
case 4u:
color = lightColor;
break;
case 5u:
color = vec4(flw_fragOverlay / 16., 0., 1.);
break;
#ifdef _FLW_EMBEDDED
case 6u:
color = vec4(_flw_lightVolumeCoord, 1.);
break;
#endif
} }
_flw_outputColor = flw_fogFilter(color); _flw_outputColor = flw_fogFilter(color);

View file

@ -1,28 +1,5 @@
#include "flywheel:internal/fog_distance.glsl" #include "flywheel:internal/fog_distance.glsl"
// https://stackoverflow.com/a/17479300
uint _flw_hash(in uint x) {
x += (x << 10u);
x ^= (x >> 6u);
x += (x << 3u);
x ^= (x >> 11u);
x += (x << 15u);
return x;
}
vec4 _flw_id2Color(in uint id) {
uint x = _flw_hash(id);
return vec4(
float(x & 0xFFu) / 255.0,
float((x >> 8u) & 0xFFu) / 255.0,
float((x >> 16u) & 0xFFu) / 255.0,
1.
);
}
out vec4 _flw_debugColor;
#ifdef _FLW_CRUMBLING #ifdef _FLW_CRUMBLING
out vec2 _flw_crumblingTexCoord; out vec2 _flw_crumblingTexCoord;
@ -98,6 +75,7 @@ uniform mat3 _flw_normal;
out vec3 _flw_lightVolumeCoord; out vec3 _flw_lightVolumeCoord;
#endif #endif
flat out uint _flw_instanceID;
void _flw_main(in FlwInstance instance, in uint stableInstanceID) { void _flw_main(in FlwInstance instance, in uint stableInstanceID) {
_flw_layoutVertex(); _flw_layoutVertex();
@ -121,26 +99,5 @@ void _flw_main(in FlwInstance instance, in uint stableInstanceID) {
gl_Position = flw_viewProjection * flw_vertexPos; gl_Position = flw_viewProjection * flw_vertexPos;
switch (_flw_debugMode) { _flw_instanceID = stableInstanceID;
case 0u:
_flw_debugColor = vec4(1.);
break;
case 1u:
_flw_debugColor = vec4(flw_vertexNormal * .5 + .5, 1.);
break;
case 2u:
_flw_debugColor = _flw_id2Color(stableInstanceID);
break;
case 3u:
_flw_debugColor = vec4(vec2((flw_vertexLight * 15.0 + 0.5) / 16.), 0., 1.);
break;
case 4u:
_flw_debugColor = vec4(flw_vertexOverlay / 16., 0., 1.);
break;
#ifdef _FLW_LIGHT_VOLUME
case 5u:
_flw_debugColor = vec4(_flw_lightVolumeCoord, 1.);
break;
#endif
}
} }