folkertdev / freestyle-svg-exporter

a Blender addon for exporting stylized lines created by the Freestyle render engine to an SVG format.
54 stars 18 forks source link

FreeStyle SVG Exporter - colors #8

Closed ghost closed 6 years ago

ghost commented 6 years ago

Dear developer, I'd like if the SVG exporter could take into account vertex coloring from geometry (instead of material's color) and turns it into an SVG gradient. I don't know how complex or simple this could be, but please share your toughts.

folkertdev commented 6 years ago

it was originally not implemented because it seemed unfeasible, but with fresh eyes it seems like this should be possible.

svg gradients are defined in terms of a factor between 0 and 1, so for every vertex on the stroke, you need to know the length along the stroke to make a point. It seems like stroke vertices store their length along the stroke, and a stroke has a total length, so that is easy.

I'll try to get a prototype working over the weekend. Thanks for the suggestion.

folkertdev commented 6 years ago

I remember now why this doesn't work generally: svg gradients are not applied along the stroke. so you could define some gradient, but it would run (for instance) from left to right over the whole image. A vertical stroke would have a constant color.

Is the gradient based on the vertex colors still valuable for you? If yes, what is your use case/idea?

xuv commented 6 years ago

@folkertdev I'm jumping in the conversation because I found the idea of gradient along a stroke to be quite pleasant... Now I understand the difficulty here and would certainly not add extra work, but it seems that Mike Bostock found a way to do gradients along an SVG stroke. Do you think this would be applicable?

folkertdev commented 6 years ago

Maybe,

That snippet uses D3.js to turn the svg path into a proper curve, subdivide it until the sections are small enough (this depends on the display size of your image, ideally the segments are less than a pixel width wide), then give each section a color based on the gradient and progression along the original stroke.

So you give up the "scalable" in svg, plus the size of your image is a lot larger. But maybe that is a trade-off you are willing to make (please let me know)

But with that idea in mind, it might be possible to subdivide on the freestyle side. I'll have to play with this a little to see what makes sense.

xuv commented 6 years ago

Yeah. You're right. That might not be the best method. Indeed, splitting the SVG stroke to a pixel size depending on scale is not really something useful in our case.

xuv commented 6 years ago

Just thinking out loud here... Maybe you already thought about this but if you create a gradient for every stroke (between 2 vertices) and you use a radial gradient with the center on the first vertex transposition and the radius of the gradient being the distance to the second vertex transposition. This would solve the vertical stroke constant problem you mentioned.

Of course, this could make an SVG file very heavy and complex if there is a lot of micro strokes with different gradients...

ghost commented 6 years ago

In response to folkertdev, my use case would be to render still (not animated) SVG files already colored (being able to not need inkscape for this task). Animation is something I didn't take in account, but just because I won't need it.

folkertdev commented 6 years ago

@mrrm92 I'm not quite sure what you mean here. Would it be enough for the gradient to be created (not displayed), or do you really want colored strokes (with a gradient) as the final product of the exporter? If the latter, are the tradeoffs that I described worth it for you (no scaling, large svg image size)

@xuv I'm worried about the join points between two vertices, but with sufficiently thin lines that should not matter.

ghost commented 6 years ago

Neither both. Just want fills with gradients instead of material''s base color

Il 03 Feb 2018 14:13, "Folkert de Vries" notifications@github.com ha scritto:

@mrrm92 https://github.com/mrrm92 I'm not quite sure what you mean here. Would it be enough for the gradient to be created (not displayed), or do you really want colored strokes (with a gradient) as the final product of the exporter? If the latter, are the tradeoffs that I described worth it for you (no scaling, large svg image size)

@xuv https://github.com/xuv I'm worried about the join points between two vertices, but with sufficiently small lines that should not matter.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/folkertdev/freestyle-svg-exporter/issues/8#issuecomment-362805109, or mute the thread https://github.com/notifications/unsubscribe-auth/AcinKLQXumsa8DtgPkQevOSbKAe-NXjQks5tRFuLgaJpZM4R1uSR .

ghost commented 6 years ago

Excuse me, I realised I weren't clear with my question. I meant: FreeStyle SVG Exporter allows to export to SVG some strokes, without filling or filled with a single color per mesh. Well, this single color should be taken from Vertex Color inside Blender, then used as the path filling color/gradient. So, let's pretend I have a box, whose coordinates are: 0,0 - 0,1 - 1,1 - 1,0 Each of the coordinates should have a color assigned, let's pretend it's: blue - red - green - yellow

Then, in the exported SVG, the result should be a square, filled with gradients, whose color are listed above.

Did I were clear this time? If not, please excuse me and ask

ghost commented 6 years ago

untitled Here's a quick example, I'd like the SVG with fills output could be the same

