Home Technical Talk

TGA Physically Based Lighting CGFX Shader for Maya Viewport

13
polycounter lvl 15
Offline / Send Message
kodde polycounter lvl 15
Hey guys,

I wanted to share a new shader with you guys. First off, a big thank you to my colleague Niklas Hansson whom I created this shader with. He's the guy with the theoretical know-how of the inner workings of this shading method, he helped out with guiding me through the shader creation in Mental Mill as well as some MSL(HLSL like) coding for custom shader components in Mental Mill.

So I give you, TGA_Physically_Based_Lighting_Shader. A realtime CGFX shader for the Maya viewport.

This shader uses a whole new way of handling lighting and in particular the specular and reflection contribution. Instead of the traditional specular, gloss and reflectivity you now use a substance and roughness texture to define your materials in a more realistic manner. There's also familiar textures such as Albedo(Diffuse), Tangent Space Normal map, Cube Map and Ambient Occlusion. This way of shading is already adopted by several triple A studios in the industry. For instance Treyarc's COD Black Ops.

Here's the highlight features of the shader.
  • A real life material based fresnel term that alters specularity and reflections.
  • A substance texture to mimic how materials reflect and refract light in real life.
  • A roughness texture to define a materials surface structure(smooth/rough).
  • Image based lighting via a cube map for reflections and ambient lighting.
  • Roughness controlled pre-blurred mip levels of the cube map for reflections.
  • Blended Normals to give a subtle skin effect in conjunction with normal maps.
  • Emissive Texture to fake emissive surfaces.
  • Fully linear shading pipeline.
  • A bundled cheat sheet image with color swatches for several substance values.
  • Shadow Map(pre-baked) support fully integrated with the shader (This feature is experimental and only works with 1 direct light source).
  • Added transparency support. Use the albedo texture alpha channel.

You can Download the shader from my website.
ATI users should be aware that CGFX shaders in general do not seem to work well in Maya with ATI cards. I have not been able to verify if this one works or not, I'm assuming it does not. :(

I created some examples to show the shaders capabilities. I started of with a gold bar, and continued making variations of it.

TGA_PBL_Promo_Bars_big.jpg

TGA_PBL_Promo_Rusty.jpg

Feel free to ask questions and discuss the shader in this thread.

