better billboarding
This commit is contained in:
parent
90758175ca
commit
a6875adf13
@ -355,7 +355,7 @@
|
||||
"contacts": false,
|
||||
"constraints": true,
|
||||
"rays": false,
|
||||
"depthTest": true
|
||||
"depthTest": false
|
||||
},
|
||||
"fixed step": true,
|
||||
"substeps": 4,
|
||||
|
||||
@ -9,17 +9,25 @@ layout (constant_id = 0) const uint PASSES = 1;
|
||||
layout (location = 0) in vec3 inPos;
|
||||
layout (location = 1) in vec2 inUv;
|
||||
layout (location = 2) in vec4 inColor;
|
||||
layout (location = 3) in vec2 inOffset;
|
||||
|
||||
layout( push_constant ) uniform PushBlock {
|
||||
uint pass;
|
||||
uint draw;
|
||||
} PushConstant;
|
||||
|
||||
layout (binding = 0) uniform Camera {
|
||||
Viewport viewport[PASSES];
|
||||
} camera;
|
||||
|
||||
layout (location = 0) out vec2 outUv;
|
||||
layout (location = 1) out vec4 outColor;
|
||||
|
||||
void main() {
|
||||
outUv = inUv;
|
||||
outColor = inColor;
|
||||
gl_Position = vec4(inPos.xyz, 1.0);
|
||||
}
|
||||
|
||||
vec4 clipPos = camera.viewport[PushConstant.pass].projection * camera.viewport[PushConstant.pass].view * vec4(inPos.xyz, 1.0);
|
||||
//clipPos.xy += inOffset * (clipPos.w / max(clipPos.w, 1.0));
|
||||
clipPos.xy += inOffset * min(clipPos.w, 1.0);
|
||||
gl_Position = clipPos;}
|
||||
@ -1,6 +1,7 @@
|
||||
layout (constant_id = 0) const uint PASSES = 6;
|
||||
layout (location = 0) in vec2 inPos;
|
||||
layout (location = 1) in vec2 inUv;
|
||||
layout (location = 3) in vec2 inOffset;
|
||||
|
||||
#include "./gui.h"
|
||||
|
||||
@ -33,10 +34,16 @@ layout (location = 1) out flat Gui outGui;
|
||||
void main() {
|
||||
outUv = inUv;
|
||||
outGui = ubo.gui;
|
||||
|
||||
#if GLYPH
|
||||
outVertexID = gl_VertexIndex;
|
||||
outGlyph = uboGlyph.glyph;
|
||||
#endif
|
||||
|
||||
gl_Position = ubo.matrices.model[PushConstant.pass] * vec4(inPos.xy, ubo.gui.depth, 1.0);
|
||||
gl_Position = ubo.matrices.model[PushConstant.pass] * vec4(inPos.xy + inOffset.xy, ubo.gui.depth, 1.0);
|
||||
/*
|
||||
vec4 clipPos = ubo.matrices.model[PushConstant.pass] * vec4(inPos.xy, ubo.gui.depth, 1.0);
|
||||
clipPos.xy += inOffset * clipPos.w;
|
||||
gl_Position = clipPos;
|
||||
*/
|
||||
}
|
||||
@ -9,11 +9,12 @@
|
||||
namespace pod {
|
||||
struct GlyphBox {
|
||||
struct {
|
||||
float x, y, w, h, z;
|
||||
} box;
|
||||
float x = 0, y = 0, w = 0, h = 0, z = 0;
|
||||
} box = {};
|
||||
|
||||
pod::Vector4f color;
|
||||
uint64_t code;
|
||||
pod::Vector4f color = { 1, 1, 1, 1 };
|
||||
pod::Vector3f anchor = { 0, 0, 0 };
|
||||
uint64_t code = 0;
|
||||
};
|
||||
struct TextToken {
|
||||
uf::stl::string text;
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
#define EXT_COLOR_FLOATS 1
|
||||
|
||||
namespace {
|
||||
struct Mesh {
|
||||
struct GuiVertex {
|
||||
pod::Vector3f position;
|
||||
pod::Vector2f uv;
|
||||
|
||||
@ -37,6 +37,7 @@ namespace {
|
||||
#else
|
||||
pod::Vector4b color;
|
||||
#endif
|
||||
pod::Vector2f offset;
|
||||
|
||||
static uf::stl::vector<uf::renderer::AttributeDescriptor> descriptor;
|
||||
};
|
||||
@ -58,14 +59,15 @@ namespace {
|
||||
};
|
||||
}
|
||||
|
||||
UF_VERTEX_DESCRIPTOR(Mesh,
|
||||
UF_VERTEX_DESCRIPTION(Mesh, R32G32B32_SFLOAT, position)
|
||||
UF_VERTEX_DESCRIPTION(Mesh, R32G32_SFLOAT, uv)
|
||||
UF_VERTEX_DESCRIPTOR(GuiVertex,
|
||||
UF_VERTEX_DESCRIPTION(GuiVertex, R32G32B32_SFLOAT, position)
|
||||
UF_VERTEX_DESCRIPTION(GuiVertex, R32G32_SFLOAT, uv)
|
||||
#if EXT_COLOR_FLOATS
|
||||
UF_VERTEX_DESCRIPTION(Mesh, R32G32B32A32_SFLOAT, color)
|
||||
UF_VERTEX_DESCRIPTION(GuiVertex, R32G32B32A32_SFLOAT, color)
|
||||
#else
|
||||
UF_VERTEX_DESCRIPTION(Mesh, R8G8B8A8_UNORM, color)
|
||||
UF_VERTEX_DESCRIPTION(GuiVertex, R8G8B8A8_UNORM, color)
|
||||
#endif
|
||||
UF_VERTEX_DESCRIPTION(GuiVertex, R32G32_SFLOAT, offset)
|
||||
)
|
||||
|
||||
namespace {
|
||||
@ -87,15 +89,15 @@ namespace {
|
||||
}
|
||||
|
||||
uf::Mesh& generateMesh( uf::Mesh& mesh, const pod::Vector4f& color, const pod::Vector2f& center ) {
|
||||
mesh.bind<::Mesh, uint16_t>();
|
||||
mesh.insertVertices<::Mesh>({
|
||||
{ pod::Vector3f{-1.0f, 1.0f, 0.0f} - center, pod::Vector2f{0.0f, 0.0f}, color },
|
||||
{ pod::Vector3f{-1.0f, -1.0f, 0.0f} - center, pod::Vector2f{0.0f, 1.0f}, color },
|
||||
{ pod::Vector3f{ 1.0f, -1.0f, 0.0f} - center, pod::Vector2f{1.0f, 1.0f}, color },
|
||||
mesh.bind<::GuiVertex, uint16_t>();
|
||||
mesh.insertVertices<::GuiVertex>({
|
||||
{ pod::Vector3f{-1.0f, 1.0f, 0.0f}, pod::Vector2f{0.0f, 0.0f}, color, center },
|
||||
{ pod::Vector3f{-1.0f, -1.0f, 0.0f}, pod::Vector2f{0.0f, 1.0f}, color, center },
|
||||
{ pod::Vector3f{ 1.0f, -1.0f, 0.0f}, pod::Vector2f{1.0f, 1.0f}, color, center },
|
||||
|
||||
{ pod::Vector3f{ 1.0f, -1.0f, 0.0f} - center, pod::Vector2f{1.0f, 1.0f}, color },
|
||||
{ pod::Vector3f{ 1.0f, 1.0f, 0.0f} - center, pod::Vector2f{1.0f, 0.0f}, color },
|
||||
{ pod::Vector3f{-1.0f, 1.0f, 0.0f} - center, pod::Vector2f{0.0f, 0.0f}, color },
|
||||
{ pod::Vector3f{ 1.0f, -1.0f, 0.0f}, pod::Vector2f{1.0f, 1.0f}, color, center },
|
||||
{ pod::Vector3f{ 1.0f, 1.0f, 0.0f}, pod::Vector2f{1.0f, 0.0f}, color, center },
|
||||
{ pod::Vector3f{-1.0f, 1.0f, 0.0f}, pod::Vector2f{0.0f, 0.0f}, color, center },
|
||||
});
|
||||
mesh.insertIndices<uint16_t>({
|
||||
0, 1, 2, 3, 4, 5
|
||||
@ -551,14 +553,20 @@ void ext::GuiBehavior::tick( uf::Object& self ) {
|
||||
pod::Vector2f min = { std::numeric_limits<float>::max(), std::numeric_limits<float>::max() };
|
||||
pod::Vector2f max = { -std::numeric_limits<float>::max(), -std::numeric_limits<float>::max() };
|
||||
|
||||
uf::Mesh::Attribute vertexAttribute;
|
||||
for ( auto& attribute : mesh.vertex.attributes ) if ( attribute.descriptor.name == "position" ) { vertexAttribute = attribute; break; }
|
||||
UF_ASSERT( vertexAttribute.descriptor.name == "position" );
|
||||
uf::Mesh::Attribute positionAttribute;
|
||||
uf::Mesh::Attribute offsetAttribute;
|
||||
for ( auto& attribute : mesh.vertex.attributes ) {
|
||||
if ( attribute.descriptor.name == "position" ) positionAttribute = attribute;
|
||||
if ( attribute.descriptor.name == "offset" ) offsetAttribute = attribute;
|
||||
}
|
||||
UF_ASSERT( positionAttribute.descriptor.name == "position" );
|
||||
|
||||
for ( auto i = 0; i < mesh.vertex.count; ++i ) {
|
||||
float* p = (float*) (static_cast<uint8_t*>(vertexAttribute.pointer) + i * vertexAttribute.stride );
|
||||
float* p = (float*) (static_cast<uint8_t*>(positionAttribute.pointer) + i * positionAttribute.stride );
|
||||
float* o = (float*) (static_cast<uint8_t*>(offsetAttribute.pointer) + i * offsetAttribute.stride );
|
||||
// pod::Vector4f position = { p[0], p[1], p[2], 1 };
|
||||
pod::Vector4f position = { p[0], p[1], 0, 1 };
|
||||
pod::Vector4f position = { p[0] + o[0], p[1] + o[1], 0, 1 };
|
||||
|
||||
pod::Vector4f translated = uf::matrix::multiply<float>( model, position );
|
||||
min.x = std::min( min.x, translated.x );
|
||||
max.x = std::max( max.x, translated.x );
|
||||
|
||||
@ -40,7 +40,7 @@ namespace impl {
|
||||
pod::GlyphSettings textSettings = {
|
||||
.alignment = "center",
|
||||
.font = "FragmentMono.ttf",
|
||||
.size = 24,
|
||||
.size = 48,
|
||||
.sdf = false,
|
||||
};
|
||||
}
|
||||
@ -287,7 +287,7 @@ void uf::debug::drawTexts( float dt ) {
|
||||
auto& scene = uf::scene::getCurrentScene();
|
||||
auto& controller = scene.getController();
|
||||
auto& camera = scene.getCamera( controller );
|
||||
auto& transform = camera.getTransform();
|
||||
auto transform = uf::transform::flatten( camera.getTransform() );
|
||||
|
||||
uf::stl::vector<pod::GlyphBox> textLayout;
|
||||
// pre-init with ASCII characters
|
||||
@ -309,27 +309,8 @@ void uf::debug::drawTexts( float dt ) {
|
||||
for ( auto& text : texts ) {
|
||||
auto tokens = uf::glyph::parseTextTokens( text.string, text.color );
|
||||
auto layout = uf::glyph::calculateLayout( tokens, impl::textSettings );
|
||||
|
||||
auto world = pod::Vector4f{ text.position.x, text.position.y, text.position.z, 1.0f };
|
||||
auto view = camera.getProjection() * camera.getView();
|
||||
auto clip = uf::matrix::multiply( view, world );
|
||||
|
||||
if ( clip.w <= 0.0f ) continue;
|
||||
|
||||
auto ndc = pod::Vector3f{ clip.x, clip.y, clip.z } / clip.w;
|
||||
float scale = 2.0f / clip.w;
|
||||
|
||||
if ( ndc.z < 0.0f || ndc.z > 1.0f ) continue;
|
||||
|
||||
for ( auto& g : layout ) {
|
||||
g.box.x = g.box.x * scale + ndc.x;
|
||||
g.box.y = g.box.y * scale + ndc.y;
|
||||
g.box.z = ndc.z;
|
||||
g.box.w *= scale;
|
||||
g.box.h *= scale;
|
||||
|
||||
if ( (g.box.x + g.box.w < -1.0f) || (g.box.x > 1.0f) || (g.box.y + g.box.h < -1.0f) || (g.box.y > 1.0f) ) continue;
|
||||
|
||||
g.anchor += text.position;
|
||||
textLayout.emplace_back( g );
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,7 +56,7 @@ void impl::drawBody( const pod::PhysicsBody& body ) {
|
||||
auto& projection = camera.getProjection();
|
||||
auto fov = std::atan(1.0f / fabs(projection(1,1)));
|
||||
auto angleThreshold = std::cos(fov * 1.5f);
|
||||
auto viewThresholdSq = std::pow(5, 2);
|
||||
auto viewThresholdSq = std::pow(10, 2);
|
||||
|
||||
// continuously pick the closest point on the AABB
|
||||
auto position = impl::closestPointOnAABB( cameraTransform.position, bounds );
|
||||
|
||||
@ -28,6 +28,8 @@ namespace {
|
||||
pod::Vector4b color;
|
||||
#endif
|
||||
|
||||
pod::Vector3f offset;
|
||||
|
||||
static uf::stl::vector<uf::renderer::AttributeDescriptor> descriptor;
|
||||
};
|
||||
}
|
||||
@ -40,6 +42,7 @@ UF_VERTEX_DESCRIPTOR(GlyphVertex,
|
||||
#else
|
||||
UF_VERTEX_DESCRIPTION(GlyphVertex, R8G8B8A8_UNORM, color)
|
||||
#endif
|
||||
UF_VERTEX_DESCRIPTION(GlyphVertex, R32G32_SFLOAT, offset)
|
||||
)
|
||||
|
||||
namespace {
|
||||
@ -216,6 +219,7 @@ uf::stl::vector<pod::GlyphBox> uf::glyph::calculateLayout( const uf::stl::vector
|
||||
.z = 0,
|
||||
},
|
||||
.color = token.color,
|
||||
.anchor = anchor,
|
||||
.code = c,
|
||||
});
|
||||
|
||||
@ -315,10 +319,15 @@ void uf::glyph::generateMesh( const uf::stl::vector<pod::GlyphBox>& layout, cons
|
||||
indices.insert( indices.end(), { idx, idx + 1, idx + 2, idx, idx + 2, idx + 3 });
|
||||
|
||||
// insert vertices
|
||||
vertices.emplace_back(::GlyphVertex{pod::Vector3f{ g.box.x, g.box.y + g.box.h, g.box.z }, atlas.mapUv(pod::Vector2f{ 0.0f, 0.0f }, hash), color});
|
||||
vertices.emplace_back(::GlyphVertex{pod::Vector3f{ g.box.x, g.box.y, g.box.z }, atlas.mapUv(pod::Vector2f{ 0.0f, 1.0f }, hash), color});
|
||||
vertices.emplace_back(::GlyphVertex{pod::Vector3f{ g.box.x + g.box.w, g.box.y, g.box.z }, atlas.mapUv(pod::Vector2f{ 1.0f, 1.0f }, hash), color});
|
||||
vertices.emplace_back(::GlyphVertex{pod::Vector3f{ g.box.x + g.box.w, g.box.y + g.box.h, g.box.z }, atlas.mapUv(pod::Vector2f{ 1.0f, 0.0f }, hash), color});
|
||||
auto p0 = pod::Vector2f{ g.box.x, g.box.y + g.box.h };
|
||||
auto p1 = pod::Vector2f{ g.box.x, g.box.y };
|
||||
auto p2 = pod::Vector2f{ g.box.x + g.box.w, g.box.y };
|
||||
auto p3 = pod::Vector2f{ g.box.x + g.box.w, g.box.y + g.box.h };
|
||||
|
||||
vertices.emplace_back(::GlyphVertex{g.anchor, atlas.mapUv(pod::Vector2f{ 0.0f, 0.0f }, hash), color, p0});
|
||||
vertices.emplace_back(::GlyphVertex{g.anchor, atlas.mapUv(pod::Vector2f{ 0.0f, 1.0f }, hash), color, p1});
|
||||
vertices.emplace_back(::GlyphVertex{g.anchor, atlas.mapUv(pod::Vector2f{ 1.0f, 1.0f }, hash), color, p2});
|
||||
vertices.emplace_back(::GlyphVertex{g.anchor, atlas.mapUv(pod::Vector2f{ 1.0f, 0.0f }, hash), color, p3});
|
||||
}
|
||||
|
||||
mesh.insertVertices(vertices);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user