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

z-range is only -3..3 #1626

Closed
vallsv opened this issue Apr 25, 2024 · 14 comments · Fixed by #1632
Closed

z-range is only -3..3 #1626

vallsv opened this issue Apr 25, 2024 · 14 comments · Fixed by #1632
Labels
enhancement New feature or request

Comments

@vallsv
Copy link

vallsv commented Apr 25, 2024

Is your feature request related to a problem?

I use a lot the z-index.

But i saw that the range is clamped to something quite small like 0..3 or -3...3

Outside, a component is hidden.

I have to use a lot of layers for my use cases.

Sure i still can divide 0..3 by an infinite amount of values. But i feel like more easy to deal with integer.

Requested solution or feature

Use a bigger range for the z-buffer, maybe something like 0..1000 or -1000..1000, i don't know.

Alternatives you've considered

Rescale the z-depth on my side.

Additional context

I use @h5web/lib": "7.0.2-beta.0

@vallsv vallsv added the enhancement New feature or request label Apr 25, 2024
@axelboc
Copy link
Contributor

axelboc commented Apr 25, 2024

Stacking has been sorted out in v7.1.0 with some additional bug fixes in later versions. I recommend you upgrade first then check out the Stacking documentation page. If you're still stuck at that point, let me know and we'll try to figure it out.

@vallsv
Copy link
Author

vallsv commented Apr 25, 2024

Hi, thanks for the answer.

But i only talk about the opengl canvas z-buffer.

In fact i don't use any SVG components.

@axelboc
Copy link
Contributor

axelboc commented Apr 25, 2024

Can you make a basic repro? Because, you're not giving us much to go on here. 😅 You can use this sandbox as a base and replace one of the visualizations with a Canvas with some R3F/ThreeJS children.

@vallsv
Copy link
Author

vallsv commented Apr 25, 2024

Here is an example.

As you can see the violet and the red are not visible because outside of the z-index.

So the visible z-range is in fact [-995...4].

import React from "react";
import { VisCanvas } from "@h5web/lib";

export default function App() {
  const width = 1000;
  const height = 1000;

  const stuffs = [
    {color:"#FF0018", z:-996, size:6},
    {color:"#FFA52C", z:-995, size:5},
    {color:"#FFFF41", z:-1, size:4},
    {color:"#008018", z:1, size:3},
    {color:"#0000F9", z:4, size:2},
    {color:"#86007D", z:5, size:1},
  ]

  return (
      <VisCanvas
        abscissaConfig={{
          visDomain: [-width, width],
          label: "x (px)",
        }}
        ordinateConfig={{
          visDomain: [-height * 0.6, height * 0.6],
          label: "y (px)",
        }}
        aspect="equal"
        showAxes
      >
        {stuffs.map((stuff, index)=> (
          <mesh key={`m${index}`} position-z={stuff.z}>
            <ambientLight />
            <planeGeometry attach="geometry" args={[stuff.size*50, stuff.size*50, 1, 1]} />
            <meshBasicMaterial
              attach="material"
              transparent={true}
              color={stuff.color}
              opacity={1}
            />
          </mesh>
        ))}
      </VisCanvas>
  );

image

@axelboc
Copy link
Contributor

axelboc commented Apr 25, 2024

Thanks! Okay, so this seems to match the far setting of R3F's default orthographic camera: 1000. The camera itself seems to be positioned at a z coordinate of 5, which explains why the range is [-995 5[.

We could maybe move the camera to a z coordinate of 1000 to make things easier?

@vallsv
Copy link
Author

vallsv commented Apr 26, 2024

You could use 500, so the range would be synetric -500, 500.

But if there possibility to setup the camera, i think it's even better to setup something like {near: -1000, far: 1000, position: [0, 0, 0]}. Maybe @t20100 would have a better feedback than me here.

@axelboc
Copy link
Contributor

axelboc commented Apr 29, 2024

near must be within [0 far], so I can do { near: 0, far: 2000, position: [0, 0, 1000] } to allow for a z coordinate range of [-1000 1000]?

@axelboc
Copy link
Contributor

axelboc commented Apr 29, 2024

... or [-1000 1000[ with the default near: 0.1.

@axelboc
Copy link
Contributor

axelboc commented Apr 29, 2024

Turns out the range [-1000 1000[ is incompatible with the technique we use to hide points with NaN or infinite coordinates.


Currently:

  • the visible z range is [-995 5[ (near = 0.1, far = 1000, z = 5);
  • we render "valid" points at z=0;
  • we render "invalid" points at z=1000 to hide them and the lines that connect them with other points.

The difference in z position between valid and invalid points was great enough, and the hidden portion of this range great enough, that the lines between them appeared to not be rendered. In reality, the lines were only cut off, leading to visual glitches at high-enough zoom levels:

image


With the following proposal:

  • a visible z range of [-1000 1000[ (near = 0.1, far = 2000, z = 1000);
  • a z coordinate for "invalid" points of 1000.

Since "valid" points are still rendered at z=0, lines are no longer hidden at all. That's because the hidden portions of the lines are very small (visible: [0 999.9]; hidden: [999.9 1000]).

image

Two ways to fix this:

  1. Render invalid points at an arbitrarily large positive or negative z coordinate. This will always render visual glitches, unfortunately, since there will always be a visible portion in [0 999.9] or [-1000 0].
  2. Render valid points exactly on the near or far plane of the camera's frustrum, so at z=-1000 or z=999.9.

The second solution fixes the visual glitches but is obviously not ideal, since it's much more convenient in the code to just render "valid" points at z=0 instead of always referring to a constant.


For this reason, I propose the following camera configuration: { near: 0, far: 1000, position: [0, 0, 1000] }. This gives a visible range of [0 1000] and allows "valid" points rendered at z=0 to end up right on the far plane; and by rendering "invalid" points just a bit further (e.g. at z=-1), we ensure that the lines between valid and invalid points are completely hidden and that we even get rid of the visual glitches:

image

@loichuder
Copy link
Member

Two ways to fix this:

Heh. There is a third one: use line segments instead of a single line and do no render the segments with an invalid point to avoid dealing with them in the display 😸

For this reason, I propose the following camera configuration: { near: 0, far: 1000, position: [0, 0, 1000] }

Sounds ok to me 👍

@axelboc
Copy link
Contributor

axelboc commented Apr 30, 2024

Heh. There is a third one: use line segments instead of a single line and do no render the segments with an invalid point to avoid dealing with them in the display 😸

Haha yes, indeed. Downside of course is larger geometry buffers and more complicated code with look-ahead or look-behind logic.

@vallsv
Copy link
Author

vallsv commented Apr 30, 2024

is incompatible with the technique we use to hide points with NaN or infinite coordinates.

If you use the z buffer to hide stuffs, i think it's a very bad idea.

@axelboc
Copy link
Contributor

axelboc commented Apr 30, 2024

Thanks for your input.

@t20100
Copy link
Member

t20100 commented Apr 30, 2024

threejs logs some errors for NaN & Inf, so this is not a neat way, IMO using the z-buffer nicely workaround this and sparses using segments and indices.

+1 for [0, 1000] z-range (and anyway it's configurable)

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

Successfully merging a pull request may close this issue.

4 participants