mirror of
https://github.com/Nexoniarz/Fry3DX.git
synced 2026-11-03 04:24:26 +00:00
Close up no longer falls apart: how near the nearest thing is goes by each object's box (not a ball round it: inside a big or long flat one's ball it came to nothing, the near plane with it, and surfaces fought each other in blocks, jittering, the sky and grid gone), the near plane a quarter of the way to it; reference pictures count too. Grid lines meet exactly where their pieces join (no crawling dots): a streak's ends each face the eye, each its own width; pieces a quarter further from the eye each. The depth pre-pass waited on before the scene uses it; the same depth in both (invariant)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
d313a9452a
commit
9d9557117a
9 changed files with 102 additions and 51 deletions
|
|
@ -211,14 +211,14 @@ void Renderer::drawSprite(const glm::vec3& at, float size, const glm::vec4& colo
|
|||
list.push_back({glm::vec4(at, size * 0.5f), color, glm::vec4(0, 0, 0, rotation), glm::vec4(0, 0, 0, tex)});
|
||||
}
|
||||
|
||||
void Renderer::drawStreak(const glm::vec3& from, const glm::vec3& to, float width, const glm::vec4& color, TextureId texture, bool additive) {
|
||||
void Renderer::drawStreak(const glm::vec3& from, const glm::vec3& to, float width, const glm::vec4& color, TextureId texture, bool additive, float widthTo) {
|
||||
auto& list = additive ? packet_.glowSprites : packet_.sprites;
|
||||
if (list.size() >= 8192) return;
|
||||
uint32_t bits = texture;
|
||||
float tex;
|
||||
std::memcpy(&tex, &bits, 4);
|
||||
// up.xyz: half its length along it (non-zero marks a streak; its side is found per frame).
|
||||
list.push_back({glm::vec4((from + to) * 0.5f, width * 0.5f), color, glm::vec4(0.0f), glm::vec4((to - from) * 0.5f, tex)});
|
||||
// up.xyz: half its length along it (non-zero marks a streak); right.w: half its width at `to`.
|
||||
list.push_back({glm::vec4((from + to) * 0.5f, width * 0.5f), color, glm::vec4(0.0f, 0.0f, 0.0f, (widthTo < 0.0f ? width : widthTo) * 0.5f), glm::vec4((to - from) * 0.5f, tex)});
|
||||
}
|
||||
|
||||
void Renderer::drawModel(ModelId model, const glm::mat4& transform, const glm::vec4& tint, const std::vector<glm::mat4>* skin,
|
||||
|
|
@ -757,11 +757,9 @@ void Renderer::buildPacket(uint32_t width, uint32_t height) {
|
|||
up = glm::cross(right, f);
|
||||
for (auto* list : {&p.sprites, &p.glowSprites})
|
||||
for (gpu::Sprite& s : *list) {
|
||||
if (const glm::vec3 half(s.up); glm::dot(half, half) > 0.0f) { // a streak: its side faces the eye
|
||||
glm::vec3 side = glm::cross(half, camera_.origin - glm::vec3(s.posSize));
|
||||
side = glm::length(side) > 1e-6f ? glm::normalize(side) : right;
|
||||
s.right = glm::vec4(side * s.posSize.w, 0.0f);
|
||||
s.posSize.w = 1.0f;
|
||||
if (const glm::vec3 half(s.up); glm::dot(half, half) > 0.0f) { // a streak: each end's side faces the eye (sprite.vert)
|
||||
s.right = glm::vec4(camera_.origin, s.right.w);
|
||||
s.posSize.w = -std::max(s.posSize.w, 1e-9f); // (below 0: a streak; its half width at `from`)
|
||||
continue;
|
||||
}
|
||||
s.right = glm::vec4(right, s.right.w), s.up = glm::vec4(up, s.up.w);
|
||||
|
|
|
|||
|
|
@ -98,9 +98,9 @@ public:
|
|||
// A particle: a camera-facing square `size` across, unlit (color can be HDR-bright).
|
||||
// additive: light added on (fire, sparks, flashes); else blended (smoke, dust).
|
||||
void drawSprite(const glm::vec3& at, float size, const glm::vec4& color, TextureId texture, float rotation = 0.0f, bool additive = true);
|
||||
// A sprite stretched from `from` to `to`, `width` across, turned to face the eye as much as
|
||||
// it can (rain).
|
||||
void drawStreak(const glm::vec3& from, const glm::vec3& to, float width, const glm::vec4& color, TextureId texture, bool additive = false);
|
||||
// A sprite stretched from `from` to `to`, `width` across (`widthTo` at `to`: < 0, the same),
|
||||
// each end turned to face the eye as much as it can (rain; lines drawn in pieces meet exactly).
|
||||
void drawStreak(const glm::vec3& from, const glm::vec3& to, float width, const glm::vec4& color, TextureId texture, bool additive = false, float widthTo = -1.0f);
|
||||
// skin: one matrix per joint (anim::skinMatrices) for skinned models; ignored otherwise.
|
||||
// lighting: probe light for moving things (nullptr = lightmap or simple sun shading).
|
||||
void drawModel(ModelId model, const glm::mat4& transform, const glm::vec4& tint = glm::vec4(1.0f),
|
||||
|
|
|
|||
|
|
@ -373,6 +373,10 @@ void main() {
|
|||
float c = cos(u_right.w), s = sin(u_right.w);
|
||||
vec2 r = vec2(c * q.x - s * q.y, s * q.x + c * q.y);
|
||||
vec3 world = u_posSize.xyz + (u_right.xyz * r.x + u_up.xyz * r.y) * u_posSize.w;
|
||||
if (u_posSize.w < 0.0) { // a streak: right.xyz the eye, w its half width at the far end; each end's side faces the eye
|
||||
vec3 end = u_posSize.xyz + u_up.xyz * q.y, side = cross(u_up.xyz, u_right.xyz - end);
|
||||
world = end + (length(side) > 1e-9 ? normalize(side) : vec3(0.0, 0.0, 1.0)) * q.x * (q.y < 0.0 ? -u_posSize.w : u_right.w);
|
||||
}
|
||||
v_uv = vec2(q.x * 0.5 + 0.5, 0.5 - q.y * 0.5);
|
||||
gl_Position = u_viewProj * vec4(world, 1.0);
|
||||
gl_Position.z = gl_Position.z * 2.0 - gl_Position.w;
|
||||
|
|
|
|||
|
|
@ -1413,6 +1413,17 @@ void VulkanBackend::render(FramePacket& p) {
|
|||
vkCmdSetScissor(cmd, 0, 1, &scissor);
|
||||
drawMeshes(cmd, p.opaque, p.viewProj, false, depthMeshPipeline_, depthSkinnedPipeline_, cullFor_, true);
|
||||
vkCmdEndRendering(cmd);
|
||||
// The scene pass tests against that depth: wait for it to be written (two render passes
|
||||
// aren't ordered on their own; without this, tiles of it could still be the old depth).
|
||||
VkMemoryBarrier2 mb{VK_STRUCTURE_TYPE_MEMORY_BARRIER_2};
|
||||
mb.srcStageMask = VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT;
|
||||
mb.srcAccessMask = VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
||||
mb.dstStageMask = VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT;
|
||||
mb.dstAccessMask = VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
||||
VkDependencyInfo dep{VK_STRUCTURE_TYPE_DEPENDENCY_INFO};
|
||||
dep.memoryBarrierCount = 1;
|
||||
dep.pMemoryBarriers = &mb;
|
||||
vkCmdPipelineBarrier2(cmd, &dep);
|
||||
mark(cmd, "depth pre-pass");
|
||||
depth.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,9 @@ layout(location = 0) out vec3 v_normal;
|
|||
layout(location = 1) out vec2 v_uv;
|
||||
layout(location = 2) out vec2 v_lightmapUv;
|
||||
layout(location = 3) out vec3 v_world;
|
||||
// The same depth in the depth pre-pass and the scene pass (else the compiler, dropping what the pre-pass
|
||||
// doesn't use, can round it differently and the scene pass fails its depth test in patches).
|
||||
invariant gl_Position;
|
||||
|
||||
void main() {
|
||||
Vertex vx = VERTEX(VERTEX_ID);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,9 @@ layout(location = 0) out vec3 v_normal;
|
|||
layout(location = 1) out vec2 v_uv;
|
||||
layout(location = 2) out vec2 v_lightmapUv;
|
||||
layout(location = 3) out vec3 v_world;
|
||||
// The same depth in the depth pre-pass and the scene pass (else the compiler, dropping what the pre-pass
|
||||
// doesn't use, can round it differently and the scene pass fails its depth test in patches).
|
||||
invariant gl_Position;
|
||||
|
||||
void main() {
|
||||
Vertex vx = VERTEX(VERTEX_ID);
|
||||
|
|
|
|||
|
|
@ -15,6 +15,10 @@ void main() {
|
|||
float c = cos(pc.right.w), s = sin(pc.right.w);
|
||||
vec2 r = vec2(c * q.x - s * q.y, s * q.x + c * q.y);
|
||||
vec3 world = pc.posSize.xyz + (pc.right.xyz * r.x + pc.up.xyz * r.y) * pc.posSize.w;
|
||||
if (pc.posSize.w < 0.0) { // a streak: right.xyz the eye, w its half width at the far end; each end's side faces the eye
|
||||
vec3 end = pc.posSize.xyz + pc.up.xyz * q.y, side = cross(pc.up.xyz, pc.right.xyz - end);
|
||||
world = end + (length(side) > 1e-9 ? normalize(side) : vec3(0.0, 0.0, 1.0)) * q.x * (q.y < 0.0 ? -pc.posSize.w : pc.right.w);
|
||||
}
|
||||
v_uv = q * 0.5 + 0.5;
|
||||
v_uv.y = 1.0 - v_uv.y;
|
||||
gl_Position = pc.viewProj * vec4(world, 1.0);
|
||||
|
|
|
|||
Loading…
Reference in a new issue