folkertdev commented 6 years ago

I don't think svg really supports that. There is some talk about svg meshes/patches, but it's quite old and doesn't really seem to move forward. (This project hasn't been touched in close to a year. The author of that project is in the working group for it I believe, and svg meshes are part of SVG 2 which looks like it's dead.

Additionally, if you want to use vertex colors, you need to use/somehow export those. Making a mapping between freestyle strokes and mesh vertices is not really possible as far as I know.

ghost commented 6 years ago

Indeed, my purpose was to map them. OK, nevermind

Il 04 Feb 2018 3:02 PM, "Folkert de Vries" notifications@github.com ha scritto:

I don't think svg really supports that. There is some talk about svg meshes/patches, but it's quite old and doesn't really seem to move forward. (This project https://gitlab.com/Tavmjong/mesh.js/ hasn't been touched in close to a year. The author of that project is in the working group for it I believe, and svg meshes are part of SVG 2 which looks like it's dead.

Additionally, if you want to use vertex colors, you need to use/somehow export those. Making a mapping between freestyle strokes and mesh vertices is not really possible as far as I know.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/folkertdev/freestyle-svg-exporter/issues/8#issuecomment-362909010, or mute the thread https://github.com/notifications/unsubscribe-auth/AcinKPxTYShrNJ_loaJ8nEWtE2N_EAqgks5tRbiMgaJpZM4R1uSR .

ghost commented 6 years ago

I made a little file, showcasing what I'd expect from the exporter. Basically, it's all about setting up some gradients and use them to fill the exported (SVG) lines. In my file, I used the gradient the wrong manner, mainly because I don't know SVG and I just tried to put something in. By the way, each vertex should have a color, and in the same stroke, colors should start with a vertex and end in another. I don't know how to better explain this. Just have a look at these example files I'm linking here: https://drive.google.com/open?id=1CDyIKZuheC0fayII-5EuGnlFX5vjM2kg

folkertdev commented 6 years ago

The problem is that those gradients are in the global space. If you rotate the cube, the color will still go from left to right in the screen space, not in the local object space.

So - as far as I know - it is impossible to say "here is a surface with x points that have a color, interpolate the color over the surface". There is a proposal for this feature, but it is only supported by inkscape and information on it is unclear.

Does the first image on this page roughly correspond to what you want to achieve?

ghost commented 6 years ago

Yes, exactly.

Il Gio 29 Mar 2018, 12:51 Folkert de Vries notifications@github.com ha scritto:

The problem is that those gradients are in the global space. If you rotate the cube, the color will still go from left to right in the screen space, not in the local object space.

So - as far as I know - it is impossible to say "here is a surface with x points that have a color, interpolate the color over the surface". There is a proposal for this feature, but it is only supported by inkscape and information on it is unclear.

Does the first image on this page http://tavmjong.free.fr/SVG/MESH/Mesh.html roughly correspond to what you want to achieve?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/folkertdev/freestyle-svg-exporter/issues/8#issuecomment-377198170, or mute the thread https://github.com/notifications/unsubscribe-auth/AcinKDWbu6Kb-3Et1ZpP65435AlFsmF1ks5tjLyYgaJpZM4R1uSR .

folkertdev commented 6 years ago

well, as I said information on this feature is super-vague. It was part of the svg 2 spec, but browser vendors sort of collectively said "we're not going to implement that" and thus svg 2 has never been accepted. Now some editors have support for it, but there is no real syntax as far as I'm aware.

Long story short, I can't/won't make the time investment to figure this all out, especially considering that a solution would probably only work in a specific editor.

ghost commented 6 years ago

Oh, I see. Could it be possible to have this in still images, at least?

Il Gio 29 Mar 2018, 13:05 Folkert de Vries notifications@github.com ha scritto:

well, as I said information on this feature is super-vague. It was part of the svg 2 spec, but browser vendors sort of collectively said "we're not going to implement that" and thus svg 2 has never been accepted. Now some editors have support for it, but there is no real syntax as far as I'm aware.

Long story short, I can't/won't make the time investment to figure this all out, especially considering that a solution would probably only work in a specific editor.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/folkertdev/freestyle-svg-exporter/issues/8#issuecomment-377201320, or mute the thread https://github.com/notifications/unsubscribe-auth/AcinKMXYLvS59MdjQM-pmjvCBLgdyChjks5tjMAVgaJpZM4R1uSR .

folkertdev commented 6 years ago

No, SVG (as implemented by browsers) is not capable of displaying what you want (in a flexible way at least, you can maybe fake it for a single frame with a lot of effort).

ghost commented 6 years ago

Wouldn't you neither fake this out? Anyhow, thanks

Il Gio 29 Mar 2018, 13:12 Folkert de Vries notifications@github.com ha scritto:

