Home 3D Art Showcase & Critiques

UDK Physically Based Lighting!

13
ngon master
Offline / Send Message
almighty_gir ngon master
hey guys, over the last few days i've been working on this:

b2Mx01v.jpg

I'd love for people to play around with it and let me know what they think.
http://crazyferretstudios.com/public/PhysicallyBasedLighting.upk

The reason i made this was to get used to a newer way of working, with the industry moving toward a PBR setup, and very few tools out there to use.

To use this tool, there are two materials in the pack, the material itself, and an instance. please use the instance.

the maps you will need are:
Albedo - similar to the current diffuse model, except you just do colour, try not to include any lighting information at all. also, try your best to look up colour values for particular things, especially metals. http://seblagarde.files.wordpress.com/2012/04/dontnodgraphicchartforblinnmicrofacet_lowres2.png?w=630&h=630]something like this should help

Mask texture - this texture has four grayscale maps, one in each channel, which are:
- R: Roughness - this defines the roughness of the material, 0 is not rough, 1 is super rough.
- G: Metalness - this defines whether the material is metallic or not. DO NOT USE GRAY VALUES. this map should either use black for not metal surfaces, or white for metal surfaces. example - if you have a painted metal surface with chips, the paint should be black and the chips should be white in this map.
- B: Emission - This map defines any surfaces which are emissive, it multiplies over your Albedo colour.
- A: Cavity - use this sparingly (there is also a parameter to increase/decrease cavity strength), can be used to remove lighting from cavity areas. could use a light AO map as well.

Normalmap - nothing special here.

Cubemap - you can use pre-filtered maps, or capture from inside UDK. you can use DX9 if you're using pre-filtered maps. if you're using UDK captured maps, please use DX11. there is a parameter for the number of mip-map levels your texture uses. the more the better. (usually 10 is max).


There are limitations with this shader however.
- Currently the image based lighting is using a hacky workaround and isn't true IBL. hopefully i can resolve this in the near future.
- Currently UDK doesn't support area lights that will be used in the future. i have no idea if it's even possible to program a new light type into udk.
- Currently UDK doesn't allow you to bake lightmaps from custom shader setups like this.



09:45 - 22/08/2013
just pushed a new version, fixing the following issue:

cubemap reflections weren't present in dielectric materials at all. they should be vaguely present.

http://crazyferretstudios.com/public/PhysicallyBasedLighting_v1.01.upk


11:02 - 25/08/2013
just found out that the above file didn't work. this one should!
http://crazyferretstudios.com/public/PhysicallyBasedLighting_v1_02.upk

03:26 - 27/08/2013
BIG OOOOOOOL' UPDATE!

http://crazyferretstudios.com/public/PhysicallyBasedLighting_v1_03.upk

Have just put in a basic layering system! you can now have four different material layers which can be defined in the following ways!

- Albedo Colour: choose your materials base albedo. use texture on/off set to 0.
- Albedo Texture: if you want your material to have a texture, put it here. use texture on/off set to 1.
- Metalness: is now a constant (not a mask/map) please use 0 for dielectric, and 1 for metals.

You now need two different mask textures. the first is the material mask, which works in the following ways:
R: Black = layer 1, White = layer 2.
G: Black = layers 1 + 2, White = layer 3.
B: Black = layers 1 + 2 + 3, White = layer 4.

think of it as building up from a base. if you were texturing a metal pipe made of copper, with black glossy paint, and a little surface rust. this would only require 3 layers. so you would start off with the copper, and mask that off with black in the red channel. then add surface rust in the second material, and mask that with white in the red channel. then add black gloss paint to the third material, and mask that with white in the green channel. you will need to do the same thing with normalmaps, although they share the same layer mask texture.

the second mask is roughness. you will need one roughness mask for each material.
R = material 1,
G = material 2,
B = material 3,
A = material 4.
IMPORTANT NOTE - due to feedback, roughness maps are now inverted, treat them the way you do with current gloss maps - black = rough, white = glossy.

there is a (very very basic and bad) set of example textures in the package to demonstrate. i only spent a couple of minutes making them.

