Home Technical Talk

[Coming Soon] PBRTK - PBR Viewport Shader for 3DS Max

1
Logo1.png

Traditionally, 3DS Max has not been very good at previewing what game art will look like in the final game, particularly with the standardization of PBR shading in next-gen engines.
PBRTK is a viewport shader for 3DS Max which solves just that! This viewport shader gives you a physically-based shader based on the metalness workflow in line with next-generation game engines, allowing you to have a much better idea of what your model will look like in the final game.

Some screenshots of the shader are below:

Screenshot1.png
Screenshot2.png

Get it here: http://www.mophogames.com/pbrtk-3ds-max-viewport-shader/

Replies

  • gsokol
    Cool! So how are you handling reflections then? Do you have a cubemap input? or...?


    Also...potential issue here. I see you are working in max 2010. Are you preparing this to work post max 2013 when autodesk decided to screw up the way normals work?
  • PhobicGunner
    There's two cubemap inputs. One for diffuse ambient IBL, one for specular reflection IBL. Two cubemaps will be included (the diffuse ambient one I just made from the specular reflection cube in Cubemapgen)

    How did max screw up the way normals work? >.>
    I'm calculating my own tangent basis from the normal, tangent, and binormals.
  • Fwap
    Offline / Send Message
    Fwap polycounter lvl 13
    Very keen for this! :)
  • PhobicGunner
    Fwap wrote: »
    Very keen for this! :)

    Glad to know there's interest in this :)
  • Revel
    Offline / Send Message
    Revel interpolator
    Really interested with this as well!
    But I can't seems to see the screenshot posted on your first post?
  • TheEngineer
    i'm interested in using this as well, however i get this in max 15 with the example you provided.
    C:\Users\Dakota\Desktop\Max_scripts\shader\memory(216,2): error X4000: variable 's' used without having been completely initialized
    C:\Users\Dakota\Desktop\Max_scripts\shader\memory(251,16): ID3DXEffectCompiler::CompileEffect: There was an error compiling expression
    ID3DXEffectCompiler: Compilation failed

    im loading it like i would Xioulin shader so if this is a error on my part my apologies, i know at least one of my buddies would love this kind of option in max aswell.

    best of luck i will be following the development of this closely.
  • radiancef0rge
    Offline / Send Message
    radiancef0rge ngon master
    Are you hard coding the multimask to those specific channels or is there an option to change that?
  • PhobicGunner
    i'm interested in using this as well, however i get this in max 15 with the example you provided.

    Eh? The example I provided?
    Are you talking about the viewport shader template?
    Try changing line 213 to this:
    SurfaceOutput s = (SurfaceOutput)0;
    
  • PhobicGunner
    Are you hard coding the multimask to those specific channels or is there an option to change that?

    Actually, I just changed that yesterday. Now it takes separate images for metalness, ambient occlusion, and roughness. Also, non-metal surfaces are now assumed to be 4% reflective - this was mentioned over on the PBR in Practice page on the Marmoset website, and I went with it as it allows me to drop a full extra texture. It also seems to work just fine in practice.
  • amartinez
    Offline / Send Message
    amartinez polycounter lvl 8
    Glad to see you are pushing this forward full on : ).

    I had a question regarding the 4% (0.04) base reflectivity. Is this the linear value? or the gamma space value? (Same for 30 -50 minimum value on the diffuse, is it 30-50 before or after gamma correction?)

    Thanks.
  • PhobicGunner
    0.04 is the linear space value.
    Don't know about the diffuse one. I think it's safe to assume that it's pre-gamma-correction, since generally PBR works/looks best in a linear color space.
  • PhobicGunner
  • Obscura
    Offline / Send Message
    Obscura grand marshal polycounter
    Thanks! Rouhgness works reverse by the way.
    - And the cubamep is wrapping strange. I mean it looks ok from the default view, but its coordinates looks buggy when im rotating the camera.
  • PhobicGunner
    Obscura wrote: »
    Thanks! Rouhgness works reverse by the way.

    Not necessarily ;)
    It's easy enough to change of course. I may add an option to change how roughness works. Until then an easy workaround is just to import your roughness map into Photoshop and hit CTRL+I.
  • PhobicGunner
    Obscura wrote: »
    And the cubamep is wrapping strange. I mean it looks ok from the default view, but its coordinates looks buggy when im rotating the camera.

    Screenshots?
  • Obscura
    Offline / Send Message
    Obscura grand marshal polycounter
    Maybe I see it wrong but it has strange distortion.
    mZjtLuN.jpg
  • PhobicGunner
    Yep, that happens in real life too.

    uffizi_probe.jpg

    Look at the top of the sphere, notice you can see the ground.

    It's actually common to capture an environment for image-based lighting by taking a photograph of a highly reflective ball as seen above.
  • Obscura
    Offline / Send Message
    Obscura grand marshal polycounter
    I worked with several cubemaps and cubemaps setups inside udk earlier, and I didnt had this strong distortion on the edges. Maybe its something with the with the dimensions of the cubemap(like with a parallax corrected cubemap)?
  • PhobicGunner
    I don't know what UDK is doing - it could be they are doing some sort of highly simplified calculation which isn't totally accurate.
    All I'm doing is reflecting view direction along surface normal using the built-in reflect function. The result is also realistically plausible as evidenced by many photographs I can find on Google Images, so I don't think it's an issue.

    EDIT
    Seems UE4 also has results closer to what I have: https://d1wzu4qct23er4.cloudfront.net/files/78349185fe86484abe39f70b3666db92/original/banner2.jpg

    So I'm assuming it's probably some optimization or approximation in UDK.
  • TheEngineer
    its not installing for me on max 2015, ran as admin and made sure i was running direct X 9, it would be awesome if i could use this in my workflow, if its too much of hassle i would understand though, you pushed out the first version quickly though and your screen grabs look amazing.
  • PhobicGunner
    its not installing for me on max 2015, ran as admin and made sure i was running direct X 9, it would be awesome if i could use this in my workflow, if its too much of hassle i would understand though, you pushed out the first version quickly though and your screen grabs look amazing.

    What issue are you encountering? Material doesn't show up in material browser, invisible in viewport, files not installed to correct locations, errors...?
  • TheEngineer
    its not doing anything, i dragged the file into the view port, then checked to see if they were going into the directories that were defined in your read me and they weren't created nothing in the start up folder nor in the folder with the other shaders are stored, its like its not running the script nor installing. no dialog pops up for installing nor does it initialize, im not sure whats going on to be honest maybe someone else who has max 2015 could try and see if they are having the same issue?
  • PhobicGunner
    Do you have any older versions to test on?
    If the MZP file runs at all it should pop up a message box telling you to restart 3DS Max. If it doesn't, then something is definitely wrong.

    EDIT
    Still, you CAN manually install the files yourself. It's just more of a pain.
    To do this, rename the .MZP extension to .ZIP, then extract it. Take the files under res/PBRTK/ and put them into Maps/fx/PBRTK/. Then, take the PBRTKMaterial.ms script under script/ and move that to Scripts/Startup/PBRTK/
  • gsokol
    There's two cubemap inputs. One for diffuse ambient IBL, one for specular reflection IBL. Two cubemaps will be included (the diffuse ambient one I just made from the specular reflection cube in Cubemapgen)

    How did max screw up the way normals work? >.>
    I'm calculating my own tangent basis from the normal, tangent, and binormals.

    Oof, sorry for responding late...I was referring to how Nitrous spits out wierd values for tangents/binormals. I really don't know much about it, other than it crippling the xoliul2 shader.

    That pretty much killed me ever attempting to use viewport shaders in max ever again, so I haven't bothered messing with any new shaders since.

    Sounds like its working fine for other people though, so ignore me :D
  • PhobicGunner
    Well, I have no idea if it works in Nitrous. Can't you just disable that and use straight DirectX 9?
  • TheEngineer
    i got it working by installing it the manual way, i just got max recently so i dont have an older version. i dont know much about scripting for max so i cant lend a hand with figuring out why it wont start for 2015 but from a brief look at what you have done so far you have done an amazing job! thank you for your work.
  • PhobicGunner
    If it's working, then that's great :). Just need to figure out MZP files then. Unfortunately, I've only got 2010 >.<
  • spacefrog
    Offline / Send Message
    spacefrog polycounter lvl 15
    Just tested in Max 2014 and Nitrous and the script spits out errors about missing albedotexture in null etc... Directly in the script's "on create" handler., when trying to assign the albedo texture .
    Switching to DirectX mode fixes that. Same is true for Max 2015 and nitrous

    I'm not sure wether the things your scripts does are not supported in Nitrous at all or only some small checks would be sufficient to make it work in Nitrous. But would be great to have it work in Nitrous

    Anyways great initiative, and thanks for posting this
  • Froyok
    Offline / Send Message
    Froyok greentooth
    Nice work !
    What BRDF do you use in your shader ?
  • PhobicGunner
    At the moment the shader is normalized blinn-phong. May switch it over to Cook-Torrance eventually, as that has nicer specular highlights.
  • EarthQuake
    If you want this to match up closely with common engines, such as UE4, Cryengine, Unity 5, etc, you should probably use GGX.
  • PhobicGunner
    Mmm, nice one.
    Hadn't heard of GGX before for some reason, will take a look. Seems to have much nicer/softer highlights than Cook-Torrance.
  • EarthQuake
    Yeah, GGX highlights are awesome. Look for disney's papers on GGX, they originally developed it.
  • almighty_gir
    Offline / Send Message
    almighty_gir ngon master
    just be aware that getting the importance sampling to work for the (ggx) reflective component is a complete bitch.

    i know from experience.
  • PhobicGunner
    Hey, if anybody's got 3DS Max 2011, mind giving this shader a test?
    I originally developed it for someone else, but they can't seem to run it in 2011 (invisible in viewport). I forged ahead and released it anyway as I have no means of actually testing or debugging this, but hopefully somebody out there may be able to help.
  • oblomov
    Offline / Send Message
    oblomov polycounter lvl 8
    @Earthquake : AFAIK the original GGX paper was by Bruce Walter, of Cornell University (at EGSR07). Disney popularized it with the course on PBR at Siggraph, but they did not invent it. Cf https://www.cs.cornell.edu/~srm/publications/EGSR07-btdf.pdf
  • PhobicGunner
    Well, as I've never even heard of GGX before I'm not sure if I've implemented it correctly, but it looks OK in the viewport.
    I actually really like the falloff of the highlight. Much less of a severe falloff than Blinn-Phong or Cook-Torrance.
  • EarthQuake
    oblomov wrote: »
    @Earthquake : AFAIK the original GGX paper was by Bruce Walter, of Cornell University (at EGSR07). Disney popularized it with the course on PBR at Siggraph, but they did not invent it. Cf https://www.cs.cornell.edu/~srm/publications/EGSR07-btdf.pdf

    Interesting, my understanding is based on what I've heard from various programmers, thanks for the correction.
  • PhobicGunner
    OK, new version coming very soon (later today?)
    This new version's got some changes:
    1.) Now using GGX instead of normalized blinn-phong, bringing specular results closer to that of UE4.
    2.) Changed the specular cube mip factor to more closely match specular highlight results.
    3.) New specular cube texture included. Apparently I forgot to check "Save mipchain" in CubeMapGen. Oops. New specular cube does not suffer sharp edges, yay!
  • PhobicGunner
    OK, new version's up! Same link as before (see first post)
    Be sure to uninstall old version first before installing new version.
  • spacefrog
    Offline / Send Message
    spacefrog polycounter lvl 15
    Hey, if anybody's got 3DS Max 2011, mind giving this shader a test?
    I originally developed it for someone else, but they can't seem to run it in 2011 (invisible in viewport). I forged ahead and released it anyway as I have no means of actually testing or debugging this, but hopefully somebody out there may be able to help.


    Just tried - works perfectly fine with Max 2011....
  • PhobicGunner
    spacefrog wrote: »
    Just tried - works perfectly fine with Max 2011....

    Hm. Well, it must be something strange with his particular setup.
    He also has Xoliul installed, maybe that would make a difference?
  • Revel
    Offline / Send Message
    Revel interpolator
    Works great on 3ds Max 2009 here. Just found some "secret" feature I guess that when we select the object and move the slider, viewport update in realtime! haha not sure it's a secret feature or what but if the object not selected the changes wont be in realtime , means after let go the slider then only viewport will update. Is this the intended behavior?
  • almighty_gir
    Offline / Send Message
    almighty_gir ngon master
    hope you don't mind but i looked through the shader code a little.

    for pbr you don't use emission for either the diffuse or specular IBL, they both get added to the diffuse/specular response as applicable.

    also, you're not doing any kind of importance sampling for your IBL, you're just scrolling through the mip levels based on roughness * mip total, which is "wrong" for a couple of reasons. the first reason is that it doesn't match the actual roughness curve that GGX has (just use the specular distribution factor for this). the second being that you're always going to have a "stepping" effect with the IBL, you'll never have true variance in IBL based on your roughness input... you could have a well defined material that looks incorrect because the IBL is returning a block value rather than a true one.

    I would suggest studying resources like these:
    http://http.developer.nvidia.com/GPUGems3/gpugems3_ch20.html
  • oblomov
    Offline / Send Message
    oblomov polycounter lvl 8
    You can also have a look at the glsl code for the PBR shader that ships with Substance Designer which uses exactly the method almighty_gir described (except I directly read the environment from a lattitude/longitude texture instead of a cubemap, but the changes to account for that are simple).
  • Revel
    Offline / Send Message
    Revel interpolator
    Also with a black albedo color, shouldn't we still get the reflection from the metalness slider?
  • almighty_gir
    Offline / Send Message
    almighty_gir ngon master
    Revel wrote: »
    Also with a black albedo color, shouldn't we still get the reflection from the metalness slider?

    if the albedo is black then metalness will try to use black as the reflective value.
  • PhobicGunner
    hope you don't mind but i looked through the shader code a little.

    for pbr you don't use emission for either the diffuse or specular IBL, they both get added to the diffuse/specular response as applicable.

    also, you're not doing any kind of importance sampling for your IBL, you're just scrolling through the mip levels based on roughness * mip total, which is "wrong" for a couple of reasons. the first reason is that it doesn't match the actual roughness curve that GGX has (just use the specular distribution factor for this). the second being that you're always going to have a "stepping" effect with the IBL, you'll never have true variance in IBL based on your roughness input... you could have a well defined material that looks incorrect because the IBL is returning a block value rather than a true one.

    I would suggest studying resources like these:
    http://http.developer.nvidia.com/GPUGems3/gpugems3_ch20.html
    1.) As far as Emission, that was a quirk of porting over some code from Unity. In Unity, it was stuffed into Emission since that's guaranteed to be added to the result after all lights have been accumulated (rather than running per-light)
    2.) Wat. I thought mip selection was the standard way of doing blurry reflections?
    Revel wrote: »
    Also with a black albedo color, shouldn't we still get the reflection from the metalness slider?

    Nope. In that case your albedo should be the color of the metal, as per standard metalness workflow. You're probably thinking of the specular color workflow

    EDIT: I'll take a look at importance sampling when I have time (probably next weekend)
  • almighty_gir
    Offline / Send Message
    almighty_gir ngon master
    1.) unity may do that, but it's incorrect on a technical and physical level.

    Emissive pixels are considered to pass without lighting/shadowing. They can also give off illumination based on their brightness, depending on the engine (and usually they're great in combination with bloom, even if they don't give off illumination, due to their high contrast with shaded pixels around them).

    Because emissive pixels don't receive lighting or shadow, they're physically incorrect, which is one of the cornerstones of PBR.

    2.) Yes, mip selection is used, but it's used in conjunction with importance sampling. the simple reason being that if your cubemap has for example, 8 mip levels. Then without importance sampling your material can only haver have 8 "bands" of roughness in the IBL contribution.

    For example:
    RoughnessChart.png

    Without importance sampling, you may have a material that's closer to the pen tip than the chrome sphere in terms of the value you've handed to the shader, but because it's not quite rough enough to be in the bracket with the pen tip, it has a chrome reflection.

    What importance sampling does is help break up each band so you get a more true representation of a roughness curve.
  • Revel
    Offline / Send Message
    Revel interpolator
    Hmm, I'm still learning and adapting the way PBR works, so correct me if I'm wrong. From what i understand is that when the object containing more metal quality in it makes the energy that hits it almost all reflected back as a reflection so since not much energy left to scatter around the surface which make the albedo appear black.

    Quote from Andrew Maximov's blog;
    And finally don’t forget that the more metallic your surface gets the closer to black your albedo contribution becomes.
1
Sign In or Register to comment.