Replies

  • kodde
    Offline / Send Message
    kodde polycounter lvl 15
    So here's a quick description of how to work with the new textures of this shading method. You can see examples of these textures used for the "Rusty Paint" in the original post.


    [size=+1]Albedo[/size]
    This is just like a diffuse texture you are familiar with. Remember only to paint the materials color, not light variations. In other words, generally more flat then traditional hand painted diffuse textures. You also generally want to increase the Albedo texture's saturation a bit above how you would generally have your saturation levels in a diffuse texture. I'd advice you not to blatantly just multiply your Ambient Occlusion in the Albedo, this information is meant to be used the Ambient Occlusion texture.

    [size=+1]Roughness[/size]
    This texture is used to define material surfaces in terms of roughness. For a perfectly smooth surface use white color, for a really really rough surface use black color. The effect of this map is how wide/narrow specular highlights will be. It is also used to determine what mip level to use from your environment cube map for reflections. It's highly advised to use pre-blurred cube map mip levels. Leave mip level 0 crisp and blur a bit for each mip level you traverse down. Have a look at the Diffusely Convolved Cube Map page on the PC Wiki if you are unfamiliar with this. Here's a freebie Cube Map with pre-blurred mips if you can't be bothered. Source images for the cube map are from humus.name.

    [size=+1]Substance[/size]
    This texture is used to define what type of material you are trying to mimic. What the texture actually mimics is how light is reflect/refracted on the surface. A brighter value will make the material specular and reflective in more angles. A darker value will make the material on specular and reflective in glancing angles. For instance, most metals have a high substance value and therefor reflect in almost all angles. Since this feature is based on real life IOR(Index Of Refraction) values I'd advice you to use the bundled "Cheat Sheet" image which has several color swatches you can sample colors from to use for your substance textures. Of course you can diverge from these presets, but they are a good start. Remember to sample from the Gamma Space column as this texture is treated as a gamma space texture by the shader. You generally want to leave this texture quite flat.


    [size=+1]Ambient Occlusion(AO)[/size]
    This texture works just as it does in traditional usages. But besides occluding ambient light it also occludes reflections and also specular highlights. Occluding the specularity might not be that physically correct, but we liked the effect of this as it made specular highlights pop more. You could say that the AO texture plays a more important role in this shader as it controls more parts of the shading than in traditional usages.
  • haiddasalami
    Offline / Send Message
    haiddasalami polycounter lvl 10
    Crazy stuff Kodde. Definitely gonna play around with this. Damn just had my ATI card removed yesterday (went Nvidia). Hopefully words out for ATI people out there.
  • onionhead_o
    Offline / Send Message
    onionhead_o polycounter lvl 12
    this is really awesome, very interesting approach for materials. definitely try it out. thanks kodde
  • wailingmonkey
    bad-ass, kodde!

    thank you for sharing yet another awesome shader! :)
  • pior
    Offline / Send Message
    pior high dynamic range
    Super interesting stuff!! One step closer to fast and efficient asset creation.
    Do you have a test scene with all these materials in it ?

    Looking really good!
  • kodde
    Offline / Send Message
    kodde polycounter lvl 15
    Thanks guys :)
    pior wrote: »
    Super interesting stuff!! One step closer to fast and efficient asset creation.
    Do you have a test scene with all these materials in it ?

    Looking really good!

    Pior> Yes indeed I do. The scene with the bars used for the images in the original post. Around 1GB of a Maya project folder full of raw uncompressed textures, PSDs, etc. :)
  • pior
    Offline / Send Message
    pior high dynamic range
    Very cool! Will try it as soon as possible :) Fascinating stuff!
  • kodde
    Offline / Send Message
    kodde polycounter lvl 15
    Pior> Here's a screen all for you.
    TGA_PBL_Promo_maya_screen.jpg
  • equil
    cool initiative! i looked over it quickly (haven't tried it out yet though. sorry!) and i guess substance is f0 (aka specular strength at normal angle aka effective refractive index)? in that case i wonder why you didn't just call it specular or something. and ao seems to only be used as a spec mask (i think), which is kind of a weird use of the term. guess you've taken some hints from hoffman.

    also, i think gloss/rough only goes up to 256? raise it further! when you're using cubemaps in conjunction with gloss, not being able to get a highlight as sharp as the reflection can be a real pain! i mean it's not like you need to worry about too sharp highlights with phong specular.
  • kodde
    Offline / Send Message
    kodde polycounter lvl 15
    Equil> First thing worth mentioning. I had help with the theory parts of the newer things in this shader. I did not read the papers myself, I got it explain second hand. Anyway.

    I was under the impression it was called Roughness by most people adopting this type of shading and therefor I wanted to stick to the same name. Also, roughness seems to make sense to me. In my opinion an artist can easily relate to that. A smooth surface will reflect many rays straight back to the viewer resulting in a sharp reflection. A rough surface will scatter the rays to a higher degree and therefor not as many rays will go straight back at the eye and since they got bent along the way this will result in a blurrier reflection that is not as intense.

    As I pointed out further up, the AO masks ambient light, reflections and specularity. The specularity part not necessarily as physically correct, but we liked the effect. It gave specular highlights more contrast and got details to "pop" more.

    Regarding roughness to 256 you might be right. This is still all new to me and I've understood that other implementations have used a higher value like you mention. I'm going to give it a go with altering this to a higher value and see how it turns out. Wouldn't this however stretch the accuracy overall and therefor making it hard to define differences in the lower end? Not that I think that would be a major problem though.
  • Bal
    Offline / Send Message
    Bal polycounter lvl 12
    Great work Kodde.
    We've been moving towards something like this at work as well, and the transition from the old method has been a bit strange, will be interseting to compare with your shader.
  • cman2k
    Offline / Send Message
    cman2k polycounter lvl 12
    Kodde, it seems to me that you and I have been learning HLSL, materials and shaders at the same pace. It's like you are reading my freaking mind, man! I have been planning to do something exactly like this for 3dsmax...and I have already done something very similar for the secret project I am working on at my job.

    Nice work as always dude!
  • equil
    aha, sorry about jumping to conclusions about the ao! I also prefer the term roughness over gloss, albedo over diffuse etc.

    generally speaking the loss of precision with higher max roughness values shouldn't be a problem, but you obviously don't want to go too high. if you want more accuracy in one end, you can cube or square roughness, but with specular normalization, the overall low intensity in that range means that people don't easily discern exact roughness anyway. Otherwise more people would probably use beckmann instead of blinn-phong.
  • kodde
    Offline / Send Message
    kodde polycounter lvl 15
    Bal> Thanks. Cool. Seems like several people are moving towards this type of shading. Let me know what you think.

    cman2k> Hehe... Maybe I have been reading your mind. Nice to hear that several are moving towards this, gives me reassurance. Thanks.

    equil> Hmm.. not familiar with Beckmann. I'll try to read up on it. Should be fairly easy to just jack up the levels to start with, and if it does become a problem I might look at some way of adjusting the levels as you mention. You do make a valid point about the intensity in the lower end.
  • TrevorJ
    Offline / Send Message
    TrevorJ polycounter lvl 9
    Hey Kodde, awesome job on this, im messing around with it. It is a little awkward to wrap my head around at first but its starting to look better. I don't see any download link you talked about with the gold bars etc, in the first post? am i blind?

    Also with the small bit of tinkering iv done, there seems to be an update problem when disconnecting maps, light. Particularly when i disconected the environment cube map, i still saw the reflections.

    another quick question, i'm getting a weird fresnel effect im very new to this, what is causing this?
    shader_tinkering.jpg
    Image does NOT reflect quality of shader, i just don't know what i'm doing
  • kodde
    Offline / Send Message
    kodde polycounter lvl 15
    Hey Trevor. Nice to see someone trying it out. Now that you mention it, I think I had some update issues as well at some time, I thought it was Maya related rather than my particular shader... hmm. When you disconnect the textures you say?

    Which is the weird fresnel effect you are referring to? Also, in your screenshot you are missing some textures. Did you just disconnect them or did you not try to use them yet? I recommend you use all the textures available for the shader to function properly.

    Regarding the gold bar you mention, it was never made available in this thread. Not yet anyways. ^^
  • TrevorJ
    Offline / Send Message
    TrevorJ polycounter lvl 9
    yeah i wasn't using the AO_texture yet, this screenshot was taken right after a right clicked on the environment_cube texture slot and hit "break connections" and nothing changed. Like you said it could be some native maya bug

    The fresnel effect area i'm talking about is the pink stuff on the handle, near the center and at the tip. I think it's the environment texture still coming through. Plus these are all just slightly tweaked textures made for a specular/diffuse/normal/gloss type shader, some better authoring will be needed for proper testing.

    EDIT, yeah the pink glancing angle was the cube map, and yeah theres some update bug, either maya or other. Once i reloaded the scene it was gone.

    Any recommendations on really specular reliant materials? aka nickel plating/polished aluminum/ worn finished metal.
  • TrevorJ
    Offline / Send Message
    TrevorJ polycounter lvl 9
    here's a better shot of what I was talking about, it's definetly the cubemap, it shows up when i plug it in. The normals on my model are totally averaged(soft) for normal baking purposes, that seems to be having some kind of effect on the cube map reflections. Hopefully that helps narrow things down a little, i really have no idea how shaders are built.

    cubemap_normals.jpg
  • kodde
    Offline / Send Message
    kodde polycounter lvl 15
    Did you try to use the bundled Cheat Sheet to sample gamma space substance values? There's a real IOR based sample for Nickel in particular there. I hardly ever add details in the substance map, but in my "Iron" example in the original post I actually added some variations in the substance map as I wanted imitate it being tarnished.
  • Keg
    Offline / Send Message
    Keg polycounter lvl 12
    Interesting approach, I haven't looked at the shader itself yet. It looks similar to something I've been working on for a project.

    Are you able to handle things like glass nicely?
  • kodde
    Offline / Send Message
    kodde polycounter lvl 15
    TrevorJ> I'm trying to figure out the issue at hand on your example images. You are using a tangent space normal map right? And you haven't altered the vertex normals since after baking your normal map?

    Keg> You mean like transparent materials? No I haven't looked into it. Nor does it handle light scattering around in wider areas than 1 pixel, i.e. SSS. I'd love to be able to implement that somehow. I've considered adding support for blended normals.
  • TrevorJ
    Offline / Send Message
    TrevorJ polycounter lvl 9
    Yup, tangent space, no I didn't change any of the normals since baking. Yeah i was using the color sample of the nickel from the picture you posted, wasn't sure if the substance texture should be have much detail, like you said this texture will usually be quite flat.
  • kodde
    Offline / Send Message
    kodde polycounter lvl 15
    Hmhmh... Not that I've tried with several normal mapped objects, but the ones I did looked alright.

    Does your model look fine with other real-time shading solutions in the Maya viewport? Say a regular blinn shader with the normal map?
  • Akula
    Akula sucks up and bows his head to Master's magnificence. Incredible work Kodde. Will test this as soon as time permits. Screenies look fantastic! /Olof-SG09
  • chrilley
    Offline / Send Message
    chrilley polycounter lvl 10
    Looks really sweet, I will definitely play with this later.
  • r_fletch_r
    Offline / Send Message
    r_fletch_r polycounter lvl 9
    awesome stuff kodde. will this work in max? (would test it but dont have access at the moment)
  • kodde
    Offline / Send Message
    kodde polycounter lvl 15
    thanks guys :)

    r_fletch_r> I'm afraid not. It should be possible to export to 3DSMax from Mental Mill. But there has been several hand edited additions to the .cgfx file after exporting. Mainly to get the mip-level functionality working since Mental Mill doesn't support texCUBElod command. Also to get a passable UI in Maya without lots of strange names and messy layout. I'm not sure how edit and tweak this to get it working in 3DSMax as I'm a Maya user.

    I think what would differ are certain UI commands and handling the fact that maya and max has differing world axises setup.

    You could just try loading it as it is. At best it might load but your cube maps would probably be rotated. That would probably be a simple swizzle of the components which would probably be fairly easy to hand-edit.
  • kodde
    Offline / Send Message
    kodde polycounter lvl 15
    New version available, 0.2.2.
    The newer version is available on my website.

    From 0.2.1 to 0.2.2:
    -Fixed a bug with how reflections were handled in conjunction with a normal map.

    Example of the bugfix:
    0.2.2_bugfix_example.jpg
  • r_fletch_r
    Offline / Send Message
    r_fletch_r polycounter lvl 9
    kodde wrote: »
    thanks guys :)

    r_fletch_r> I'm afraid not. It should be possible to export to 3DSMax from Mental Mill. But there has been several hand edited additions to the .cgfx file after exporting. Mainly to get the mip-level functionality working since Mental Mill doesn't support texCUBElod command. Also to get a passable UI in Maya without lots of strange names and messy layout. I'm not sure how edit and tweak this to get it working in 3DSMax as I'm a Maya user.

    I think what would differ are certain UI commands and handling the fact that maya and max has differing world axises setup.

    You could just try loading it as it is. At best it might load but your cube maps would probably be rotated. That would probably be a simple swizzle of the components which would probably be fairly easy to hand-edit.


    When I get a chance I might see if I can knock up the same in shader fx. I had started something similar a while back. (anyone looking for it shouldnt hold their breath)

    will have to look at how you did the IOR stuff.
  • kodde
    Offline / Send Message
    kodde polycounter lvl 15
    Knock yourself out ;)
  • kodde
    Offline / Send Message
    kodde polycounter lvl 15
    So as you probably know, Maya does not have support for real time shadows in conjunction with CGFX shaders. A major issue in my opinion since shadows contribute lots to the visual end results.

    Therefor I decide to take the leap and try to implement Shadow Map support for this shader and my coming projects. So far I just created a proof of concept test case for myself to see this in action. It seems to work just fine. Major issue will be to handle the creation and updating process of these Shadow Maps. Light directions and intensities need to sync, etc. Also, my ambition is to streamline this as much as possible to make it easy for the user to create and update the Shadow Maps. The shadow maps will be based on a secondary UV-set to keep the option of having overlapping/stacked UVs.

    Here's a quick video of where I'm at for the moment.

    [ame=" of concept: CGFX w Shadow Map support in Maya - YouTube[/ame]
  • Stradigos
    Offline / Send Message
    Stradigos polycounter lvl 9
    I really like your shaders! I think we're going to start using your KoddeShader one here at work. I like the TGA shader, but we need transparency. We just medical animations, nothing too crazy. In combination with an AO pass, it looks just as good a mental ray. Saves us some nice render times and is great for development. :)
  • kodde
    Offline / Send Message
    kodde polycounter lvl 15
    Stradigos> Sounds cool. Mind sharing any of your renders? Would be nice to see :) You can PM me if you don't want to post here.
  • kodde
    Offline / Send Message
    kodde polycounter lvl 15
    I think I will be adding Blended Normals support for this shader as well while I'm at it. To make it more capable of shading characters as well.
  • haiddasalami
    Offline / Send Message
    haiddasalami polycounter lvl 10
    Shadow Maps sounds exciting. Definitely would read the code if you put it up :) Out of curiosity how do you render the shadow map?

    Is this something been done through the hypershade and you're plugging that in as a file?
  • Xoliul
    Offline / Send Message
    Xoliul polycounter lvl 10
    It's just baked shadows, right ? Or are you "dynamically" baking them?
    It would be epic if you actually had access to the realtime Zbuffer but that seems like a very far cry...
  • kodde
    Offline / Send Message
    kodde polycounter lvl 15
    Sorry to get you all worked up guys.
    It is baked shadows I'm talking about. My intention is to streamline the process of working with this setup by a script. Best case scenario you would just push a button to update the shadow map after you've edited your light setup.

    haiddasalami> I'm going to try to utilize the Polygon Module > Color > Batch Bake(Mental Ray) with ray traced shadows. This will render to a texture which I will connect to the CGFX shader.
  • Xoliul
    Offline / Send Message
    Xoliul polycounter lvl 10
    Things that you'll have to watch out for is that to do these calculations, you should bake only the cast shadows, not faces that are just not lit by a dot formula. Otherwise you'll have to a lot more complex things to get normalmaps working resolution-independent from the lightmaps (don't wanna go there). But I think you know that.
    Also you might run into some issues with smooth curving surfaces, where there is no direct transition from unlit surface to shadowed surface. I get these problems when adjusting the shading function (like using Half Lambert), you actually see bias problems where the shadows start to appear. Don't know how it'll be for baked maps and not realtime ones.
  • Stradigos
    Offline / Send Message
    Stradigos polycounter lvl 9
    Stradigos> Sounds cool. Mind sharing any of your renders? Would be nice to see :) You can PM me if you don't want to post here.
    Yeah man, here's a good example on the head. No AO pass on this guy since this isn't a capture from post, but it looks great. At least to us. We've come a long way since last year :poly124:

    examplel.jpg

    Unfortunately I can't show off the one of the dressing right now, but it needs some more tweaking texture-wise anyway. We still need to use Mental Ray on some parts, like the dressing window (to view the IV sites), but your shader has really sped up production and looks great too. Our AO pass is now the most time consuming thing we render lol... you've essentially beat out Mental Ray for most of our needs!
  • kodde
    Offline / Send Message
    kodde polycounter lvl 15
    Xoliul wrote: »
    Things that you'll have to watch out for is that to do these calculations, you should bake only the cast shadows, not faces that are just not lit by a dot formula. Otherwise you'll have to a lot more complex things to get normalmaps working resolution-independent from the lightmaps (don't wanna go there). But I think you know that.
    Also you might run into some issues with smooth curving surfaces, where there is no direct transition from unlit surface to shadowed surface. I get these problems when adjusting the shading function (like using Half Lambert), you actually see bias problems where the shadows start to appear. Don't know how it'll be for baked maps and not realtime ones.

    Xoliul> Thanks for the heads-up. I think I know what you are talking about and I am confident that I will run into a heap of different problems and challenges :)

    I have a general idea of all the involved steps and I feel fairy confident that I will be able to solve it to some degree. But I'll just have to go step by step and take it from there.

    Stradigos> Thanks for sharing. Nice to hear that you find it useful. Couldn't the SSAO from viewport 2.0 be used for AO or do you need better accuracy? I mean if it's quality is good enough you could probably save even more time.
    By the way, are you using the Blended Normals feature on your human skin materials? If not, check it out.
  • Stradigos
    Offline / Send Message
    Stradigos polycounter lvl 9
    Shit, I've got to apologize. We're using your shader on our dressings (still a big bulk of the render time saved by you :)), but we're using Chronic's shader on the head. My mistake! Here's the issue I was having with your shader. Yours is on the left, Chronic's is on the right.

    issued.jpgissued.jpg

    Any tips? Using a diffuse, normal, spec, not using DXT5nm style, using skin blended normals, no cube map, and one directional light. If you want more details I can give them.
    Stradigos> Thanks for sharing. Nice to hear that you find it useful. Couldn't the SSAO from viewport 2.0 be used for AO or do you need better accuracy? I mean if it's quality is good enough you could probably save even more time.
    By the way, are you using the Blended Normals feature on your human skin materials? If not, check it out.
    Thanks for the tip :) After some testing today, I found that the SSAO just wasn't as accurate as a quick AO bake from Mental Ray. I'm not surprised. I managed to get the SSAO really close at one point, but as soon as the camera distance changed, it was like I had to find new settings for it because the shadows began to tear.

    Was happy to find the viewport anti-aliasing settings while looking through those settings though :D
  • kodde
    Offline / Send Message
    kodde polycounter lvl 15
    Oh I see...
    Well I cannot tell right off the bat whats up with that shading on the left hand model. But if you're already using Leo's shader then I'm not sure if you stand to gain much if anything with getting proper results with my shader. I'm not entirely familiar with his.

    I'm going to be posting some WIP screenshots soon based on Lee-Perry Smith's free head model, that should give you an indication of what is possible to mimic in terms of human skin with the PBL shader.
  • Stradigos
    Offline / Send Message
    Stradigos polycounter lvl 9
    It's a great learning process though and I'd be happy to do any field testing you need done. I could strip out confidential stuff from the scene and give it to you as well for testing purposes. Just let me know.
  • kodde
    Offline / Send Message
    kodde polycounter lvl 15
    Here's some screens with where I'm at for the moment. Both the main features are in for this push (v0.3). I've done some testing and I've fixed an issue with Cyan Suppression for the Blended Normals feature that had me reorganize the structure of the shader components. But it works fine now. Think this should be stable to release.

    I haven't put that much effort to tweaking the textures to perfection. The substance and roughness are pretty much one solid color all over. There's one directional light from top right corner and the cube map which is lighting the model in this example.

    pblv03wip02.jpg

    PBL_v0_3_wip_gif.gif
  • kodde
    Offline / Send Message
    kodde polycounter lvl 15
    So I just made the [size=+1]version 0.3 available[/size] on my [size=+1]shader site[/size]. Please feel free to try it out and give me feedback.

    The new features are:
    • Blended Normals to give a subtle skin effect in conjunction with normal maps.
    • Shadow Map(pre-baked) support fully integrated with the shader.
    Also, AO was using the same UV-set as the other textures in the older versions. Instead it now uses TEXCOORD3 to allow the user to create a separate UV-set for the AO/Shadow Map.
  • Stradigos
    Offline / Send Message
    Stradigos polycounter lvl 9
    Downloaded it. Giving it a try Monday seeing as I have tomorrow off.

    PS: Do you have any recommendations for a cube map? I think not having one is killing any possible good renders I get from it.
  • kodde
    Offline / Send Message
    kodde polycounter lvl 15
    You are correct, it's absolutely of the utmost critically life threatening importance that you need the cube map to use this shader.

    Check my post nr2 in this thread. You really should learn how to create and tweak your own pre-blurred cube maps, but there's a freebie to get your started :)
  • TrevorJ
    Offline / Send Message
    TrevorJ polycounter lvl 9
    Nice Kodde, lost track of this for a little while, was moving. I fixed the severe angle issues in my normal map and am going to try this out again.
  • kodde
    Offline / Send Message
    kodde polycounter lvl 15
    TrevorJ> Cool. Let me know if you have any questions or encounter any issues and I'll try to help.
  • [HP]
    Offline / Send Message
    [HP] polycounter lvl 12
    I'm a sucker for materials and this is some really great stuff, thanks for sharing!
13
Sign In or Register to comment.