Coder Social home page Coder Social logo

Comments (14)

torinmb avatar torinmb commented on June 18, 2024

yess! it'd be really interesting to have groups. For a simple case is it possible to wrap the code in a function and then push it into an array to call later on in the code?

let spheres = function() {
    color(0, 1, 0);
    displace(0.2, 0, 0);
    sphere(0.2);
    color(1, 0, 0);
    reset();
    displace(-0.2, 0, 0);
    sphere(0.2);
};
let group = [spheres];
group.push(() => {
    reset();
    color(0, 0, 1);
    sphere(0.2);
});
group.forEach(item => item());

from shader-park-website.

torinmb avatar torinmb commented on June 18, 2024

image

yup checks out.

from shader-park-website.

torinmb avatar torinmb commented on June 18, 2024

it'd be nice to abstract that in some way

from shader-park-website.

torinmb avatar torinmb commented on June 18, 2024

It'd also be nice to find a way of preserving the coordinate space and treating the groups as individual objects. That way you could blend between two groups, while the objects inside the group preserve their blend modes

from shader-park-website.

PWhiddy avatar PWhiddy commented on June 18, 2024

possible api

let sp = createShape();
activateShape(sp);
displace(0.2,0.0,0.3);
mirrorX();
sphere(0.3);
reset();
box(0.2,0.2,0.2);
activateShape();
sphere(0.3);
difference();
applyShape(sp);

from shader-park-website.

torinmb avatar torinmb commented on June 18, 2024

would something like this be possible?

let sp = createShape(() => {
    displace(0.2,0.0,0.3);
    mirrorX();
    sphere(0.3);
    reset();
    box(0.2,0.2,0.2);
});

sphere(0.3);
difference();
sp();

from shader-park-website.

PWhids avatar PWhids commented on June 18, 2024

Hm that is a functional approach rather than imperative. I like functional in general although is it confusing to use both in the api?
Most other high level sdf editors Ive seen (curv, that other one you linked me recently) use a functional approach. Would it be better to switch more entirely to functional rather than the imperative style like processing?
for example-

let sub = subtract( () => {
    displace(0.2,0.0,0.3);
    mirrorX();
    sphere(0.3);
    reset();
    box(0.2,0.2,0.2);
});
sphere(0.3);
sub();

This would eliminate all the 'modes' that comes along with the processing api

from shader-park-website.

torinmb avatar torinmb commented on June 18, 2024

If you want to reuse sub you'd only be able to subtract it from other objects though. I think it's important to be able to declaratively create the df and then use the operators on the df.
With your above approach, I'd expect subtract to take 2 arguments. Granted it's still combining functional and declarative.

let sp = createShape(() => {
    displace(0.2,0.0,0.3);
    mirrorX();
    sphere(0.3);
    reset();
    box(0.2,0.2,0.2);
});
subtract(sphere(0.2), sp());

from shader-park-website.

PWhids avatar PWhids commented on June 18, 2024

Confused what you mean by "combining functional and declarative". Did you mean imperative?

I totally agree its good to be able to specify a shape and reuse it in different modes. Looking at this again, a cleaner version of the imperative/processing style would probably be like this

startShape();
    displace(0.2,0.0,0.3);
    mirrorX();
    sphere(0.3);
    reset();
    box(0.2,0.2,0.2);
let sp = endShape();

sphere(0.3);
subtract();
applyShape(sp);

Whereas the strictly functional version would look something like this

let sp = shape( () => {
    scene(
        displace(0.2,0.0,0.3, () => {
            mirrorX( () => {
                sphere( 0.3 );
            });
       } ),
       box(0.2,0.2,0.2);
       );
});

scene(
    subtract( 
        sp, 
        sphere(0.3)
    )
);

I agree I think in this case it could be good to combine functional/imperative

from shader-park-website.

torinmb avatar torinmb commented on June 18, 2024

yeah, I think it'd be good to do a combo of functional/imperative.
I worry about using purely functional because of endlessly nesting functions, but the ability to chain the operators together while maintaining an order of operations is very appealing.

One drawback to using imperative is that we'll need to use createShape quite often when we're constructing a shape, but the advantage is that the code structure will remain much flatter.

For the imperative example you gave I think it's confusing to capture the shape at endShape. I'd expect to be able to capture the return value on startShape similar to a constructor.

beginShape / endShape will have its own scope, so I'm wondering if we can just use javascript's functions to illustrate that. This would also remove the need to call endShape because the code is encapsulated in a function. You also wouldn't need to call applyShape because you could just call the function that's returned from beginShape / createShape.

I tried to illustrate both below:

// this gets rid of needing to use endShape. 
// I also like this approach because javascript developers would know that the operations that take
// place inside the function are scoped. e.g. the current coordinate space is passed in, but if we 
// call reset() it's only reset inside createShape.
let sp = createShape(() => {
    displace(0.2,0.0,0.3);
    mirrorX();
    sphere(0.3);
    reset();
    box(0.2,0.2,0.2);
});
sphere(0.2);
subtract();
sp();

E.g. calling the return value of createShape

createShape(() => {
    sphere(0.2);
    mixGeo(0.2);
    box(0.2, 0.2, 0.2);
})();
mixGeo(abs(sin(time)));
displace(0.2, 0, 0);
createShape(() => {
    torus(0.4, 0.2);
    subtract();
    box(0.2, 0.2);
})(); 

from shader-park-website.

PWhids avatar PWhids commented on June 18, 2024

That second example would be very confusing to a new user I think.
I am also realizing that in order to support nested state inside of a function/lambda, we have to implement full encapsulation of the state with a stack so that if you change any modes (geo modes or color or anything) all that state is pushed/popped from a call stack as you enter the body of each shape.
Should be possible in theory. Although will def be a bit tricky and idk how performance will be for complex scenes

from shader-park-website.

torinmb avatar torinmb commented on June 18, 2024

I think it gives us a pretty fun way of encapsulating and chaining together operations

let gird = (width, depth, shape) => {
    return createShape(() => {
        for(let x = 0; x < width; i++) {
            for (let z = 0; z < depth; i++) {
                displace(x, 0, z);
                shape();
            }
        }
    });
}
//for simple shapes you don't need to use createShape
let spheres = grid(20, 20, () => sphere(0.2));
let boxes = grid(20, 20, () => box(0.2, .2, 0.2));

spheres();
displace(0, -0.1, 0);
mixGeo(abs(sin(time)));
boxes();

//or you could do this with a more complex shape
grid(20, 20, createShape(() => {
    sphere(0.2);
    mixGeo(0.4);
    box(0.2, 0.2, 0.2);
}))();
displace(0, -0.1, 0);
mixGeo(abs(sin(time)));
grid(20, 20, () => box(0.2, .2, 0.2))();

from shader-park-website.

PWhids avatar PWhids commented on June 18, 2024

Yeah thats neat. Basically createShape lets you define new primitives which is obviously very useful.
There might there be some tricky scenarios where variable scope and ownership might have some problems when sharing variables between nesting levels. Or maybe it would be fine. I'd have to think about it more.

from shader-park-website.

PWhids avatar PWhids commented on June 18, 2024

This is finally implemented!

shader-park/shader-park-core@d905a7b

from shader-park-website.

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.