Last modified: 2025-03-12 17:58:11
< 2025-03-11I am having trouble getting the 2d polygon SDF to work.
It's meant to be a triangle, currently I'm not seeing anything at all.
OK, finally! I stopped doing ray marching and just plotted the immediate SDF value, and eventually made this work:
So now I'm happy that the 2d SDF is working, I can turn it 3d?
Here we go!
Working. Good.
And arc segments?
Arc segments not working. I don't quite understand the arguments to Quilez's arc segment function:
vec2 sdSqArc( in vec2 p, in vec2 a, in vec2 b, in float h, float d2min )
Skip it for now. So next up would be a polygon editor, but I want to fix the adaptive quality thing first.
OK, I got Cursor to make it rescale the render resolution without changing the canvas size. Seems to be working better.
Nothing else to do: polygon editor time!
I want to be able to edit the polygons in a SketchNode
. I'm thinking that when we are editing a polygon we'll draw the scene with the
ray marching fragment shader like normal, and then on top of that we'll have a layer where you can see the polygons that you're editing, in the same
coordinate system as the object. Should the layer on top be drawn by another shader, or just with a second HTML canvas with a see-through background?
Features for a first pass:
SketchEditor
class or whatever should take a SketchNode
as an argument and only allow editing the first polygon in the node; and only allow line segmentsSketchNode
object selected in the tree we open up the SketchEditor
SketchEditor
is open and one of the tools is selected, clicking and dragging no longer rotates the viewAlright!
Issues are:
Fixing the coordinate system mapping is proving difficult. I've had a lot of attempts with claude-3.7-sonnet-thinking and still not got it. I'm trying o1 now. If o1 can't do it I may have to work it out myself.
The shader basically implements screenToWorld()
- so maybe the thing to do is get that to work, and then get Cursor to write me the inverse?
OK, one key point is that the point comes into worldToScreen()
with no Z coordinate, so we need to implicitly set Z=0.
Woo, working!
Now the issue is that screenToWorld()
doesn't work properly. Needs to give an answer that has Z=0.
I have a workable version. It's not exactly right, but the error is small enough to live with for now. So, onwards.
So now we need pad/revolve operations.
How should this interact with child elements that aren't sketches?
I've gone with number 3 for now.
This is kind of working:
I have an extruded sketch (yay!), but the edges aren't being detected, which suggests the SDF is wrong.
Also if I apply a "Roughen" to the extruded shape, it is obvious that it is a broken SDF, because I don't get the same pattern that I get on good SDFs.
I have Extrude kind of working now, but the Roughen looks like this:
That should be the same texture on the prism as on the box.
OK, I am realising the problem. If I make my SketchNode
render as a flat object, then its distance everywhere is basically 0, which is
why it gives a broken shape when elongated. But if I make SketchNode
ignore the Z coordinate then it renders as an infinite extrusion.
I think "Extrude" and "Elongate" need to be separate operations. I also think "Elongate" may produce a broken SDF on the interior, unsure.
I need to make a TreeNode
be able to declare that it is a 2d SDF, and I also need to be able to generate child shader code in 2d mode and
3d mode.
Hmm, if I Transform
a Sketch
, I get a broken SDF again. Oh! It's because the Transform
is evaluating the sketch's 3d shader code
instead of its 2d shader code.
I guess for now we just make the Transform
node check whether its child is a 2d SDF and evaluate its 2d code if so?
Oh no! But then the transformed shape is an infinite extrusion!
We can't even just truncate the infinite extrusion in Union
, because a Union
of 2d shapes is a perfectly reasonable thing to do!
I guess sketches just show up as infinite extrusions? I have made the nodes able to report 2dness with is2d()
, in future I guess we can
make the nodes also say if they want 2d or 3d children? Forget it for now, infinite extrusions is OK.
So the plan with this is to make every node be able to give a centre and radius for a bounding sphere. The default will be infinite. And then in linear pattern etc. we only need to do a union of as many copies as fit inside one bounding sphere, and use domain repetition for the rest.
Let's say the bounding sphere has radius 5, and the spacing is 8. Then we know that the bounding spheres overlap, because
2*radius < spacing
.
For a first pass, we can do domain repetition if 2*radius <= spacing
, and explicit union otherwise.
It works if I make it always space in the Z axis, but how do I make it step in other axes?
Oh, this is not working right because my coordinate system is somehow left-handed. That may be also why other coordinate stuff wasn't working very well.
I may have fixed it. Hmm, no, I think it is still left-handed.
requestAnimationFrame()
if the pan/zoom/document etc. has changed, no need to redraw the same frame over and over againsmoothK
be renamed to blendRadius
? filletRadius
? If it doesn't act like a radius, can we make it one? If not, what else should we call it?