Comments (14)
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.
yup checks out.
from shader-park-website.
it'd be nice to abstract that in some way
from shader-park-website.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
This is finally implemented!
shader-park/shader-park-core@d905a7b
from shader-park-website.
Related Issues (20)
- Include three.js endpoint in Share Page HOT 1
- Fix formatting of code editor + console HOT 1
- Add Landing Page + Featured Projects w/ CMS HOT 1
- Firefox Error HOT 1
- Error loading SP in Oculus browser HOT 1
- Unable to sign up HOT 2
- Finish documentation HOT 2
- private sculptures
- Docs page explaining API categories, and what each does and hows its used HOT 1
- saving with syntax errors causes page to crash without displaying editor HOT 5
- 😄 Convert glsl sculps -> JS
- Fix Nav Bar to scale on smaller devices / turn into Hamburger
- Make /embed use a transparent background HOT 6
- Fix broken grid HOT 1
- Fix Editor Resize HOT 1
- Action Bar HOT 1
- Share Modal HOT 1
- Screen shots with transparent background show up black HOT 2
- Setup Github Sponsor / Open Collective
- add command / to comment out code on editor
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from shader-park-website.