Closed vallsv closed 2 months ago
Hi, thanks for the answer.
But i only talk about the opengl canvas z-buffer.
In fact i don't use any SVG components.
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.
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>
);
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?
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.
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]
?
... or [-1000 1000[
with the default near: 0.1
.
Turns out the range [-1000 1000[
is incompatible with the technique we use to hide points with NaN
or infinite coordinates.
Currently:
z
range is [-995 5[
(near = 0.1, far = 1000, z = 5);z=0
;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:
With the following proposal:
z
range of [-1000 1000[
(near = 0.1, far = 2000, z = 1000);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]
).
Two ways to fix this:
z
coordinate. This will always render visual glitches, unfortunately, since there will always be a visible portion in [0 999.9]
or [-1000 0]
.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:
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 :smile_cat:
For this reason, I propose the following camera configuration: { near: 0, far: 1000, position: [0, 0, 1000] }
Sounds ok to me 👍
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.
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.
Thanks for your input.
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)
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