this system should hoooopefully allow people to use tiled textures on the various channels and come up with some cool effects. it also allows you to choose whether or not you want to use a basic constant coloured material, or texture per material, or even mix between them.

current functionality removed:
emission, cavity map. these will be added in again soon when i can figure out an efficient way of doing it.

i'll make a good example asset and some maps over the next couple of days to demonstrate better, unless someone beats me to it!

cheers guys, have fun!

20:00 - 27/08/2013
LATEST RELEASE
http://crazyferretstudios.com/public/PhysicallyBasedLighting_v1_04.upk



UPDATE TIME!!!
00:08 - 27/09/2013

http://crazyferretstudios.com/public/PhysicallyBasedLighting_v1_05.zip

I STRONGLY RECOMMEND DELETING ALL PREVIOUS VERSIONS ENTIRELY.
this will stop any cross over between the shader functions, and hopefully minimize any errors. there are a lot of changes under the hood in this update, so this is the best course!

I've got good and bad news! i've managed to get IBL working the way the UE4 paper says they do, but it's WAY too intense for UDK. my rig is a beast, and it chugs so bad i had to abandon it. which means i need to figure out a better/cheaper way to do it... so here's hoping!

until i've figured that out, the IBL is in the emissive slot, along with your emissive map.

new features/functionality:
four materials to blend between. each material has it's own normalmap, and albedo slot. they also have a metalness and roughness parameter. simply slot in your albedo, tell it whether that material is metal (1) or not (0), and define how rough it is with the slider. if you want additional functionality, you could put metalness in the alpha channel of the albedo, which would allow you to have more detailed materials, but you would need to swap the alpha and the parameter around in the shader. you can also adjust how much each layer tiles with a parameter, each layer can tile separately from one another.

there is a texture slot in "Masks". this is your layer mask:
R - black = base layer, white = second layer.
G - black = combined first and second layer, white = third layer.
B - black = combined first second and third layers, white = fourth layer.

there are two "Global" map inputs:
Global Normals - here is where you put your models unique normals.
Roughness/Cavity/Emission - R = Roughness channel, again white is rough and black is glossy. G = Cavity, this multiplies lighting down globally, use this for very fine details you want to convey, things like cloth seams or similar. B = emission, multiplies over your albedo to give a coloured glow, there's an emissive parameter to strengthen this effect as desired.

there is a "Cube" input. this needs to be the T-shaped cube texture. you can generate one inside UDK if you need to. currently UDK doesn't support DDS textures, so no custom mip-maps just yet =[

enjoy!

