Home Technical Talk

Blended normals hack for fake SSS

1
polycounter lvl 19
Offline / Send Message
kodde polycounter lvl 19
Hey guys,

Tried the "Blended normals" shader hack today in Mental Mill. Found info about this from Naughty Dog's Siggraph powerpoint.

Works quite alright for the rendering cost if you ask me.

Head and textures is from Infinite Realities, as posted on PC News page a week or two back.

Here's my results.

blendedNormals.gif
Gif doesn't do much justice, but it's nice to see them on top of each other for comparison reasons.


EDIT: Oh, and a big thanks for my colleague Niklas for helping out with the blended normal effect.

Replies

  • kodde
    Options
    Offline / Send Message
    kodde polycounter lvl 19
    Here's another, shows of effect even better. You get some color bleeds, but it's a matter of tweaking the effect to a point you think works best. Considering not using it you might find this to be worth it. I'm quite convinced so far.

    blendedNormals2.gif
  • r_fletch_r
    Options
    Offline / Send Message
    r_fletch_r polycounter lvl 9
    I wonder if you could merge this with the nvidia method instead of blurred RTT
  • kodde
    Options
    Offline / Send Message
    kodde polycounter lvl 19
    r_fletch_r> How do you mean? The Nvidia Human Head method? Isn't that an even more fancy form of blurring of the light?
  • r_fletch_r
    Options
    Offline / Send Message
    r_fletch_r polycounter lvl 9
    I'll have to look it up but someone adapted the nvidia method to use a set of progressively blurred normal maps to do the light scattering rather than using the suggested method of blurring a baked lightmap.

    I wondered if the same could not be done with this method, simulating scatter with the weight rather than the blur radius.. not as fancy but there would be no need to do the light blurring or use memory for multiple normal maps.
  • kodde
    Options
    Offline / Send Message
    kodde polycounter lvl 19
    Sounds interesting. Please do get back to me if you come up with something nice.

    Regarding this method it does not use multiple normals maps. From what I can tell the extra cost compared to not using it is one extra diffuse light calculation and one float3 lerp.

    What you essentially do is calculate light for diffuse light twice, once with normal map and once without. Then you lerp between these results with separate weighting values for each channel (RGB) in the lerp. You let the red color stay closer to diffuse light without normal map and the green and blue closer to the normal mapped result. This gives the illusion of the red scattering.
  • r_fletch_r
    Options
    Offline / Send Message
    r_fletch_r polycounter lvl 9
    :) I get how it works, the other method i saw used normal maps rather than baked lightmaps. using this method would be taking it 1 step further.
  • Brice Vandemoortele
    Options
    Offline / Send Message
    Brice Vandemoortele polycounter lvl 19
    you could also use lower mips of the normal map instead of the vertex normal, but there's going to be artifacts in all cases
  • kodde
    Options
    Offline / Send Message
    kodde polycounter lvl 19
    Brice> Ah, that's a nice idea. Right now I think I'm using an uncompressed normal map source. So there will be more artifacts as you mention.

    I definitely want to find out if I can force a lower mip through mental mill.

    Do you know how to force a certain mip level with HLSL/CGFX code?

    Thanks.
  • arshlevon
    Options
    Offline / Send Message
    arshlevon polycounter lvl 18
    on one of my current contract projects we are using this technique and i think its really nice when you get in there play with the blend amount, add cyan suppression, and a Fresnel based spec model. unlike the nvidia human head shader this actually runs in games. while the nvidia shader looks nice its really not practical for game development, thats why naughty dog only used a version of it in pre-rendered cinematics and not in real time.

    @kodde: i think what your looking for is called LOD bias, or mip bias, a negitive value will force higher mips a positive value will force lower mips.
  • kodde
    Options
    Offline / Send Message
    kodde polycounter lvl 19
    arshlevon> Ah thanks. Will look for info on LOD/Mip bias. Also going to look into cyan suppression.
  • arshlevon
    Options
    Offline / Send Message
    arshlevon polycounter lvl 18
    make a float value call it SuppressCyan (or whatever you want!)

    // suppress the blue and green components
    blendedDiffuse.g = min(blendedDiffuse.r + SuppressCyan, blendedDiffuse.g);
    blendedDiffuse.b = min(blendedDiffuse.r + SuppressCyan, blendedDiffuse.b);

    lower the value, the more cyan is suppressed.
  • kodde
    Options
    Offline / Send Message
    kodde polycounter lvl 19
    arshlevon wrote: »
    make a float value call it SuppressCyan (or whatever you want!)

    // suppress the blue and green components
    blendedDiffuse.g = min(blendedDiffuse.r + SuppressCyan, blendedDiffuse.g);
    blendedDiffuse.b = min(blendedDiffuse.r + SuppressCyan, blendedDiffuse.b);

    lower the value, the more cyan is suppressed.

    Ah thanks. It was along these lines I was thinking originally. But I figured there might be more to it. Shouldn't suppressing this also mean the red "bleed" effect would be less apparent? I mean, isn't there some correlation to how having much of the desired effect also means more of the not that good parts such as increased cyan?
  • arshlevon
    Options
    Offline / Send Message
    arshlevon polycounter lvl 18
    well its a balance, you don't want total suppression, i find a value of 0.4 to 0.6 works best. if you find a better way to do it let me know.
  • chronic
    Options
    Offline / Send Message
    chronic polycounter lvl 10
    my lcSkinShader_2.0.cgfx does this same thing - blended normals ala John Hable/Uncharted 2 with cyan suppression. Its all wrapped up in a compact skinShading function - take a look and copy/adapt it if its helpful
  • kodde
    Options
    Offline / Send Message
    kodde polycounter lvl 19
    arshlevon> Those values are very dependent on what your blend weighting is at from what I can tell.

    I'm used to editing my shader in Mental Mill but I'm not completely lost when editing shaders by hand. I don't have access to MM here but I went ahead an edited it by hand. Here's a video of my suppression atm. I'm quite content with it's functionality. Thank you for sharing!

    [ame]http://www.youtube.com/watch?v=8qoRmGa_eNc&hd=1[/ame]
    Cyan seems a bit suppressed with the video compression as well, not as vivid anyway. Should be 1080p available ^^


    Chronic> Yes thank you I have seen your skinshader :) Your blogpost about this and the Hable presentation is what got my attention originally.
  • odium
    Options
    Offline / Send Message
    odium polycounter lvl 18
    This... Really doesn't work at all. Putting aside it looks nothing like SSS for a second, it also works nothing like SSS giving unexpected results at every turn and never how you would want them.

    Its akin to using env mapping and calling it "specular". If your engine is really so poor that it has to use such a low effect like this, it shouldn't be using normal maps anyway.
  • arshlevon
    Options
    Offline / Send Message
    arshlevon polycounter lvl 18
    odium wrote: »
    This... Really doesn't work at all. Putting aside it looks nothing like SSS for a second, it also works nothing like SSS giving unexpected results at every turn and never how you would want them.

    Its akin to using env mapping and calling it "specular". If your engine is really so poor that it has to use such a low effect like this, it shouldn't be using normal maps anyway.


    i disagree completely, when you use proper maps and good settings it looks great. go play uncharted 2, or read the white paper, i would say currently for its cost is the best way to attempt SSS in "real time"

    this is using the same method, just took this from maya...

    ****see one post down*****
  • cman2k
    Options
    Offline / Send Message
    cman2k polycounter lvl 17
    odium wrote: »
    Its akin to using env mapping and calling it "specular". If your engine is really so poor that it has to use such a low effect like this, it shouldn't be using normal maps anyway.

    In addition, Image-based reflections (env maps) are technically closer to 'specular' and more physically correct than what most games use. "Specular" is a fake concept used to make up for our inability to diffuse light and reflections in real-time.

    Cubemaps are also more expensive than specular. So your analogy really doesn't make any sense.
  • arshlevon
    Options
    Offline / Send Message
    arshlevon polycounter lvl 18
    Okay so to make it even a better comparison, here is the same model kodde is using for his tests, only with a little love to the settings and a proper spec map.

    headder2.jpg

    headder3.jpg
  • kodde
    Options
    Offline / Send Message
    kodde polycounter lvl 19
    That looks nice arshlevon. Can you show us with/without comparison of the difference the blended normals do?
  • arshlevon
    Options
    Offline / Send Message
    arshlevon polycounter lvl 18
  • Malus
    Options
    Offline / Send Message
    Malus polycounter lvl 17
    Arshlevon:
    A much clearer example of how powerful this can be.
    I have to disagree with Odium, it's a great 'hack' and a relatively simple and cheap one as well.
  • kodde
    Options
    Offline / Send Message
    kodde polycounter lvl 19
    Nice, I'm sold. Good job.

    EDIT:
    Does the lighting model differ anything else besides the Blended Normals? No wrap around half-lambert stuff going on? Differing Ambient lighting?
  • arshlevon
    Options
    Offline / Send Message
    arshlevon polycounter lvl 18
    i have a little bit of ambient going on, but its not different in one or the other, i am using chronic's shader by the way, as the one i have been using isn't for the maya viewport. but its the same thing really, the one i am using in production has a different spec model, but the results are similar, once you know how to make your spec map and tweak your color a bit you can get some nice stuff. what i did above was a quick test to prove a point, if i was making a real asset i would spend more time making it pretty.
  • chronic
    Options
    Offline / Send Message
    chronic polycounter lvl 10
    Its correct to say the Blended Normals technique is not a great general SSS approximation, but it is a great skin shading hack, it mimics sub-dermal/epidermal scattering pretty well at a relatively low cost.

    My skin shader does use a modified diffuse shading function with an adjustable edge, but if you pull it too far across the surface, approaching half-lambert, things stop looking realistic, but a little softening can be nice.

    Edit: taking care to be linear in your shading really helps things look better and more realistic too.
  • EarthQuake
    Options
    Offline / Send Message
    Odium, its astounding how little you know, yet how confident you are that your opinions are correct in tech talk.
  • kodde
    Options
    Offline / Send Message
    kodde polycounter lvl 19
    Chronic> Ah, thank you for confirming this with the modified diffuse model. I was trying to compare with my shading solution and I could not figure out how you got that result by just modifying blended normals. Either way, I think it works fine. It's all a matter of tweaking it to a nice level but not too far. I agree that a little bit towards half-lambert does give a nice effect for skin.

    EDIT: Do you incorporate any kind of gamma correction?
  • chronic
    Options
    Offline / Send Message
    chronic polycounter lvl 10
    @kodde - i gamma correct all rgb color imputs (swatches/textures), and reapply apply gamma on the final output.
  • kodde
    Options
    Offline / Send Message
    kodde polycounter lvl 19
    Perna that's quite cool. How does front side of the ear know that the back side of the ear is being lit? Care to elaborate or trade secret? ;)
  • arshlevon
    Options
    Offline / Send Message
    arshlevon polycounter lvl 18
    per thats nice, i notice in the 3point shader there is a lot of little subtleties that really sell the effect, i like the peach fuzz stuff, and the back scattering. might have to break down and buy your shader.
  • kodde
    Options
    Offline / Send Message
    kodde polycounter lvl 19
    So I kept at it a bit today with my shader.
    Spent a few minutes making a basic spec map with gloss. Upped to 2048 maps.

    sssfriday.jpg

    The difference between the two images is that the shot on the right has:
    -Blended normals with Cyan suppress
    -Red color tint in darker diffuse light spectrum
    -Light terminator edge pushed back slightly and tweaked a bit

    I have an idea on how to get pass through light, but without shadows it will look strange.

    EDIT: Just noticed that with blended normals you can increase normal map intensity/amount a bit above usual since this feature reduces the nasty black areas the normal map usually generates. Around 1.5x level still looked pretty good to me. The image above is still 1.0x normal map intensity.
  • fearian
    Options
    Offline / Send Message
    fearian greentooth
    Wow, the results are definitely impressive. Can someone try to match the lighting results between standard normals and blended? So far blended normals seem to make the object seem alot lighter that it would otherwise be, which would make it stand out compared to other normal map objects in my mind...
  • kodde
    Options
    Offline / Send Message
    kodde polycounter lvl 19
    fearian> I could disable the red color tint and leave the terminator edge be and you would just have the blended normals feature left. But thing is, blended normals is all about varying the lighting. First of all it is based on the normal map, so depending on what you are faking with your normal map you will get different results. Also from what I can tell it seems most prominent in the darker regions, where light is starting to diminish.

    If you look at the first posts in this thread you can see the difference between not using blended normal and using blended normal, no other really fancy things going on there.

    In this pic I think it's the pushing terminator line backwards that is also slightly increasing the light areas a bit. Shouldn't be that much though.
  • kodde
    Options
    Offline / Send Message
    kodde polycounter lvl 19
    This is the modified diffuse curve I'm using in the image above. The push back amount can be tweaked by the user ofc.

    currentcurve.jpg

    I tried using this curve earlier but as you can see some areas would actually get darker. This might not be a bad idea after all. I mean, a SSS material would absorb more light and therefor not be as lit as a non SSS material no? Or am I not seeing something? Does all the light eventually find it's way out again? Does some light deteriorate as it scatters around or how does light work?

    newcurve.jpg
  • odium
    Options
    Offline / Send Message
    odium polycounter lvl 18
    EarthQuake wrote: »
    Odium, its astounding how little you know, yet how confident you are that your opinions are correct in tech talk.

    Not really. The earlier pics really do look like trash and give off a white SSS glow rather than a proper sub dermal effect. The later pics don't exactly look perfect, but look much better, I'll admit to that.

    But the key there was in what you said... You just called my "opinions" wrong... Thats like saying I'm wrong because I don't like Mac & Cheese. How can anybody be wrong for an opinion?

    Regardless, the later shots in the thread have sold me much more than the original, hacky 1999 style normals they were showing with bad blocky lighting, so relax, its all gravy :D
  • Malus
    Options
    Offline / Send Message
    Malus polycounter lvl 17
    Odium:

    I think Earthquakes comment was more directed at how little you seemed to realise the potential of this.

    Yes the original image was not the greatest example of it but it was however a first pass attempt and therefore required us to look beyond the immediate flaws as Arshlevon did and think of its potential uses.

    Calling a work in progress image trash just highlights how little you get it btw, not cool.

    A quick read of any white-paper regarding this technique or some basic understanding of premise makes you look past the visual discrepancies in the initial example quite quickly.


    Kodde:

    Looking good, would be interested in seeing some examples with the normals pushed to 1.5 as you talked about.
  • kodde
    Options
    Offline / Send Message
    kodde polycounter lvl 19
    Malus> Gonna work some more on the shader a bit later today, I'll get you some screens with normal mapped pushed.
  • Stromberg90
    Options
    Offline / Send Message
    Stromberg90 polycounter lvl 11
    Sweet work :)

    Just wondering, but before i say something i have to make you understand that i have no technical background at all, so i shouldnt realy say anything :P

    It's about the light passing trough thin surfaces, the new render to surface maps in 2011 have a sss option wich calculates how thin a area is, isnt it possible to use some of that?
  • kodde
    Options
    Offline / Send Message
    kodde polycounter lvl 19
    Stromberg09> One idea is to render a second diffuse pass with geometry having reversed normals, if your sampled surface is being lit from behind you check that against a "depth" map as you speak of and if the sampled area is "thin enough" you add some light and possibly tint it a bit red. Far from a perfect solution but should work for some objects.

    This method needs to be combined with shadows to be more work more properly. But should be fully possible.
  • Stromberg90
    Options
    Offline / Send Message
    Stromberg90 polycounter lvl 11
    Glad to hear you have a methode to try out :)
    Even tough i'm not a character artist, i would like them to get a real good skin shader to showcase there models.
  • r_fletch_r
    Options
    Offline / Send Message
    r_fletch_r polycounter lvl 9
    Odium, no one was trying to sell it to you, or i doubt gives a crap if you like it or not. You came in and pissed on something you clearly didn't understand.
  • chronic
    Options
    Offline / Send Message
    chronic polycounter lvl 10
    Increasing the normalmap intensity can help with the softening inherent in the blended normals technique - but push it too far and you end up having a face thats crazed and strange looking. Another way to bring out the impression of more detail is to increase the intensity of the normal used for the specular calculation
  • kodde
    Options
    Offline / Send Message
    kodde polycounter lvl 19
    Here's some comparison of pushing the normal map intensity with blended and non blended normals.

    normalmapincreased.jpg
  • EarthQuake
    Options
    Offline / Send Message
    odium wrote: »
    This... Really doesn't work at all. Putting aside it looks nothing like SSS for a second, it also works nothing like SSS giving unexpected results at every turn and never how you would want them.

    Knee-jerk reaction, no helpful advice on how it could look better. You claim it is nothing like how SSS works, but provide absolutely no technical information as to how it actually should work. This whole response is akin to saying "Shit sux", without backing up your argument with any sort of reason, logic, or adding anything positive to the thread. Basically the end result of this statement is showing polycount a new and exciting way for Odium to be a twat.
    Its akin to using env mapping and calling it "specular". If your engine is really so poor that it has to use such a low effect like this, it shouldn't be using normal maps anyway.
    This is just factually incorrect on so many levels, that it makes any argument you possible could have thought about making above entirely irrelevant.

    A. "Specular" is not a real thing, its a hack, a trick to approximate the effects of general reflection. "Specular" and "Reflection" are not two different things that exist in the world.

    B. Using a proper Image Based Lighting environment in a game engine is not only more accurate, more physically realistic, it is also not a "cheap trick" that you would use in a low spec game, to suggest this is just silly.

    Moreover, using cubemaps, with gloss maps to define the sharpness of the reflection is *very much* physically accurate to how the world actually works, and in an ideal system you would have these cube maps generated in various spots of your level. Much like what HL2 does, ideally, these could be generated per-frame or very frequently to have a wonderfully realistic, persistent IBL environment, again far from a "low spec" effect. This is the next best thing to *realtime raytraced reflections*, and certainly a far leap past pointlight only dynamic lighting systems.

    C. Many games coming out today use IBL systems(cube maps!) for their games, and most games you will see come out in the future will use them. The days of Doom3 style point light only lighting are long gone, as they should be.
  • kodde
    Options
    Offline / Send Message
    kodde polycounter lvl 19
    EarthQuake wrote: »
    Moreover, using cubemaps, with gloss maps to define the sharpness of the reflection is *very much* physically accurate to how the world actually works, and in an ideal system you would have these cube maps generated in various spots of your level.

    This sounds interesting, combining gloss functionality to the reflections. By sharpness do you mean like more/less blurred?
  • EarthQuake
    Options
    Offline / Send Message
    Yes, exactly, and you can either store multiple cubemaps at various resolutions for the blur(what marmoset does) or simply use the different mip-levels(what 3ps shader does).
  • haiddasalami
    Options
    Offline / Send Message
    haiddasalami polycounter lvl 14
    @Kodde: Been lurking here but the information you, chronic, perna and arshlevon posted have helped me understand whats going on. Excellent work.

    I'm guessing everyone is seeing how much of a twat Odium is.
  • kodde
    Options
    Offline / Send Message
    kodde polycounter lvl 19
    EQ> That's a really neat idea. Gotta give that a go.

    haiddasalami> Good to hear, that's what internet forums are all about imo.
  • Malus
    Options
    Offline / Send Message
    Malus polycounter lvl 17
    EarthQuake:
    My Lead and I were talking about tinkering with the possibility of using pre-generated cubemaps for that exact purpose, do you know of any games that have or will be doing it?

    I'd love to see some tests/results.
    Maybe start a new thread if you do, so as to not high-jack Koddes awesomeness. :)
  • cman2k
    Options
    Offline / Send Message
    cman2k polycounter lvl 17
    I'm working on a game that is doing it, but we won't be out for a long while...

    I can confirm it's definitely a sweet methodology though. and it let's you make badass metals! :D

    In my shaders for this system the "gloss" is referred to as "roughness". It's stored in the alpha channel of our full-color specular maps.

    It's used to do several things including:
    controlling the cubemap mip-map levels (ie; "blurriness" of the cubemap)
    controlling the exponent of the specular (we still use specular to reflect dynamic lighting)
    mask a detail normal/specular (ie; "rough" areas can optionally get a detail normal that "smooth" areas won't get).

    I think DICE used a system like this in BFBC2? check out this awesome whitepaper on their [url=http://www.slideshare.net/repii/frostbite-rendering-architecture-and-realtime-procedural-shading-texturing-techniques-presentation?from=ss_embed
    ]frostbite rendering system[/url]. (page 51)

    As EQ said it's more physically correct than the standard cubemap/specular methods. I have spoken with several people who have compared it to mental ray's shader setup in terms of functions and controls.
1
Sign In or Register to comment.