NPR nodes proposal for Cycles 2.8x
Feature request proposal: set of Non-Photo-Realistic nodes for cycles
The following proposal consists of a set of tools aimed at giving Cycles additional Non-Photo-Realitic (NPR for short), in this document the proposal will be explained (and compared to existing tools and another proposal) and in some extend demonstrated with some working proof of concept node setups.
A working proof of concept node setup can be downloaded here (UPDATED!!!!):
blendswap.com/blends/view/91247
- Difference with NPR Uber Shader (Wasili Novratidis and Marius Oberholster)
Before starting, I think it’s necessary to explain why and how this proposal is different to the one made by Marius Oberholster and Wasillis Novratidis, both in focus and usage.
blender.community/c/rightclickselect/11bbbc/npr-in-2-8
Marius proposal mockup:
My proposal Mockup:
Their proposal is about a single Ubershader NPR node containing everything with heavy focus on realtime use with Eevee.
In the other hand, my proposal has 2 different elements (minimal setup): a Flat shader to render flat colors in an integrated way with the rest of available shaders. And a texture node where the shading should be stored, like a shadow map buffer, this way further customization of the NPR look should be possible by the flexibility of image nodes and converters already available for Cycles. Maybe this “shading texture node” could be also be used with geometry modifiers (for example: emitting particles only on projected shadows falling on certain objects).
- Reason d’être: NPR and photorealism integration
So, why this proposal? What’s wrong with Cycles and NPR? Simple: Until now (Blender 2.79) you either choose NPR only in old Blender Internal Renderer (BI for short), or realism with Cycles and to some extend BI too.
( blendernews.org/xe/Feature_Articles/1274 )
And if for some reason you want to make a piece of work with both kind of element together (for example “Who framed Rogger Rabit”), you could only use BI. Compositing is very useful tool, but in many cases can make things unnecessarily difficult (for example the cartoon character goes behind a refractive/reflective object).
"Who framed Rogger Rabbit", a classic movie with mixed reality.
This is what happens when you try to customise the Toon shader to look cellshaded, the environment breaks.
Example of mixed artistic element made in Cycles.
There also the concepts of “Versatility - Ease of Use - Artistic Freedom – Speed “.
o Issues with Toon BSDF vs true NPR
Toon BSDF is not bad but hard to use and doesn't give the exact results you may want.
The NPR tools in Cycles are too limited (only Toon BSDF Shader), and they are require many tweaks depending on the look you want to achieve, and by then other shaders tend to break. Worse: even if this look is achieved, there is no proper control on the color themselves. And there is the “Terminator Bug” too. In this case the “Toon Shader” proves not being versatile, it looks easy to use but has hidden complexity, it’s kind of fast compared with other shaders maybe, but it certainly doesn’t provide artistic freedom.
I think the versatility part is well explained, the ease of use is debatable, speed part is quite technical, so let’s dig into artistic freedom:
• Color Theory
While Color Theory is common for all kind of graphic related art (even realistic rendering), for drawings, painting, and thus NPR rendering it is vital: artist NEED to choose their colors, either as fixed color palettes, picture or movement composition based or enhanced with color, etc., even if it is not physically accurate. I really like this crash course on color theory, in this image color harmony, made by this artist. trisketched.deviantart.com/art/HOW-TO-MAKE-YOUR-ART-LOOK-NICE-Color-Harmony-423507240 In BI it is possible to do that in many different ways (diffuse, specular, color ramps, mixing nodes, normal manipulations, even shadows, etc.) per object/material. Cycles’s Toon shader? Not so much, especially if trying to do it within a realistic looking environment.
• Another issue of Toon shaders in general: “Shading Clamp”
Not a specific problem of Cycles, but 3D Toon shaders in general, most of them act in a realistic/logical of “light just add up”, where if you have more than 1 light affecting an surface, a new more lighted up color will pop up, which makes sense. But in Cartoons and Japanese animation (Anime for short), they use Cellshading which actually simplifies light into a concept I’ll be calling “Shade Clamping”, where all kind of light sources in a scene (direct light, indirect lights, environment lights, etc.) are concentrated and represented in only 2 or 3 colors, this can be done in 3D by using a Color Ramp Converter and force clamp the result.
I admit this technique and concept that only works when all light sources are of the same color (in general white), but again this is an example of things possible in BI but not in Cycles. The following proposal enables this.
- Proposal
As mentioned earlier, the proposal is comprised of several elements:
o Flat Shader
This shader purpose is to get a desired color to the final image in a way that no physical interference can modify, unless this interference’s position occludes the object from the camera (example refraction, volumetric material, mist, etc.) or it’s a secondary representation of this color (example: reflections). An additional feature is the way this shader interacts with the surrounding objects/shaders, the 2 cases that come to mind are: this shaders acts as a “Diffuse shader” when ligh bounces off of it, and the second case is that light simple doesn’t bounce off it (like a black body). Here is an example of a working proof of concept; the only missing feature is a way to ascertain the input color and the rendered color are exactly the same, but this is pretty close.
o Inverted Hull Shader
This shader has a very limited and specific use and its very tricky conceptually speaking, and that is for the “Inverted Hull outline technique”, an old modeling trick to get a 3D outline of a 3D object to make cartoons, it is similar to Freestyle, but can work in realtime giving similar results, also this technique works in reflections, refractions and transparencies as shown in the proof of concept, although there are 2 examples, mostly because of some lighting issues depending on how these nodes are arranged. The ideal case scenario is that the shader can be reflected as shown in picture A, but without affecting the lighting of the inner object as in B in case the inner object has a standard shader (for example Diffuse BSDF, if the inner object has Glossy and Glass shaders it should ignore the outliner object).
o Classic OpenGL Shading Texture
The most important part of this proposal, but also the most complicated, and the one with most incomplete proof of concept, here are many unresolved questions and my lack of understanding may make me talk about things that can’t be actually done, beware. In the picture I show 1 of 2 possible versions:
• Single node • Multiple Nodes •---- Diffuse •---- Specular •---- Shadow and AO/SSAO
The picture has a single huge node that may be more practical and personally like it more, this one could be divided in diffuse, specular and shadows, and while it may go better along with the nodal concept of cycles, it could lead to unnecessary extra work for artists.
The idea is that the bulk of the NPR rendering and shader design happen here, in the texture and color nodes level of the material, in order to get access to all mix and blend modes available. It’s because of this that most nodes in and out of this proposal are yellow. Because of the above, the light sources would be limited to vector like lights, like the ones of old BI (Sun, Point, Hemi, Spot), thus mesh lights (Emission Shader) would be entirely discarded in this stage at least. But since all of this is texture based, it can be later plugged into another shader besides “Flat Shader” if the artist wants to mix things up. I have 2 theories of implementation: The first one is by making a small renderer within Cycles; this is the reason I call this node “Classic OpenGL shading Texture Node” (needs better name, I know). So far, something like this is what both my proposal and the other one have achieved to some degree with the proof of concept setups, they can simulate Diffuse and Specular shading along NormalMaps, but limited are to a single white light source.
di3d.cl/wp-content/uploads/2018/02/03-3-proof-of-concept-classic-gl-texture.jpg
There are some issues with the light source angle (driven by a empty driver) but in general works. What is missing is an implementation of Shadows and AO. But I think it could be implemented in a similar way of shadow maps, at the very least I know that it is possible to project bitmaps as shown in this node setup:
blender.stackexchange.com/questions/70717/projecting-texture-onto-surface-from-point
It seems a function to detect if a single ray had made a collision twice is missing. The second implementation is to “simply bake in realtime the viewport graphics” (the content in the GPU that shows in the 3D viewport) into the texture, at least as an idea sounds simple, not sure how that would happen code-wise (sounds kinda hackish?). The reason I think this may be feasible is because this graphical information is the GPU memory as a buffer, or at least Eevee seems to still use buffer shadow maps, which could be re-used in Cycles.
Example using very low resolution shadow map buffer.
• Single Light Source – a way to make Light Groups
At the botom of the node, as you see in the mock-up picture, there is a socket in the nodes to choose a single light source, by default this node setup shall get light vectors from all light source objects (but not mesh lights), but with this we can have further control on how individual elements are being shaded, since this proposal already uses an independent light system I think this shouldn’t be a problem, and it’s a great feature too.
• AO or SSAO
This last point, while not critical it would be very beneficial, since AO is fairly used in NPR too for different reasons, here a little example as a way to get intersection outline.
This AO should be independent to Cycles’s AO, in fact even SSAO may work, its an interesting feature that should be considered, since Cycles’s AO can’t be used without compositing, since it’s a shader.
o Versus NPR Uber Shader
• Advantages of this proposal
• All shading design within texture nodes -> RGB Data worklow ->maximum artistic freedom. • After finishing the deisgning above, it can be further expanded/experimented with already available shaders besides proposed Flat Shader, highly versatile. • If it works as imagined, could give some sort of light group functionalities. • If it works as imagined, this texture node could be used with modifiers. Interesting modeling feature if you ask me. • Potencially noise-less in final render, if using Flatshader of course.
• Disadvantages of this proposal
• No access to shader data (green nodes) -> Only Object lights (Sun, Spot, Point Hemi) and not Mesh Lights (Emision shader lighting). • Slightly harder to use because of more nodes implied. • Not sure if actually possible? • Noise would pop up again if using normal shaders, but this is expected.
• Advantages of NPR UberShader
• Single Node, easier imposible. • Compatiblity with Mesh lights (EmissionShader). • Maybe easier to develop?
• Disadvantages of NPR UberShader
• Limited blending/mixing/masking possibilities would not enable artist to do much more than its design would enable them to. • If Cycles can’t work with light groups, neither will this shader. • Heavy focus only on realtime Eevee worries me, what about Cycles and the possible noise made out by realistic shading turned into NPR?
- Showcase of actual functions (this proposal)
o What can it do now
• White single light (maybe more but hard) Classic openGL shader • Use Ramps to modify color output and design material • Compare with drawings from artist • Using “ligh” info to modify realistic shaders or together with them
o What it currently can’t do VS BI
• Automatic multi-lights • Integrated Ramp • Shadow maps • Ao / SSAO
18 Comments
Well done! I don't remember where I read or heard it, but I'm fairly sure light groups are a thing for Cycles with 2.8. Don't quote me on it, can't find a link to confirm it, hahaha, ironic.
I think this should be done in addition to the UberShader - it will add more flexibility as it relates to shadows and AO. Reflection really do need to be fixed for NPR in cycles for sure... There is a way to make those NPR elements work in Cycles, but again will come down to compositing. If you deliver the direct and color passes for both the diffuse and glossy, you can get flat shading with flat specularity in the compositor. Unfortunately, yet again, reflections give a kick in the face...
Great proposal! Both need to be implemented! (^^,)
@marius.oberholster:
Yeah I also think both should be implemented, thanks!
@marius.oberholster: By the way Marius, what reflection issue are you talking about? The ones made by Toon BSDF when the size is small?
@raul.gonzalez.luy: No, when you have more than one glossy bounce for water or glass or mirrors. I have an example my proposal: blender.community/c/rightclickselect/11bbbc/npr-in-2-8
Scroll to the FAQ - there's a blue suzanne - check the reflection. It's one of the main reasons people can't say to just use compositing or the light path node. Doesn't fix that horrible PBR glossiness in the Cycles toon shader.
@marius.oberholster: Yeah I saw that, but that only happens if you use the Toon BSDF because it works like a weird variation of the Glossy BSDF, not sure why they took that route (maybe becuase that could emulate specularity?) It would been a lot better if they had done something similar but using as reference the Diffuse BSDF, at least midtones or shadow areas wouldn't turn into mirrors.
@raul.gonzalez.luy: The toon gloss (supposed to be specularity) gives a blinn-phong style specularity that actually responds right, but with reflectivity...(sigh) (I think it was a poor design choice, but made by people who generally don't pursue NPR, so understandable).
What about a NPR Engine AND NPR Shader nodes for current PBR Render Engine?
Could something like JOT ( jot.cs.princeton.edu/ ) be implemented into blender?
EDIT: looks like someone is already working on a Live Action NPR engine for Blender: youtube.com/watch
@mew.suaykat: I think there are people working on a (realtime) NPR engine nowadays, not sure how it is going for them, at least now there is a new node for Eevee that gives a bit of NPR capabilities to it, about Cycles, now there is ToonKit (appart from a newer version of my node setup), a paid addon that works fairly well already in 2.79 and should not have issues in 2.80 onward, saddly is OSL which means it would be CPU only rendering, but it's better than nothing.
JOT has been seen but no one seem to be doing anything with it, instead there is someone working now in LANPR as you said, but that is more outline focused instead of shading, like Freestyle, but realtime oriented with offline rendering also expected for the future. Not sure if JOT and LANPR are related, but the later seem to be able to do some stuff JOT can.
blendswap.com/blends/view/91247 I updated the node setup, this time around added matcaps, the outline material and even image tutorials. Cheers.
So where do we vote so that it will get implemented besides developer.blender.org/ ? I mean, how can we officially petition this to the devs?
@3dcinetv: This is where they recommend it be proposed and of course above the post, you can vote it up. Additionally, you can use the e-mail channels to contact the devs as a group, but you can also look for their names and contact them individually. I've contacted at least two personally. One politely told me off and another never responded (not an official dev, but still has committed a lot), hahaha. So you can choose which channel you prefer. Maybe Blender Cloud subscribers have more access to devs through there? I don't know...
@3dcinetv: Sorry for late reply (I was travelling out side the country), actually I don't know the answer, but here Marius answered thankfully.
What a pain, I can't login using my previous profile because of facebook bug :(
@raul.gonzalez.luy1: I had the same problem. Logged in with Google. Did you try that?
@marius.oberholster: Yep, tha't what I'm doing now :(
@raul.gonzalez.luy1: :( ...
@marius.oberholster: Working now! YAY
@raul.gonzalez.luy: Welcome back!! (^^,)