Code Monkey home page Code Monkey logo

Comments (7)

benthillerkus avatar benthillerkus commented on May 17, 2024 20

So, I've just tried out doing this the super naive way:

let fov = -150;
function scale(z) {return fov/(fov+z)};

And then on each wrapper function for canvas rendering I added:

CanvasRenderer.line = function( ctx, elem, point ) {
  let s = scale(point.z);
  ctx.lineTo( point.x * s, point.y * s);
};

Obviously this can't handle tapering of strokes, setting the fov in the factory / as a property or have the user set custom clipping planes...
Besides that this does work pretty well and I can't really see any weird distortions or wobbles on beziers.

image
image
image

It does however break the cone shape completely (for some reason it even animates itself), produces slight wobbling on Polygons (aka the Z-Dog-Charme) and it pretty much renders every single occlusion hack useless.
image
image

Still I'd be super glad if you've decided to implement this properly and ship it in the next version of Z-Dog ✌

from zdog.

desandro avatar desandro commented on May 17, 2024 17

FWIW My approach would be to add a simple scale multiply on render points given the z-distance from the origin. Definitely not mathematically accurate, but it could cover 80% of use cases in like 4 lines of code. Zdog is not trying to be the ultimate 3D engine, more like a lightweight 3D illustration tool.

from zdog.

jrus avatar jrus commented on May 17, 2024 6

The tricky thing about perspective is that the representation here is cubic Bézier segments. These are affine-invariant, which means that to apply any arbitrary affine transformation we can transform just the control points and the transformation of any arbitrary point on the curve will be correct. That is, if we call our affine transformation A, and our Bézier curve with control points [a, b, c, d] a parametric function f_[a, b, c, d] (t), we have

A(f_[a, b, c, d] (t)) = f_[A(a), A(b), A(c), A(d)] (t)

for every parameter value t. But perspective transformations are not in general affine.

Therefore, to apply a perspective transformation we need to do more work: in general there is no exact Bézier-curve (or multi-segment Bézier spline) representation of a perspective-transformed Bézier curve, so it is necessary to approximate the perspective-transformed curve by multiple Bézier segments to within some desired level of tolerance.

To implement this feature therefore requires (1) an algorithm for determining the control points of the best (or at least some) approximation of a perspective-transformed segment by a single Bézier segment, possibly under some reparametrization, (2) some kind of error metric defining the difference between two curves, (3) some scheme for subdividing the original curve, optionally optimizing the split points to reduce the number of required curves.

It turns out to be just about as easy (or hard) to support applying arbitrary transformation functions as it is to just support perspective transforms.

Let me recommend as one pretty performant method, https://observablehq.com/@jrus/bezplot

@desandro if you want help with this feature shoot me an email or something.

from zdog.

timo-jj avatar timo-jj commented on May 17, 2024 5

Took a look to the doc and If I’m not wrong there is no shadow and light parameter.. It could add a nice depth to the shapes especially if they are moving. Maybe a suggestion to explore :)

from zdog.

shaunlebron avatar shaunlebron commented on May 17, 2024 1

It's a relatively low-complexity addition

Is it though? How would you draw a simple circle, rotated on any 3D axis? With orthographic, rotated circles are just ellipses. With perspective, you either need a polygon conversion or some way to compute a spline to fit it. ·(I’d be curious to follow the spline math if that’s what you’re thinking)

from zdog.

jrus avatar jrus commented on May 17, 2024 1

It's a relatively low-complexity addition

Is it though? How would you draw a simple circle, rotated on any 3D axis? With orthographic, rotated circles are just ellipses. With perspective, you either need a polygon conversion or some way to compute a spline to fit it. ·(I’d be curious to follow the spline math if that’s what you’re thinking)

Many perspective transformations of circles are ellipses. Of course, if you go far enough you get hyperbolas instead, and then need to approximate those with cubic polynomial segments.

from zdog.

motionarray avatar motionarray commented on May 17, 2024

Yes, this. It'd be great to have shapes change perspective in relationship to where they are on a webpage as you scroll down.

from zdog.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.