Home Technical Talk

[PBR] Physically Based Rendering Bible

13

Replies

  • jerry
    Thanks for making this document man, it's very well done already.

    I have sort of a related question: What is rust?
    On wikipedia it's defined as an Iron-Oxide. If I'm making rust in UE4 with the metalness workflow how much of my rust would be metallic? Half, none, all? I'm not really clear on this.

    Anyone care to weigh in on this?

    Thanks.
  • marks
    Offline / Send Message
    marks greentooth
    Well, oxidisation isn't a binary process, you can have varying degrees of "how rusty" a metal is. If you want something to be only very lightly rusted, you could use a metalness value of 0.8-1.0, or for something very very rusty you could use a metalness value of 0.0-0.2
  • Xoliul
    Offline / Send Message
    Xoliul polycounter lvl 16
    Good example of why a 'value chart' wouldn't work so well; you really have to make the calls for values yourself, based on some basic understanding.
  • marks
    Offline / Send Message
    marks greentooth
    Clarification because lee called me out on it:

    Oxidization IS a binary process - at a molecular level. At the scale we're talking about here - the amount of particles which are oxidised is what we're referring to, which is what our 0-1 scale represents :) eg, how MUCH of that metal surface has become oxidized.
  • Mik2121
    Offline / Send Message
    Mik2121 polycounter lvl 9
    Uhm. The way I understand oxidized metals (and I could be very wrong here) is that for a metallic texture it would simply have lots of areas with 0.8~1.0 and lots of areas with 0.0~0.2 for where the rust would actually be. I had some guy at work that insisted that the texture would be medium grey and I told them I thought a metallic texture would either be black or white in 99% of the cases except for some more unique materials.

    Was I wrong?
  • stevston89
    Offline / Send Message
    stevston89 interpolator
    @ Mik - You really don't want midtones unless you are blending between two materials ( non metal and metal). Especially with something like rust. You will end up with something that is giving off orange specular (which rust doesn't) and is very dark in the diffuse. I would keep it close to either end of the spectrum, but not in between.
  • almighty_gir
    Offline / Send Message
    almighty_gir ngon master
    Mik2121 wrote: »
    Uhm. The way I understand oxidized metals (and I could be very wrong here) is that for a metallic texture it would simply have lots of areas with 0.8~1.0 and lots of areas with 0.0~0.2 for where the rust would actually be. I had some guy at work that insisted that the texture would be medium grey and I told them I thought a metallic texture would either be black or white in 99% of the cases except for some more unique materials.

    Was I wrong?

    you're right, in 99% of cases it should be black or white. however there are exceptions and rust is one of them.

    minor science bit here:
    you may remember from school that chemical reactions are irreversible, and usually happen "instantly". the same is true of oxidation, once a molecule becomes oxidized it stays that way forever. That's why when you want to get a rust patch cleaned off of your car, you have to sand it right down to the bare metal and treat it from there.

    Now, how to apply that to your metalness map:
    start off with white, this is your metallic layer, which will always be underneath the oxidized layer. then take a black brush, and adjust the opacity of the brush to reflect how THICK you want the layer of oxidation to be. the thicker the layer of oxidation, the blacker it becomes. It's possible to have a very fine/thin layer of oxidation that still allows a lot of light to be reflected by the underlying metal, but it's also possible for the oxidation to become so thick that no light can be reflected by the metal beneath. Also bear in mind that the thickness of the oxidized layer really doesn't need to be huge for it to reach that "zero" value, we're talking like a millimeter of thickness for complete loss of reflectivity.
  • 3py0n
    Offline / Send Message
    3py0n polycounter lvl 10
    @Jerry - Thanks man :) I appreciate that.

    @almighty_gir - Thanks for that insightful approach. Since it's a matter of personal experience and a method of working, I shall add it to the tips section if you don't mind :)

    @stevston89 - Thanks for chiming in :)
  • EarthQuake
    So, the whole "light oxidization" thing, isn't it true that if a metal shows even light oxidization, it would generally be much less reflective than .8-1 or so? Probably much closer to the 0.04 baseline? In which case you might be able to get by with tagging that as not metallic.

    Essentially, as soon as starts to rust, you can basically consider it no longer a metal.

    So here is a post from Per in another thread: http://www.polycount.com/forum/showpost.php?p=2059969&postcount=11 where he made a good example of a case where you may want partial metallic values (light rusting on certain areas).

    However, looking at it again, the areas which are only lightly rusted, are quite significantly less reflective than the un-rusted areas.

    But maybe you would still want a metalness value of 0.1 or 0.2 or something, as its probably a bit more reflective than 0.04.
  • almighty_gir
    Offline / Send Message
    almighty_gir ngon master
    I'd probably agree with that assessment, EQ.

    I was just trying to give an approach to metalness, and by painting with a black brush over a white background you're going to significantly reduce reflectivity anyway.
  • Mr Whippy
    Offline / Send Message
    Mr Whippy polycounter lvl 7
    EarthQuake wrote: »
    Good stuff

    Ah ok the metalness makes sense now.

    So in practice if you really want, you can just define a material irrespective of a metal/non-metal flag, and rely entirely on a spec map (rgb) that gives the IOR for a metal.

    But since metals generally have near zero albedo we just sub the spec rgb into the diffuse rgb space, thus saving lots of space.


    So metalness is really just a flag to say this texture is metal, or it's non-metal, thus saving some texture data.



    But as per the blued gun metals thing raised, metals often don't exist as pure any way. Or perhaps a metal drain cover on a road, with the top surface smoothed off and being near pure metal, but with rusty patches and dirt in the recesses.
    In that case you can't simply pick one or the other and you'd need to be able to define all parameters.

    So diffuse rgb, IOR rgb, and gloss, cavity and AO on another rgb, then normals perhaps on another rgb again.



    Thanks for your help so far, I've at least grasped what metalness actually is now, a simplification to allow material hard splits per shader based on metal/non-metal type.
    From it's name it sounds more like something with multiple variances, more or less metal. Not just metal or not metal.


    Cheers

    Dave
  • EarthQuake
    Not quite, metalness can be set per-pixel, not only per shader. So if you have metalic and non-metalic elements in the same texture, you would use 0 and 1 values in the metalness map. If you have partial metals, you can use a grey value in the metalness map there, but partial metals are not particularly common.
  • jerry
    Wow, thanks everyone for the input.
    I guess what I was really looking for is understanding what oxidation does to a metal. I just wasn't sure and thought perhaps oxidized metal is still just metal (with its metallic properties) in a different form.

    But it's clear now that where oxidation occurs the metal loses its metallic properties and becomes a non-conductor.

    Excellent answers. Thanks.
  • SimonT
    Offline / Send Message
    SimonT interpolator
    Thanks for all the work! Looks great!
  • Elith2
    Offline / Send Message
    Elith2 polycounter lvl 9
    Yeah this is an ace little resource you have put together, thanks for giving all the sources for what you are saying as well, further reading is always fun.

    The discussion in here has been really interesting to read through on how oxidization actually occurs/effects metals too, something I didn't have a great handle on when I was doing my first PBR prop.
  • RyanGatts
    Offline / Send Message
    RyanGatts polycounter lvl 8
    Oof, wish this had been collected when I was writing my PBR shader -- I have so many of these images saved for reference and calibration purposes already, it's good to know I wasn't missing much on the subject!
  • Mr Whippy
    Offline / Send Message
    Mr Whippy polycounter lvl 7
    EarthQuake wrote: »
    Not quite, metalness can be set per-pixel, not only per shader. So if you have metalic and non-metalic elements in the same texture, you would use 0 and 1 values in the metalness map. If you have partial metals, you can use a grey value in the metalness map there, but partial metals are not particularly common.

    Haha, ok.

    So a metalness map is always a blend between a hard-coded IOR of 0.04 equivalent perp reflectivity (for non-metals) and then using the diffuse/albedo for the IOR of the metal.

    We can then use a 0/1 toggle or a greyscale map to interpolate between the metalness.


    I suppose that is elegant because then you're not wasting UV space on an albedo or IOR map, or vice versa, if you run with that system.

    So really a metalness map is an optimisation approach, so you're not doubling VRAM space for metals or non-metals, by having a texture area mainly in similar shades, blacks for albedo on metals, or mostly dark greys near 0.04 for IOR on non-metals respectively.


    I suppose with good albedo, cavity and gloss maps, the variance in IOR for non-metals does start to be hard to spot given they all land in roughly the same kinda places... so metalness is a very good optimisation to use!


    That said if you can find the space somewhere a non-metal IOR channel isn't going to break the bank if you need values other than the default 0.04 for non-metals.

    Thanks again!

    Dave
  • EarthQuake
    Mr Whippy wrote: »
    Haha, ok.

    So a metalness map is always a blend between a hard-coded IOR of 0.04 equivalent perp reflectivity (for non-metals) and then using the diffuse/albedo for the IOR of the metal.

    We can then use a 0/1 toggle or a greyscale map to interpolate between the metalness.


    I suppose that is elegant because then you're not wasting UV space on an albedo or IOR map, or vice versa, if you run with that system.

    So really a metalness map is an optimisation approach, so you're not doubling VRAM space for metals or non-metals, by having a texture area mainly in similar shades, blacks for albedo on metals, or mostly dark greys near 0.04 for IOR on non-metals respectively.


    I suppose with good albedo, cavity and gloss maps, the variance in IOR for non-metals does start to be hard to spot given they all land in roughly the same kinda places... so metalness is a very good optimisation to use!


    That said if you can find the space somewhere a non-metal IOR channel isn't going to break the bank if you need values other than the default 0.04 for non-metals.

    Thanks again!

    Dave

    Yes, a big part of it is simply optimization/a more efficient way to pack the various inputs. The other part is basic consistency and setting up a more fool-proof workflow that is harder to break (eg, keep artists from setting reflectance to 0.5 for not metals).
  • Mr Whippy
    Offline / Send Message
    Mr Whippy polycounter lvl 7
    Yes limiting artists from doing wrong things is always good. That is why I like the idea of colour pickers that give you values in absolute terms, and 8bit gamma/linear values.

    In the end though I'd expect any artist to know good/bad values for different things, or if they don't then check.
    Workflow management I suppose just comes down to peer review. Even the best of us need to have our work checked by a fresh set of eyes hehe.


    Well I've learnt a lot in this thread thanks to you EarthQuake, time to go apply some of it to my PBR shaders to try get a more optimised and better looking result!

    Thanks

    Dave
  • 3py0n
    Offline / Send Message
    3py0n polycounter lvl 10
    Glad to see this thread is helping some people out!

    Sorry all who have been waiting for an update. Been busy for the past few days but should get some more data/info up on the doc in the following days :)
  • Joopson
    Offline / Send Message
    Joopson quad damage
    Whipped up a roughness/metalness chart for Marmoset, and one for Unreal too. Could be helpful for someone!

    Marmoset:
    AndrewLeslieMetalnessRougnessGraph.jpg

    Unreal:
    LQBncv1.jpg
  • almighty_gir
    Offline / Send Message
    almighty_gir ngon master
    might be useful to make sure the axes are the same in both images, and also use the same cubemap in both?

    just my two cents, still a useful visualisation.
  • Joopson
    Offline / Send Message
    Joopson quad damage
    Good points. I'll fix the axes tonight, and see about making the cubemap the same. Surprised I didn't think to do that.

    [edit:] Here you are.

    Matched the axes, and got the same HDR.

    Kie6fj2.jpg
  • EarthQuake
    Andrew, you'll have to do another when we release GGX too. :P
  • ZacD
    Offline / Send Message
    ZacD ngon master
    Bigger difference than I expected. Marmo is a lot sharper and I like the highlights better, but that's completely subjective and doesn't say much.
  • almighty_gir
    Offline / Send Message
    almighty_gir ngon master
    ZacD wrote: »
    Bigger difference than I expected. Marmo is a lot sharper and I like the highlights better, but that's completely subjective and doesn't say much.

    i'm pretty sure the science behind this is in how we process our IBL vs how they do.

    since toolbag is a standalone rendering platform, all we really need to worry about is making sure things look good while still performing well on our minimum specs. UE4 doesn't have that liberty, they need to make sure that their renderer works within the context of a full game, with instead of one character or small scene having potentially hundreds of characters within a very large scene.

    so when you import a cubemap into UE4, it pre-processes a lot of the calculations for blurring based on roughness, and stores that information in the cubes mipmap chain as well as generating a lookup texture to match up to the mip chain. this makes it less strenuous on the GPU as it now no longer needs to do as much math in realtime since all of the computations are done and the results stored in textures. the downside being that clearly there is some small loss of clarity, but looking at the images above i'd say it's a very worthwhile tradeoff.

    toolbag2 on the other hand does everything in realtime, we don't precompute anything at all. this means that you can load in any panorama from any source and have it "just work" as your IBL contribution instantly. the resulting image is about as sharp as it can be, but it's a lot more work for your processor to do in realtime.


    Also, as EQ points out: currently Toolbags reflection model is Phong based while UE4's is GGX based. We'll be releasing our own GGX based reflection model soon so a more accurate comparison can be had.
  • jerry
    Hi all,

    I have another question about metal. If you look at the metalness chart that was posted on the previous page it's clear that the more metallic the surface is the darker it gets.

    My question is what exactly is the cause of this? Why is metal consequently darker than a non-conductor surface of the same color and roughness?

    I know that the color no longer acts as an albedo color and that there is no diffusion on the metal but I'm trying to wrap my head around this.

    Thanks.
  • marks
    Offline / Send Message
    marks greentooth
    Most of what what defines metals is reflection properties. In the example chart on the previous page, the reflections are pretty dark ... that's why it looks dark. If you used an IBL that was like, bright daylight outside in a field in the middle of summer, it would look way brighter.

    What things "look" like is made up of far more factors than just the material definition.
  • jerry
    Thanks for your answer. That is basically what I figured.

    There seems to be a tendency that reflected environments (IBL's) just don't reach the brightness of non-conductors though.

    I could be making that up but it seems pretty consistent to me.
  • marks
    Offline / Send Message
    marks greentooth
    You're talking about perceptual luminance right? eg what you think it looks like visually, to your eyes?

    I actually think UE4 has done a really solid job of maintaining perceptual luminance all the way through the metalness range, I've definitely seen much more jarring mismatches in other PBR renderers.

    (e/ yes, I know that perceptual luminance does have a far more specific meaning than that)
  • jerry
    Yeah, that's what I mean.

    I just checked the image again, comparing the brightness/luminance in the 4 corners and the real difference appears to indeed be less than the perceived difference.

    It's really the bottom 3/4 rows where it becomes significant.

    Of course, as you said it depends on the IBL but I've been testing in UE4 at the same time in basically a white box level and it's still noticable.
  • EarthQuake
    This is an interesting question. I'm not sure I'll do a very good job here as I can't think of a way to explain it simply (which means I probably don't understand it that well myself), so someone smarter can probably correct me here. Anyway I will take a stab at it:

    To explain it I think its important to understand how blurring works in HDR.

    So, if you have a basic LDR image, and you have some bright white highlights in it, and you blur it, what happens? The highlight gets dimmer, more of a nasty gray color. On the other hand, if your content is HDR, that bright white highlight might have a value of 50 or 100 instead of a value of 1.0. What that means is that you can blur (or diffuse) the content and still end up with a very bright highlight.

    When creating the ambient diffuse content, those bright highlights are blured to an extreme level, but if you have very high contrast in the initial content, those highlights are still going to retain some of their brightness, while the darker areas tend to get brighter as the bright highlight spreads out and cancels out the darkeness, resulting in an overall loss of contrast. Though again, as the values are in HDR, the content still ends up pretty bright.

    This is really easy to demonstrate by varying the gloss/roughness levels, the rougher surface will have a much wider, but dimmer highlight, while the glossier surface will have a smaller, and perceptively brighter highlight. Both are reflecting the same amount of light though, the rougher object simply spreads it out over a larger area. The highlight on the glossy object clips to white because your monitor isn't HDR, you're limited to the range your monitor can actually display so you can't see anything close to the true brightness.

    glossbrightness.jpg
    So this image is simply the reflectivity (diffuse is at 0), but diffuse lighting is basically the same thing as specular lighting from a very rough surface.

    Now, you can actually replicate this in real life too. If you can manage to control your ambient light (generally by taking a photo in a perfectly dark room, with a single light source like a flash) you'll see exactly the same thing. The rougher surface will have this wider highlight, while the glossier surface will appear "darker", but the glossy surface isn't reflecting any less light.

    You can do the same experiment with objects of the same glossiness too, by using a diffuser or softbox on your light, what you do is increase the size of the light and spread the light out more, again the light doesn't become less intense(may not be entirely true if your diffuser blocks some light, which is likely, but thats not really here nor there for this topic), it simply has a wider spread.

    TL;DR: perceptive differences in brightness with different materials happen IRL too and are not a bad thing
  • jerry
    Hi EarthQuake,

    I think that was an excellent explanation and I understood it immediately. I had not looked at it like that but it makes perfect sense.

    Thanks :)
  • jerry
    I have another question about metal...

    First, the image generously provided by Sebastian Lagarde: Image

    It has an entry for "Forged Iron" but it is grouped with the non-conductors. Is this a mistake?

    Then extrapolating from there; all the other metals on that chart have luminosity values anywhere from around 180 to 255. Much brighter than most Albedo values.

    However, do a quick google search for: cast iron, wrought iron, forged iron etc. and you will find that many of those images look closer to the value of "Forged Iron" in the chart from Lagarde.

    What's going on here? It seems to me that the luminosity range for metal should be much broader than what's implied by the chart.
    Otherwise I would have to assume that these types of iron are not classified as metal (Wikipedia would disagree).

    Thanks.
  • Xoliul
    Offline / Send Message
    Xoliul polycounter lvl 16
    The metal values listed on that chart (the ones that are 180-255) are not albedo values, but reflection strength (specular) values. That's why they are brighter. Their albedo would be black anyway. Make sure you understand what a metallic map means for an albedo map if this surprises/confuses you.

    Why Forged iron is listed there is probably because there is very little exposed metal on iron that cam straight from the forge; it tends to be very dull and rough since it is covered in slag and carbon. It tends to be pretty crusty when it has just cooled off from forging temperature.

    It's really a question of "what's on the surface"; just like you shouldn't be surprised that 'painted metal' isn't actually a bare metal, 'slag- and carbon-encrusted metal' isn't either.
  • jerry
    I guess I should have been a little more careful writing that. I do understand the difference.

    seasoning%20cast%20iron-16.JPG

    So, this pan has 0 exposed (cast)iron?
    I tried to find some supporting evidence, not so easy buy I found these: Img01 Img02

    Can we then conclude that the specular color/reflection strength of metal always has a luminosity of above ~180?
  • almighty_gir
    Offline / Send Message
    almighty_gir ngon master
    the general rule is that the the reflectivity of metals is between 180-255.

    to further what Laurens is talking about:
    when texturing for PBR it's very important to take quite a strict layering approach. if you're using photoshop, i'd suggest using a new group for each specific material you're texturing, and stick to that material in that group. that way you can move groups above/below each other to put them in the final compositional order.

    for example, if you were to create a copper pipe, you would want it layered as follows listed from top layer to bottom:

    dirt
    paint
    oxidation
    copper
  • marks
    Offline / Send Message
    marks greentooth
    Well, this is all working on the assumption that you're using a single-layer material model, which I'm pretty certain *every* games PBR renderer is right now for your standard BRDFs.
  • cman2k
    Offline / Send Message
    cman2k polycounter lvl 17
    Yo @Joopson - any way you could share the assets for the spheres (hdr and all) or tell us their source? It'd be cool to be able to do my own comparisons with some other tools and proprietary tech.
  • Joopson
    Offline / Send Message
    Joopson quad damage
    cman2k, I just made a sphere and duplicated it over and over until I had enough. The HDR is Grace Cathedral, it comes in Marmoset, and is also available here:

    http://gl.ict.usc.edu/Data/HighResProbes/

    Applying materials is the hard part, because it's 100 materials, and you have to manually adjust each value. That's the only hard part, really.

    If you want, I can share the obj or fbx of the spheres, but considering they are just spheres, I don't know if it's necessary. Alternatively, you could probably create a texture to control roughness and metalness, and just planar map the group of spheres from the top. Probably would be faster.

    I'll look into it, and if it works out the way I expect it to, I'll share that.
  • EarthQuake
    Yeah that would work, planar map the whole lot and then apply a gradient to the roughness and a gradient to the metalness, one up-down, one left-right.

    Issues you will have with that:
    1. Idealy you want the corner pixels to map to the corner spheres, but what you'll get is values from 0-1%, 1-2% 2-3% mapped to each sphere instead. Probably won't be noticeable though.
    2. Make sure you make a linear space gradient and load the textures as linear space as well.
  • Harbinger
    Offline / Send Message
    Harbinger polycounter lvl 8
    jerry wrote: »
    So, this pan has 0 exposed (cast)iron?

    Cast iron cookware isn't a good reference to look at, as the surface is "seasoned". What you're actually looking at on the surface is a thin layer of fat that has been heat treated, which is what makes cast iron cookware non-stick. If you ever scrub/sand this layer off to re-season the pan, it will look like a dull-grey color.
  • Joopson
    Offline / Send Message
    Joopson quad damage
    Ok, guys, uploaded it to Dropbox. I think I got the values right. They look right, compared with my Marmoset and UE4 examples, anyway. Let me know if anything ought to be changed, and I'll change it right away.

    https://dl.dropboxusercontent.com/u/30185090/CalibrationSpheres.rar (1.20 MB)

    I included the spheres in OBJ and FBX, and included Roughness, Gloss, Specular, and Metalness stairstepped gradients. All textures are in TGA format. I've included sRGB and linear versions. In marmoset, the Linear versions are correct when sRGB is unchecked, and the sRGB versions are correct when the sRGB box is checked. Not sure how it'll work in other engines, though.

    If you'd like to download the HDR I used, you can get it here (labelled as "Grace Cathedral":
    http://gl.ict.usc.edu/Data/HighResProbes/

    I'd love to see some examples from other engines posted (even proprietary ones, if it isn't against the rules).
  • EarthQuake
    Joopson wrote: »
    In marmoset, the Linear versions are correct when sRGB is unchecked, and the sRGB versions are correct when the sRGB box is checked. Not sure how it'll work in other engines, though.

    This should be true in UE4 as well.
  • Joopson
    Offline / Send Message
    Joopson quad damage
    threw one together for Marmoset's new GGX specular, compared with its regular blinn-phong.

    I think I'll add a page to my website about this soon. It's very interesting seeing side-by-side comparisons of how these shaders behave. Unfortunately, the only other engine I can get to, other than Marmoset and UE4, is Cryengine; there are so many more out there, though.

    Gt7VoVn.jpg
  • cman2k
    Offline / Send Message
    cman2k polycounter lvl 17
    Thanks for the effort man.

    I tried to make one for Substance Designer, but it really doesn't like this HDR. It gets these really strange artifacts when I try to use it.

    To be very clear - THIS IS NOT NORMAL BEHAVIOR, it's only happening with this specific HDR. I tried both the .hdr and .exr versions.

    http://i.imgur.com/9IV8iui.jpg
  • almighty_gir
    Offline / Send Message
    almighty_gir ngon master
    thanks for the effort though cman2k!

    it's actually more helpful than you think.
  • marks
    Offline / Send Message
    marks greentooth
    That metalness 1 roughness 1 corner in marmoset GGX looks kinda sketchy...
  • NicolasW
    Offline / Send Message
    NicolasW polycounter lvl 13
    cman2k wrote: »
    Thanks for the effort man.

    I tried to make one for Substance Designer, but it really doesn't like this HDR. It gets these really strange artifacts when I try to use it.

    To be very clear - THIS IS NOT NORMAL BEHAVIOR, it's only happening with this specific HDR. I tried both the .hdr and .exr versions.

    http://i.imgur.com/9IV8iui.jpg

    SD still uses a "brute force" multi sampling technique for reflection. In case of very bright small areas, the samples becomes visible.
    You can set a higher amount of sample in the preferences / editors / View 3D / Sample table Size (at the very bottom).
  • cman2k
    Offline / Send Message
    cman2k polycounter lvl 17
    I tried this actually...does it only apply after a restart or something? I'll try again today.

    edit; even with the sample table size set to 256, and a restart, I'm still getting the artifacts. It may be worth noting that while both the physically_based and physically_based_specular_glossiness shaders get the artifacts, they look slightly different. Also I used the linear textures and disabled post-processing.
13
Sign In or Register to comment.