nannou-org / nannou

A Creative Coding Framework for Rust.
https://nannou.cc/
6.03k stars 304 forks source link

Questions about custom fragment shader #882

Open Enigmatisms opened 2 years ago

Enigmatisms commented 2 years ago

I have been building an App which simulates light source and cast shadow when there is obstacle. After building shadow casting algorithm, I wanted to make things more good-looking, by simulating the intensity attenuation, which looks just like this: Screenshot from 2022-08-08 16-28-56

However, the outcome above is achieved by using texture. I know using texture API is simple and efficient, but initially, I was thinking about how to color tessellated polygon (tessellating the visible area, which is a polygon) to render the same effect. I tried draw.mesh().tris_colored(...), and compute color for each vertex in the triangle. Yet I believe coloring for the whole triangle is done via linear interpolation, and I have results like this: (Note that tessellated triangles are "radial" (all the triangles have one vertex right on the light source, and two others lie on the obstacles)) Screenshot from 2022-08-08 16-21-51

(You can clearly see the color discontinuity between neighboring triangles, caused by depth discontinuity)

There is no simple function for coloring vertices that can result in the desired "color continuity" between neighboring triangles via linear interpolation. Therefore, I wonder if there is a simple way in nannou, to define how a given triangle is filled (colored). For example, given a container or iterator for triangles (or quads), we can pass a user-defined function to an API, telling nannou how to color the primitives in the container.

This feature seems to be custom fragment shader, and I've read about the possibility of using self defined fragment shader in: #626. It kind of feels like I am asking for a pixel level API mentioned in #542, too. I am just not sure whether there is such a feature and if there is, how I am gonna use it.

mvklingeren commented 2 years ago

i don't understand why you've written a shadow cast algorithm. If you can just draw 3d objects, and use 3d lighting methods?

I would believe its easier to let the engine (opengl..) do such work.

But since thats what you've got now, could texture bleding be of any help? https://twitter.com/nannoucc/status/1241034086870683649

Enigmatisms commented 2 years ago

@mvklingeren Thanks for ur reply. Sure, 3D would help yet the entire application is 2D so I suppose there is no point adding one more dimension. Also, as mentioned in the question, I've already done the job by using texture (loading a radial gradient image as texture). Therefore, shadow cast algorithm or how to implement this attenuation effect are not my concern any more.

Currently, what I'm asking for is a simple case. So what if I'm trying to make more complicated stuffs? for example, a texture which is highly dynamic (ever-changing, should be controlled by the program). The main question I am trying to ask is: Can I use self-defined fragment shader (I think the answer is 'of course'), and how? Is there a simple API that can be passed a user-defined function to an API, telling nannou how to color the primitives? Or is there any extended examples or docs I can refer to?

mvklingeren commented 2 years ago

I see where you're comming from, and trying to get to unfortunately i have not much experience with fragment-shaders, to help you with that

but i was wondering -> could raytracing be of any use? :) mitchmindtree (a founder of nannou), has written one if i remember properly

-edit: link https://twitter.com/themindtree/status/1403387445748580359

-edit: to be clear, im not suggesting to make it 3d, but to use/make a raytracer flattened to 2d.

Enigmatisms commented 2 years ago

@mvklingeren That's interesting. I didn't expect a raytracer in nannou. Yet I think raytracing can only solve part of the problem, in which the effect to be implemented as something to do with lighting. I suppose fragment shader can serve more general purpose? For example, when using nannou for 2D game development, some bizarre effects can be drawn on the screen by fragment shader. I don't know whether raytracing could easily do such things, but I suppose fragment shader definitely could.