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 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.
*
* @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.
* Reset any collected lighting information.
*/
void invalidateLight(int minX, int minY, int minZ, int sizeX, int sizeY, int sizeZ);
void invalidateLight();
/**
* Delete this embedding.

View file

@ -68,13 +68,13 @@ public class EmbeddedEnvironment extends AtomicReferenceCounted implements Envir
}
@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);
}
@Override
public void invalidateLight(int minX, int minY, int minZ, int sizeX, int sizeY, int sizeZ) {
lightVolume.invalidate(minX, minY, minZ, sizeX, sizeY, sizeZ);
public void invalidateLight() {
lightVolume.delete();
}
@Override
@ -95,6 +95,9 @@ public class EmbeddedEnvironment extends AtomicReferenceCounted implements Envir
drawProgram.setVec3("_flw_oneOverLightBoxSize", oneOverSizeX, oneOverSizeY, oneOverSizeZ);
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.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) {
scratchPos.set(x, y, z);

View file

@ -4,7 +4,8 @@ public enum DebugMode {
OFF,
NORMALS,
INSTANCE_ID,
LIGHT,
LIGHT_LEVEL,
LIGHT_COLOR,
OVERLAY,
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/diffuse.glsl"
#include "flywheel:internal/colorizer.glsl"
// optimize discard usage
#ifdef GL_ARB_conservative_depth
@ -15,11 +16,12 @@ in vec2 _flw_crumblingTexCoord;
#ifdef _FLW_EMBEDDED
uniform sampler3D _flw_lightVolume;
in vec3 _flw_lightVolumeCoord;
uniform bool _flw_useLightVolume;
in vec3 _flw_lightVolumeCoord;
#endif
in vec4 _flw_debugColor;
flat in uint _flw_instanceID;
out vec4 _flw_outputColor;
@ -30,7 +32,9 @@ void _flw_main() {
flw_fragLight = flw_vertexLight;
#ifdef _FLW_EMBEDDED
flw_fragLight = max(flw_fragLight, texture(_flw_lightVolume, _flw_lightVolumeCoord).rg);
if (_flw_useLightVolume) {
flw_fragLight = max(flw_fragLight, texture(_flw_lightVolume, _flw_lightVolumeCoord).rg);
}
#endif
flw_materialFragment();
@ -60,8 +64,9 @@ void _flw_main() {
color.rgb = mix(overlayColor.rgb, color.rgb, overlayColor.a);
}
vec4 lightColor = vec4(1.);
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;
}
@ -69,8 +74,27 @@ void _flw_main() {
discard;
}
if (_flw_debugMode != 0u) {
color = _flw_debugColor;
switch (_flw_debugMode) {
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);

View file

@ -1,28 +1,5 @@
#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
out vec2 _flw_crumblingTexCoord;
@ -98,6 +75,7 @@ uniform mat3 _flw_normal;
out vec3 _flw_lightVolumeCoord;
#endif
flat out uint _flw_instanceID;
void _flw_main(in FlwInstance instance, in uint stableInstanceID) {
_flw_layoutVertex();
@ -121,26 +99,5 @@ void _flw_main(in FlwInstance instance, in uint stableInstanceID) {
gl_Position = flw_viewProjection * flw_vertexPos;
switch (_flw_debugMode) {
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
}
_flw_instanceID = stableInstanceID;
}