No, SVG (as implemented by browsers) is not capable of displaying what you want (in a flexible way at least, you can maybe fake it for a single frame with a lot of effort).

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/folkertdev/freestyle-svg-exporter/issues/8#issuecomment-377202660, or mute the thread https://github.com/notifications/unsubscribe-auth/AcinKOHz6Sx-C494tyuQFeHUBvQTZoj8ks5tjMGMgaJpZM4R1uSR .

anonimo82 commented 6 years ago

I guess he meant to use gradients as actual fills, not on a per-vertex basis, but rather use vertices as placeholders for gradient to start and finish to. So, if I'm right, the color should be indeed taken from vertex colours, but not be applied directly to path nodes, but rather as (indeed) a fill style. Also, looking at his/her SVG source, it's somewhat evident he used a gradient to paint vertices, but the gradient itself was separate from the shape used.

I also guess this way animation could be exported too.

folkertdev commented 6 years ago

I don't think that would in general. When you have a cube and lone render its edges (with edge marks) then maybe you can do it, but as shown you can do it manually. For fancier stroke styles with more complex meshes, it's really not feasible.

As mentioned, SVG gradients are extremely limited in what they can do. Most importantly here they are 2D gradients, whilst the vertex colors - and the gradient between them - is defined in 3D.

Secondly, mesh vertices don't need to map to stroke vertices, so associating mesh vertices with stroke vertices to extract the vertex color is extremely tricky.

So, I really don't see a way forward with the current SVG features that would give an end product that is nice, and there are a lot of technical hurdles.

anonimo82 commented 6 years ago

I didn't get your 2nd sentence: "As mentioned, SVG gradients are extremely limited in what they can do. Most importantly here they are 2D gradients, whilst the vertex colors - and the gradient between them - is defined in 3D." What does it mean?

Anyhow, you're right about doing this manually, but think manually fill an animation frame by frame...

By the way, as far as I understood, it's just a matter of: 1) Get the vertex color for a couple vertices 2) Define a gradient between them 3) Apply it (NOT in the stroke, but in the fill)

That's it. Why would this be so hard? I could even do this with SVG code, it's not really that hard. Animation is still apart, but possible IMHO.

folkertdev commented 6 years ago

Can you describe how that workflow would work in more detail. Is it something that can be described precisely?

Regarding the gradients - I didn't explain this very well. There are two kinds of gradients, linear and radial. The main problem is that these don't respect curvature: they cant bend locally, your fill is just sort of stamped out of the gradient background.So when drawing an S shape, the gradient will just run from left to right, and not along the shape.

anonimo82 commented 6 years ago

Yes, I know. I'm mainly interested in linear gradients, but if you see fit, radial could be a nice addition. Basicly, it's about drawing strokes (let's say a square of 0.0, 0.1, 1.1, 1.0) and then get vertex colors (let's say, in RGB values, 255.0.0, 0.255.0, 0.0.255, 0.255.255). Now, draw the square and add a gradient in the SVG code from 255.0.0 to 0.255.0, and 255.0.0 to 0.255.255. Repeat for each vertex. I hope this clears out a bit. By the way, while writing, I realized may be is not possible to have at the same time a vertical and an horizontal gradients. I'm unsure about this.

Cheers.

Edit: Yes, I verified. It's not possible to have gradients in more than one direction at a time, so this is almost pointless, unless the mesh gets triangulated and other requirements are met, which would make the whole gradients thing too hard to understand. But, at least, will you fix coloring for different materials in the same mesh? Look at this example: https://drive.google.com/open?id=1XtJIOY37jvys2celCfsbLKifNgud-Auq It contains a regular render and a SVG render from FreeStyle. The target would be to render SVG with different matierials on the same mesh, or at least keeping materials from more meshes without overlapping them.

anonimo82 commented 6 years ago

P.S.: May be you could be interested in this: https://vrm.ao2.it/section/en/files/download.html

anonimo82 commented 6 years ago

Did anyone check the link? Please, keep me posted.

anonimo82 commented 6 years ago

Look at this: https://drive.google.com/open?id=1r5LY-3KlHjQ42ZPsYt0SHTYRnWdTDF3A

folkertdev commented 6 years ago

I'm not quite sure what to look at/for. We essentially concluded that complex coloring of surfaces is not possible in current SVG, and that it is unlikely to become possible in the foreseeable future. It looks like you're trying to find different ways to render the output. Could you please open a new issue with all the relevant information if this is the case (please save me the work of clicking through a bunch of links not knowing what I'm actually looking for).

anonimo82 commented 6 years ago

Yes, sure. I also found this Liero SVG renderer, it's like the thing I've been looking for.

Liero: https://blenderartists.org/t/svg-output-script/566412