Replies

  • Stromberg90
    Offline / Send Message
    Stromberg90 polycounter lvl 9
    Nice job, will give it a try and post if I get anything worth showing :)
  • gsokol
    Offline / Send Message
    gsokol Polycount Sponsor
    I love you for setting this up...this is awesome.

    I'll definitely take a crack at it when I get a chance.
  • almighty_gir
    Offline / Send Message
    almighty_gir ngon master
    cheers guys, can't wait to see what you make. even if it's just simple stuff! just want to see it in action haha.

    FYI, the cube mips is set to 5 in the material instance, change that to 10 for a smoother transition between cubemap blurs.

    edit: am aware of an issue where having lights too close to the object with the shader causes a strange artifact. working on a fix now.
  • Stromberg90
    Offline / Send Message
    Stromberg90 polycounter lvl 9
    Could this be that issue?
    I don't really have any close lights, but a dominant directional one.
    3cT7sEN.jpg
  • almighty_gir
    Offline / Send Message
    almighty_gir ngon master
    Hey Guys,

    please re-download the file, as i've just put in a fix that will stop you getting a horrible halo effect at angles away from a light source.

    @Stromberg, i'm not sure what that is, other than it looks like some horrific compression... would you mind posting your source maps?
  • Stromberg90
    Offline / Send Message
    Stromberg90 polycounter lvl 9
    Seems to be my normal map compression, cause when I used the one you provided I did not get any such artifacts.

    Here is the normal map.
    mcFgITl.png
  • almighty_gir
    Offline / Send Message
    almighty_gir ngon master
    try reimporting the normalmap and putting it in the UI lod group. that might get rid of the issue for you.

    and yes, UDK has shitty normal compression.
  • Stromberg90
    Offline / Send Message
    Stromberg90 polycounter lvl 9
    Works a bit better, but it's still there.
    When removing the dominant directional light it gets a lot better.
  • [HP]
    Offline / Send Message
    [HP] polycounter lvl 13
    Great to see someone sink in some time to try and do this with the tech we already have. Is your technique similar to this? http://www.polycount.com/forum/showpost.php?p=1787202&postcount=10

    I'll give it a go tonight if I have the time, thanks man.
  • almighty_gir
    Offline / Send Message
    almighty_gir ngon master
    fairly similar. the thought process is the same, just the math is a bit different for some of the terms, that's all.
  • Ace-Angel
    Offline / Send Message
    Ace-Angel polycounter lvl 7
    Stromberg, that is a Normal Map issue, either check UncompressedNormalMap for your map type or make sure you baked it out with proper anti-aliasing setting from your package. You might not see the issue on the map, but playing around with your levels in PS will show you normal map having gradient issues.

    Also, make sure if you're using a program like dDo2, you use high end texture, and not JPG, as the acne from compression will transfer to the normal map.
  • almighty_gir
    Offline / Send Message
    almighty_gir ngon master
    new issue:
    just realised that metallic specular isn't tinted by underlying colour. will fix asap.
  • Stromberg90
    Offline / Send Message
    Stromberg90 polycounter lvl 9
    Ace-Angel: Yeah I changed it to UncompressedNormalMap but for some reason it looks worse.
    I bake with max anti-aliasing(4x) in xNormal and always use .tga files, but I think it's mostly my own fault, it's not too bad when removing the sunlight in udk.

    almighty_gir: that's good to hear :)
  • Esselle
    Offline / Send Message
    Esselle polycounter lvl 5
    I didn't understand how to make a colored metallic surface... i mean to make a metallic (full metalness, not painted) looking not black
    Anyway awesome work here!
  • joeriv
    Offline / Send Message
    joeriv polycounter lvl 7
    Can't get it to open, the moment I open the package and the bar with "loading package physicallyBasedlighting" appears UDK just crashes.
    Happens in both dx9 & dx11

    And tried in both the feb&july2013 release (july being a fresh install on my c-drive).

    edit: downloaded it again, and now it suddenly works :)
  • almighty_gir
    Offline / Send Message
    almighty_gir ngon master
    Hi guys,

    Just uploaded a new version, please redownload. this version has tinted specular for metals.

    from now on i'll upload a new file with a unique version number.

    @Stromberg, try setting the LOD group to UI as well, that forces it to import with the least compression.

    @Esselle, in your mask texture, select the green channel, anything you want metallic paint pure white (255,255,255) with a 100% hard brush. anything you want non metallic, make black (0,0,0).

    @joeriv, i created this with July 2013 version of UDK. is there any specific message it has other than "loading package PhysicallyBasedLighting"?
  • Esselle
    Offline / Send Message
    Esselle polycounter lvl 5
    @Esselle, in your mask texture, select the green channel, anything you want metallic paint pure white (255,255,255) with a 100% hard brush. anything you want non metallic, make black (0,0,0).

    Yeah, this... i made it white for metallic, but the appearance of the surface, the diffuse in other models, is completely black
  • almighty_gir
    Offline / Send Message
    almighty_gir ngon master
    okay, could you show me your albedo and mask textures?
  • Esselle
    Offline / Send Message
    Esselle polycounter lvl 5
  • almighty_gir
    Offline / Send Message
    almighty_gir ngon master
    XMgHEW8.jpg

    seems to be working okay for me... just to be sure, your mask texture looks like this?
    p9iDTS0.png
  • Esselle
    Offline / Send Message
    Esselle polycounter lvl 5
    Yes, exactly like that.. anyway it wonderfully works now! I just changed directly textures in the instance made by you, instead of making another one, and it works lol
    thank you and sorry for the time wasted
  • almighty_gir
    Offline / Send Message
    almighty_gir ngon master
    no problem, i'm glad you like it.

    be sure to download the newest version again if you haven't already.
  • Kazperstan
    Offline / Send Message
    Kazperstan greentooth
    ooo yay! shall be giving this a play in the morning :D nice work!
  • Ace-Angel
    Offline / Send Message
    Ace-Angel polycounter lvl 7
    Stromberg, this has been mentioned on the XNormal thread a few times, but I'm not sure if a solution was EVER found, but according to many, XNormal indeed does bake out with banding issues.
  • Stromberg90
    Offline / Send Message
    Stromberg90 polycounter lvl 9
    if thats the case, then hopefully it will be fixed for xN4, since I have noticed the issue in toolbag sometimes to :)
  • almighty_gir
    Offline / Send Message
    almighty_gir ngon master
    try to bake out from xNormal as a 16bit texture (.png), then in photoshop convert it to 8bit. this should help limit the banding issues.
  • Stromberg90
    Offline / Send Message
    Stromberg90 polycounter lvl 9
    Thanks, will try that, sorry to hijack your thread like this xD
  • Dave Jr
    Offline / Send Message
    Dave Jr polycounter lvl 7
    Will be giving this a try! :D
  • jfeez
    Offline / Send Message
    jfeez polycounter lvl 8
    awesome!!! will be giving this a try later today =)
  • almighty_gir
    Offline / Send Message
    almighty_gir ngon master
    just pushed a new version, fixing the following issue:

    cubemap reflections weren't present in dielectric materials at all. they should be vaguely present.

    http://crazyferretstudios.com/public/PhysicallyBasedLighting_v1.01.upk

    thinking of adding in a switch which will allow you to simulate HDR in non HDR cubemaps, if people think that would be useful.
  • Quickel
    Offline / Send Message
    Quickel polycounter lvl 12
    Great to see this. Is there a place we can get the cubemap you're using? I'm not too familiar with UDK's cubemap process and your material errors out without it.
  • Teessider
    Offline / Send Message
    Teessider polycounter lvl 7
    Lee this is awesome :D. I will definitely have a play about with this!
  • chriszuko
    Offline / Send Message
    chriszuko polycounter lvl 10
    The fact that it blurs the reflection is just blowing my mind. Absolutely stunning!
  • Esselle
    Offline / Send Message
    Esselle polycounter lvl 5
    I'm not sure about how to make in this lighting model those famous scratches and grungy areas we put in specular map...

    Let's make an example:
    I have a smooth titanium plate painted in red and it is scratched.
    Albedo: painted surface - red albedo; scratches - titanium albedo.
    Roughness: painted surface - black/gray (not rough); scratches - white (full roughness)
    Metalness: is a painted metal metallic or not? And scratches? I guess both are metallic...
    let me now if i am right :)
  • r3spawn
    Could someone explain what exactly physically based lighting is like I'm a complete idiot? I'm not entirely sure what it is.
  • Vailias
    Offline / Send Message
    Vailias polycounter lvl 16
    Essele. Metallic should basically mean: "Are the reflections colored like the underlying material?"
    Painted stuff, unless its metallic paint = non metallic. Scratches = Metallic as its exposed metal.
  • Stinkhorse
    Offline / Send Message
    Stinkhorse polycounter lvl 10
    I'm right there with you r3spawn! Super excited to learn though!
  • RogelioD
    Offline / Send Message
    RogelioD Polycount Sponsor
    r3spawn wrote: »
    Could someone explain what exactly physically based lighting is like I'm a complete idiot? I'm not entirely sure what it is.

    read through this: http://www.polycount.com/forum/showthread.php?t=124683
  • MooseCommander
    Offline / Send Message
    MooseCommander Polycount Sponsor
    For DX9, how would we use prefiltered cubemaps?

    I'm just curious, because the current system in the shader only works with mip map generation, which to my understand you don't have control of in UDK. Even with a prefiltered cubemap, there isn't anything in the shader that would tell it to be blend properly.
  • almighty_gir
    Offline / Send Message
    almighty_gir ngon master
    yeah, that's going to be a bit of an obstacle to overcome. but i'll see what can be done about it.

    as for prefiltering cubemaps, you can do it with ATI's cubemap tools but they output to DDS, and i'm not sure you can easily convert to another format for UDK to read them.

    that said, why work in dx9? the newest cryengine for example doesn't even support dx9. i doubt many new engines will.
  • Esselle
    Offline / Send Message
    Esselle polycounter lvl 5
    For dx9 you could also capture the scene with a cubemap actor, then convert your rendertargetcube texture in a static texture, and export the faces to make a cubemap in photoshop (you can use the static cubemap already created from those textures by UDK only as a guide, because it doesn't let you export it in a .tga, .png or whatelse)
  • MooseCommander
    Offline / Send Message
    MooseCommander Polycount Sponsor
    Just a few more tidbits I noticed.

    First off, you're not using any specular maps. It's an interesting choice to pull from the diffuse. Out of curiosity, is there any reason behind that, other than to try and save on some memory? Typically PBR relies on a black (or almost black) diffuse for metal, with the specular defining the color value.

    I've also noticed that how the material deals with roughness seems to be inverted.

    dontnodgraphicchartforblinnmicrofacet_lowres2.png?w=630&h=630]something%20like%20this%20should%20help

    Black should typically provide you with the blurred reflection, with white giving you a sharp reflection. I'm having the opposite occur. It's easy enough to change, just wanted to give you a heads up.
  • Vailias
    Offline / Send Message
    Vailias polycounter lvl 16
    Moose: Just a thought, but if the diffuse is totally black on a full spec material, then why use an extra color map to shift the reflected hues? Just use the underlying diffuse.
    Aside from having non-photo real effects, things aren't really going to reflect the environment in a different color than they appear to be. (thin film and iridescent materials excluded, however just a metallic slider won't be physically based with those anyhow...)
    On the roughness. Perhaps labeling it "smoothness" would help?
  • MooseCommander
    Offline / Send Message
    MooseCommander Polycount Sponsor
    Vailias wrote: »
    Moose: Just a thought, but if the diffuse is totally black on a full spec material, then why use an extra color map to shift the reflected hues? Just use the underlying diffuse.
    Aside from having non-photo real effects, things aren't really going to reflect the environment in a different color than they appear to be. (thin film and iridescent materials excluded, however just a metallic slider won't be physically based with those anyhow...)
    On the roughness. Perhaps labeling it "smoothness" would help?

    Fair point on the diffuse. That makes sense for a material that is completely metal, but if you have a texture with multiple material definitions, you'll need to have the differentiation, or some form of mask that you would then lerp in a color value from a constant 3. It is an interesting option, but I think you can forgo the mask texture, replace that with a spec with roughness in alpha, and you have the same amount of texture calls. To be fair, this does not include a cavity or emissive option, but that can easily be adjusted for as well. Worse case scenario, you're adding one more map but getting much better control.

    As for roughness, I don't quite follow? Changing the name doesn't change how you interact with it. The reason being, I've worked on two engines that use PBL and both went from black (blurred) to white (sharp), not white (blurred) to black (sharp). The issue can't simply be fixed by inverting your maps or using OneMinuns, either, because the highlight will still be incorrect. It will change the area that is blurred, but the highlight will still be sharp and strong on the bumpy portion while large and weak on the smooth potion, if that makes sense.
  • almighty_gir
    Offline / Send Message
    almighty_gir ngon master
    what's happening inside the shader, is that any parts of the albedo which are masked as metal, are lerped to black. the shader then takes the IOR from the original albedo colour.

    so say you wanted gold, you put your gold colour in the albedo. then mask it as metal. the shader takes the gold colour and puts it into the specular, but turns the final albedo black for that masked area.
  • MooseCommander
    Offline / Send Message
    MooseCommander Polycount Sponsor
    what's happening inside the shader, is that any parts of the albedo which are masked as metal, are lerped to black. the shader then takes the IOR from the original albedo colour.

    so say you wanted gold, you put your gold colour in the albedo. then mask it as metal. the shader takes the gold colour and puts it into the specular, but turns the final albedo black for that masked area.

    Ah, okay. That's pretty awesome actually. That's a pretty nifty workflow.

    Any thoughts on the roughness being inverted (where black is getting the strong, smaller highlight with white getting a larger, broad highlight)?

    I've tried to look at the equation and adjust it, but it isn't giving a correct result.
  • almighty_gir
    Offline / Send Message
    almighty_gir ngon master
    sure, it's easy enough to do man. go into the material editor, and find the mask texture node here:
    http://i.imgur.com/KFRAddl.png

    add a "one-minus" node, and plug the R channel into it like this:
    http://i.imgur.com/HWUNFUU.png

    then plug that node into this constant clamp here:
    http://i.imgur.com/SVayQov.png

    and this multiply node here:
    http://i.imgur.com/ZzXdEd2.png
  • Esselle
    Offline / Send Message
    Esselle polycounter lvl 5
    Yet another question... sorry but i really want to fully understand this, since it will be the next generation shader.

    So, according to metalness map, that can only be 0 or 1 (black or white), a mterial can only be metallic (black diffuse and cubemap) or dielectric (colored diffuse and no cubemap). But i didn't understand this... let's talk about a sign on can, a gloss paint, or a colored gloss plastic. They should be dielettric, but even if they have colored diffuse, they also have a cubemap reflection. Maybe the sign on the can is some sort of translucent paint that let light penetrate and let it interact with the metal, but a gloss not translucent paint or a gloss colored plastic, what kind of material is it?
    In the UE4, for example, i guess it can be done with layered materials, a layer of gloss paint on a metallic material. Am i wrong?
    In this shader i know it is nearly impossible, or anyway very difficult to create, but I also have seen that metallic characteristic in UE4 can be setted to any value between 0 - 1. So, shouldn't we have to use gray metallness map? I tried to set a gray metallicness and it works with no artifacts or some other errors, so i don't understand why the metallness mask has to be 0 or 1, no other values.
  • almighty_gir
    Offline / Send Message
    almighty_gir ngon master
    hey Esselle,

    that issue should have been fixed in version 1.01, however there seems to be a bug with udk files, where if you rename the package to something else outside udk, udk won't load it properly. please use this file, it should work now:

    http://crazyferretstudios.com/public/PhysicallyBasedLighting_v1_02.upk


    to answer your other questions:
    in UE4, they would have two materials, one for the paint, and one for the metal underneath, you would then mask on/off those materials to get your effect. my shader is a simplified version of that.

    in my shader, you can also use gray for metalness if you want to. but that doesn't mean you should (and the only reason they do in the UE4 tech-paper, is to show the difference gradually). there are four semi-metals which exist in the real world, all of which have the reflectance qualities of actual metals. thse semi-metals are:
    antimony
    arsenic
    grey-tin
    graphite

    so, because there is no material in the real world that has semi-metallic lighting properties, we should only use 0 or 1 for that setting.
  • MooseCommander
    Offline / Send Message
    MooseCommander Polycount Sponsor
    I just wanted to follow up real quickly!

    The OneMinus trick does not work. I pointed out earlier that the issue behind is more systemic of how the system is interpreting the roughness map.

    Right now, a value of zero will give you a sharp, clear highlight and will also use the highest quality cubemap (the non-mipped version).

    This is, according to most PB shaders, incorrect. White, or a value of one, should give you a strong, small highlight and a clear cubemap. Black (zero) should give us a low mip cubemap and a soft specular highlight. Plugging in a OneMinus doesn't fix the issue because it just inverts the map, but not the equation. You could potentially put a OneMinus on the end of the Specular D part of the equation, but it will blow the material out (although maybe a constant clamp will fix that, I'll experiment with that).

    The issue isn't in your Specular D equation, but I think it is coming in the Custom node right before it where you input Roughness and NdotH. I looked at the HLSL and I can't quite figure out what it is doing or where it came from (it's not in the UE4 paper most of your code is based off), but either way, the code is producing the opposite result of what you want.

    Obviously, Roughness squared on its own also does not produce a good result, but the values are at least not inverted.
13
Sign In or Register to comment.