Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some trouble with LineGL3D shader when camera is close #634

Open
bz-next opened this issue Feb 10, 2024 · 1 comment
Open

Some trouble with LineGL3D shader when camera is close #634

bz-next opened this issue Feb 10, 2024 · 1 comment

Comments

@bz-next
Copy link

bz-next commented Feb 10, 2024

I toyed around with the LineGL3D shader to render a simple debug grid:

image

The trouble is, when I zoom in close to the grid, the window gets filled with some artifacts:

image

image

I am just using the default LineGL3D shader with no special config.

Below is the code that generates the line objects and attaches the drawables:

{
        debugLine = new GL::Mesh{
            MeshTools::compileLines(
                MeshTools::generateLines(
                    WorldPrimitiveGenerator::debugLine(
                        {-1.0f, 0.0f, 0.0f},
                        {1.0f, 0.0f, 0.0f})))};
        Object3D *debugLines = new Object3D{};
        debugLines->setParent(worldParent);
        debugLines->scale(Vector3{100.0, 100.0, 100.0});
        // Create debug grid
        int numLines = 20;
        float start = -1.0f;
        float step = 2.0f/numLines;

        // xy grid
        for (int i = 0; i <= numLines; ++i) {
            Object3D *xline = new Object3D{};
            xline->setParent(debugLines);
            xline->translate({0.0f, start+i*step, 0.0f});
            new DebugLineDrawable{*xline, _lineShader, 0.5*Color3{1.0f, 0.0f, 0.0f}, *debugLine, *worldDebugDrawables};
            Object3D *yline = new Object3D{};
            yline->setParent(debugLines);
            yline->rotateZ(Deg(90.0f));
            yline->translate({start+i*step, 0.0f, 0.0f});
            new DebugLineDrawable{*yline, _lineShader, 0.5*Color3{0.0f, 1.0f, 0.0f}, *debugLine, *worldDebugDrawables};
        }
        Object3D *zline = new Object3D{};
        zline->setParent(debugLines);
        zline->rotateY(Deg(90.0));
        new DebugLineDrawable{*zline, _lineShader, 0.5*Color3{0.0f, 0.0f, 1.0f}, *debugLine, *worldDebugDrawables};
    }

And the drawable itself:

void DebugLineDrawable::draw(const Matrix4& transformationMatrix, SceneGraph::Camera3D& camera) {
    _shader
        .setColor(_color)
        .setViewportSize(Vector2{GL::defaultFramebuffer.viewport().size()})
        .setTransformationProjectionMatrix(camera.projectionMatrix()*transformationMatrix)
        .setWidth(2.0f)
        .draw(_mesh);
}

Generator for the debug line mesh:

Trade::MeshData WorldPrimitiveGenerator::debugLine(Magnum::Math::Vector3<float> a, Magnum::Math::Vector3<float> b) {
    constexpr Trade::MeshAttributeData AttributeData3DWireframe[]{
        Trade::MeshAttributeData{Trade::MeshAttribute::Position, VertexFormat::Vector3,
            0, 0, sizeof(Vector3)}
    };
    constexpr UnsignedInt points = 11;

    Containers::Array<char> vertexData{points*sizeof(Vector3)};
    auto positions = Containers::arrayCast<Vector3>(vertexData);
    Vector3 delta = b-a;
    delta /= float(points)-1;

    Vector3 pos = a;
    for (int i = 0; i < points; ++i) {
        positions[i] = pos+delta*i;
    }

    return MeshTools::copy(Trade::MeshData{MeshPrimitive::LineStrip, Utility::move(vertexData),
        Trade::meshAttributeDataNonOwningArray(AttributeData3DWireframe), UnsignedInt(positions.size())});
}

In terms of scale: The lines themselves are 2 units long (-1.0 to 1.0 on their respective axes). They are parented to an Object3D that has a scale factor of 100 in all dimensions. That Object3D is parented to another object that has a scale factor of 0.05. The overall hierarchy is:

[scene manipulator] <- [world object (0.05x)] <- [debug lines object (100x)] <- [the lines]

The camera projection matrix is defined by .setProjectionMatrix(Matrix4::perspectiveProjection(35.0_degf, 1.0f, 0.1f, 1000.0f))

I tried increasing my near plane from 0.1f to 1.0f since I read this helps with z-buffer artifacts, and it doesn't eliminate the issue, just changes it:

image

Is there something I'm doing wrong with using the shader? I've tried changing the number of points / line (ideally I'd just use 2, but I tried varying it in case it made a difference. Here I'm using 11 points.)

@mosra mosra added this to TODO in Debugging and prototyping via automation Feb 14, 2024
@mosra mosra added this to the 2023.0a milestone Feb 14, 2024
@mosra
Copy link
Owner

mosra commented Feb 14, 2024

Hello -- I already replied on Gitter, but replying here as well to not make it look like I'm ignoring this.

Artifacts with the near clip plane are a problem I'm aware of and on my list of things to fix. Enabling GL::Renderer::Feature::DepthClamp should help with that, at least in most cases. I looked around and discovered that it's now also available on WebGL, so with bb4064b you should be able to use it there as well.

I'll comment here once I get back to investigating this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Development

No branches or pull requests

2 participants