mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-30 23:04:57 +01:00
20/20 vision
- Calculate actual bounding sphere for glyph meshes - Cull objects that are less than a pixel on the screen
This commit is contained in:
parent
39b2508d02
commit
47b6648681
2 changed files with 63 additions and 26 deletions
|
@ -87,38 +87,46 @@ bool _flw_isVisible(uint instanceIndex, uint modelIndex) {
|
||||||
transformBoundingSphere(flw_view, center, radius);
|
transformBoundingSphere(flw_view, center, radius);
|
||||||
|
|
||||||
vec4 aabb;
|
vec4 aabb;
|
||||||
if (projectSphere(center, radius, _flw_cullData.znear, _flw_cullData.P00, _flw_cullData.P11, aabb))
|
if (projectSphere(center, radius, _flw_cullData.znear, _flw_cullData.P00, _flw_cullData.P11, aabb)) {
|
||||||
{
|
vec2 size = aabb.zw - aabb.xy;
|
||||||
float width = (aabb.z - aabb.x) * _flw_cullData.pyramidWidth;
|
|
||||||
float height = (aabb.w - aabb.y) * _flw_cullData.pyramidHeight;
|
|
||||||
|
|
||||||
int level = clamp(int(ceil(log2(max(width, height)))), 0, _flw_cullData.pyramidLevels);
|
vec2 sizeInPixels = size * flw_viewportSize;
|
||||||
|
|
||||||
ivec2 levelSize = textureSize(_flw_depthPyramid, level);
|
// Cull objects that are less than a pixel in size. Could probably make this configurable.
|
||||||
|
isVisible = isVisible && any(greaterThan(sizeInPixels, vec2(1.)));
|
||||||
|
|
||||||
ivec4 levelSizePair = ivec4(levelSize, levelSize);
|
if (isVisible) {
|
||||||
|
float width = size.x * _flw_cullData.pyramidWidth;
|
||||||
|
float height = size.y * _flw_cullData.pyramidHeight;
|
||||||
|
|
||||||
ivec4 bounds = ivec4(aabb * vec4(levelSizePair));
|
int level = clamp(int(ceil(log2(max(width, height)))), 0, _flw_cullData.pyramidLevels);
|
||||||
|
|
||||||
// Clamp to the texture bounds.
|
ivec2 levelSize = textureSize(_flw_depthPyramid, level);
|
||||||
// Since we're not going through a sampler out of bounds texel fetches will return 0.
|
|
||||||
bounds = clamp(bounds, ivec4(0), levelSizePair);
|
|
||||||
|
|
||||||
float depth01 = texelFetch(_flw_depthPyramid, bounds.xw, level).r;
|
ivec4 levelSizePair = ivec4(levelSize, levelSize);
|
||||||
float depth11 = texelFetch(_flw_depthPyramid, bounds.zw, level).r;
|
|
||||||
float depth10 = texelFetch(_flw_depthPyramid, bounds.zy, level).r;
|
|
||||||
float depth00 = texelFetch(_flw_depthPyramid, bounds.xy, level).r;
|
|
||||||
|
|
||||||
float depth;
|
ivec4 bounds = ivec4(aabb * vec4(levelSizePair));
|
||||||
if (_flw_cullData.useMin == 0) {
|
|
||||||
depth = max(max(depth00, depth01), max(depth10, depth11));
|
// Clamp to the texture bounds.
|
||||||
} else {
|
// Since we're not going through a sampler out of bounds texel fetches will return 0.
|
||||||
depth = min(min(depth00, depth01), min(depth10, depth11));
|
bounds = clamp(bounds, ivec4(0), levelSizePair);
|
||||||
|
|
||||||
|
float depth01 = texelFetch(_flw_depthPyramid, bounds.xw, level).r;
|
||||||
|
float depth11 = texelFetch(_flw_depthPyramid, bounds.zw, level).r;
|
||||||
|
float depth10 = texelFetch(_flw_depthPyramid, bounds.zy, level).r;
|
||||||
|
float depth00 = texelFetch(_flw_depthPyramid, bounds.xy, level).r;
|
||||||
|
|
||||||
|
float depth;
|
||||||
|
if (_flw_cullData.useMin == 0) {
|
||||||
|
depth = max(max(depth00, depth01), max(depth10, depth11));
|
||||||
|
} else {
|
||||||
|
depth = min(min(depth00, depth01), min(depth10, depth11));
|
||||||
|
}
|
||||||
|
|
||||||
|
float depthSphere = 1. + _flw_cullData.znear / (center.z + radius);
|
||||||
|
|
||||||
|
isVisible = isVisible && depthSphere <= depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
float depthSphere = 1. + _flw_cullData.znear / (center.z + radius);
|
|
||||||
|
|
||||||
isVisible = isVisible && depthSphere <= depth;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -308,9 +308,8 @@ public final class TextVisual {
|
||||||
private static final float[] X = new float[] { 0, 0, 1, 1 };
|
private static final float[] X = new float[] { 0, 0, 1, 1 };
|
||||||
private static final float[] Y = new float[] { 0, 1, 1, 0 };
|
private static final float[] Y = new float[] { 0, 1, 1, 0 };
|
||||||
|
|
||||||
// FIXME: what is the actual bounding sphere??
|
|
||||||
public GlyphMesh(float glyphWidth, float glyphHeight, Vector2fc[] offsets) {
|
public GlyphMesh(float glyphWidth, float glyphHeight, Vector2fc[] offsets) {
|
||||||
this(glyphWidth, glyphHeight, offsets, new Vector4f(0, 0, 0, Math.max(glyphWidth, glyphHeight) * 2 * Mth.SQRT_OF_TWO));
|
this(glyphWidth, glyphHeight, offsets, boundingSphere(glyphWidth, glyphHeight, offsets));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -344,6 +343,36 @@ public final class TextVisual {
|
||||||
public Vector4fc boundingSphere() {
|
public Vector4fc boundingSphere() {
|
||||||
return boundingSphere;
|
return boundingSphere;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Vector4fc boundingSphere(float glyphWidth, float glyphHeight, Vector2fc[] offsets) {
|
||||||
|
if (offsets.length == 0) {
|
||||||
|
return new Vector4f(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
float minX = Float.POSITIVE_INFINITY;
|
||||||
|
float minY = Float.POSITIVE_INFINITY;
|
||||||
|
float maxX = Float.NEGATIVE_INFINITY;
|
||||||
|
float maxY = Float.NEGATIVE_INFINITY;
|
||||||
|
for (Vector2fc offset : offsets) {
|
||||||
|
for (int j = 0; j < 4; j++) {
|
||||||
|
var x = offset.x() + (glyphWidth * X[j]);
|
||||||
|
var y = offset.y() + (glyphHeight * Y[j]);
|
||||||
|
minX = Math.min(minX, x);
|
||||||
|
minY = Math.min(minY, y);
|
||||||
|
maxX = Math.max(maxX, x);
|
||||||
|
maxY = Math.max(maxY, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float x = (minX + maxX) / 2;
|
||||||
|
float y = (minY + maxY) / 2;
|
||||||
|
|
||||||
|
float sizeX = maxX - minX;
|
||||||
|
float sizeY = maxY - minY;
|
||||||
|
float maxSize = Math.max(sizeX, sizeY);
|
||||||
|
|
||||||
|
return new Vector4f(x, y, 0, Mth.SQRT_OF_TWO * maxSize / 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private record GlyphEffectMesh() implements QuadMesh {
|
private record GlyphEffectMesh() implements QuadMesh {
|
||||||
|
|
Loading…
Reference in a new issue