Hey everyone.
I've finally gotten around to porting the
TGA PBL CGFX shader for Maya to the new ShaderFX format for Maya(Works in 3DSMAX as well?). In essence this shader is very similar to the old one, but there are a few improvements.
Highlight features of this 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 sharpness of reflections using pre-blurred mip levels of the cube map.
- Linear shading pipeline. Albedo, roughness, substance, ambient occlusion and the cube map are converted to linear.
- Transparency support through the Albedo texture alpha channel.
- Energy conservation for light amount for both direct and ambient light.
- A bundled cheat sheet image with color swatches for several substance values as well as a bundled cube map to get started.
- SSAO and MSAA through the VP2.0 in Maya(not a feature of the shader itself).
- Optional Blended Normals diffuse lighting method for skin level SSS-effect along with option mask texture. New!
- Shadows with directional and spot lights. New!
- User defined amount of Maya native lights in viewport. New!
- Exposure and Gamma are tweakable in the viewport in Maya 2015 extensions1 for better overall contrast(not a feature of the shader itself). New!
Ideas for future improvements:
- Tutorial video for getting started and using the shader.
- Alternative anisotropic specularity model
- Emissive Texture to simulate emissive surfaces.
- Multi-pass mode to get reflections on transparent surfaces to mimic glass like materials.
- DX11 Tesselation and displacement.
- Vertex color tinting.
- Some kind of SSS approximation other than blended normals(?). Maybe something like this?
Known issues:
- Haven't found a way to get cube map image size or number of mip-map levels to automatically handle this. User has to manually set cube map resolution/side. Default at 512px/side.
Technical Requirements:
- Maya 2015 Service Pack 3(?) or newer. Run with DirectX as render engine.
- Maya 2015 LT(no info on this but has ShaderFX support)? Run with DirectX as render engine.
- Maya 2014 LT(no info on this but has ShaderFX support)? Run with DirectX as render engine.
- 3D Studio Max 2015(no info on this but has ShaderFX support)?
Changelog:
From 1.0 RC2 -> 1.0 RC3:
- Added option to use Blended Normals for the diffuse ligthing. Comes with optional mask texture, weight slider and cyan suppress slider.
- The shader now handles not having textures loaded better. You now get meaningful results from whatever combination of textures you decide to load. As meaningful as it gets anyway.
- The "Use_Abledo_Alpha_as_Transparency" gave strange results when unchecked, not acts as intended and gets completely opaque when not checked.
- The Rotate Cube map slider is now at default value of 360 to force the slider to go from 0-360 range instead of 0-1 as before.
Download:
Using the shader in Maya:
- Apply a ShaderFX material to your object.
- Open the ShaderFX editor through the material in the attribute editor
- File > Import Graph > point to the SFX file.
- Close the ShaderFX editor to show the shader attributes in the Attribute editor.
- Tip: Use MEL command "shaderfx -update" to easily refresh all the textures in the shader.
- Tip: Rename the .sfx file to "startup.sfx" and place it into "Documents\maya\ShaderFX\ Scenes". This will set the shader as the default shader graph to use for new ShaderFX materials.
This is the first public version of this shader. I will keep updating the shader continously with improvments, fixes and maybe a new feature or two. Please give any feedback you have in this thread. Thanks.
The code for light contribution(color & intensity) and shadows are blatantly copy pasted from the TraditionalGameSurfaceShader supplied with ShaderFX in Maya. Did not feel inclined to re-invent the wheel. Author of these snippets? Kees Rijnen?
The model and textures in the image above created by Ronja Melin,
ronjamelin.com.
Replies
The Horizontal Strip, Nvidia style. Needs pre blurred mig levels to fake reflection sharpness.
I'm curious as to what you mean my Multi-Pass mode?
You can save the .sfx file as "Startup.sfx" into "MyDocuments \ maya \ ShaderFX \ Scenes" and then ShaderFX will use this graph every time you apply a new shader. That way you do not constantly have to do the "apply shader, open graph, load .sfx ...etc steps"
Clamped textures go outside range 0-1?
How are you clamping the textures? 3dsMax's bitmap load dialog or in the shader itself?
In the shader itself it should never go outside that range and I dare you to give me steps to repro
Shadows do not work with DX materials in Max and I hate this limitation.
One day I hope to convince internal people to fix this
I'm surprised you have problems with DX11 running in Max. I know tessellation doesn't work but I have not encountered any lock-ups (But then I am probably not pushing max as hard like you do in production)
In your graph, change the default value for "Rotate Cubemap" node to be 360.
That will start the maya spinner with a range from 0-360
Could perhaps do something via MEL?
There is a "shaderfx" command available (but not documented in MEL help docs)
shaderfx -help;
shaderfx -update might work. Not sure. I guess it depends if other shaders in the viewport use the same texture maybe...
ShaderFX> Wow thanks. That startup especially is a nice tip!
While you're handing out nice tips, Any good way to reload textures?
For some reason, I have to clamp the textures in the 0.1-0.99 range manually, this is most prevalent on 1D textures that might have been saved in a somewhat lossy format or compressed format (such as TGA or BMP as example).
I don't have the access extension update, so I can't say if that fixed the clamp issue, but I know for example when I was using the 1D Fresnel like maps (ei: the ones found in the DOTA), the extreme ends of the texture would still show up (a black blob or such).
Just to make it clear, I don't have access to the extension update, which I heard brought some updates to FX, so I cannot say if that fixed it on my end.
Sorry, I should have been more specific, when I said DX11, I meant to say the Tesselation setup (bad habit), every-time I tried to use it, it would lock up Max for me (at least on the default material node, I didn't try creating a naked version and testing that since I figured it's another Max related issue).
Cheers for the input!
@Kodde,
I see, that could work actually well enough.
I intend to get some more examples next week if I can find some time for it. There's a lot of talented students at the school where I work and I'm certain that they've got some nice PBL-based projects. So hopefully I will be able to work something out.
http://www.creativecrash.com/maya/script/filereload
Regarding that texture reloading script I don't think that will work with ShaderFX. That script is most likely based on finding the texture File nodes associated with your selected objects. ShaderFX does not use the same type of File nodes in the same manner.
However as shaderfx(the user) suggested a bit up in this thread the MEL command "shaderfx update" seems to work fine to reload the texture, regardless if the object is selected or not. Maybe just append that command to the MEL-script?
From 1.0 RC2 -> 1.0 RC3:
Download the shader here: kostas.se/shaderfx-tga-pbl-shader
Anyone tried the shader? Any feedback?
I've given it a try and am getting nothing but a solid unshaded red material in my VP2. I've tried a few different textures, some png and some tga, same results...
I'm using the cube that was supplied with the shader (un_Ditch_River.dds)
Im using maya 2015 SP2
Also tried it on SP5, Extention 1
edit:
I just noticed that when I open the shader graph it has these errors in the bottom right:
Am I missing someting?
Thanks
A red/orange shader means the shader code generated is invalid.
So it is not related to the textures you input.
What viewport mode are you in (dx11 or ogl)?
The shader error would usually be printed in the Maya output window I believe.
I'm also curious what Render Engine(OpenGL/DirectX11) you are running?
Now that I have it working, I have some feedback :
I initailly assumed your shader was using the Disney BRDF (Unreal4 style) PBR.
It took me a bit to realize it, but yours is using the Specular/Glossiness model correct? I believe this is the one that marmoset uses.
So with your shader the maps are named a bit differently (Kobbe in green):
Glossiness = Roughness
Specular = Substance
I initially tried plugging in a metallic mask (black for dielectric areas and white for metallic areas) into the "Substance" slot and a Roughness map into the "Roughness" slot. I ended up getting almost no specular response on my asset. After plugging in a specular texture and a glossiness (inverted roughness) texture I got more desirable results.
Note: My textures are all exported out of Substance Painter
My Feedback:
1) Mention up front which shading model you are using, since some people might assume it is the BRDF technique at first.
2) Rename your "Roughness" channel to "Glossiness" to be more consistent with other software using this technique.
3) Rename your "Substance" to "Specular" to be more consistent with other software using this technique as well.
4) More of a wishlist thing, but make a version that supports the BRDF model as well.
Need to wrap up this new version with GGX spec and better synced reflection/spec blurriness.
But I do see the use of being able to work with the UE4 and many others do it with optimizing away a full RGB texture and going for the 1-channel metallic style approach as well. Also I'll be switching around the roughness soon enough to match everyone else's approach to this. Just gets confusing.
Now that I have the proper textures plugged into your shader, it is looking really good! My asset actually looks quite similar between Substance Painter and Maya now. I think the only thing I need to do is use the same IBL in both and it will match up really well.
One other request. I don't know how possible this would be, but its worth a try!
Instead of having a shader where you just plug in textures, I would love to have a root node in shader fx that allows me to make my own shader while using your pbr light model.
Something like this:
Or for Metallic:
Can I ask why you want this interface instead where you have to create your own texture nodes? It's totally possible, I just thought it would be more convenient for the users to not have to create these nodes. I think it might be hard for me to support both approaches. Maybe just reorganize all my input textures in the structure I have now so their all located in the same ground/area in the editor. Making it easier for users like you who want to feed your own solutions?
Some examples:
-Diffuse overlay texture (multiplied usually)
-Tinting based on alpha channel
-Specular overlay to break up tiling on specular of large shiny surfaces.
-Puddles controlled by a puddle mask
-Detail normal map
-Layered shader
-Macro normal map with tiling albedo/spec/normal under it
-animating emissive
etc. etc.
When working on any game asset I quite quite often finding myself in need of some of these "compositing" techniques. Having a basic shader that allows you to plug in your textures is great for really simple assets, but in my opinion, the whole point of having a shader graph system like ShaderFX is to allow artists to do whatever they need to get the end result. Your setup could allow artists to use ShaderFX the way that its built to be used, but with PBL which would be incredibly powerful because we can see pretty much what the in game asset will look like in the maya viewport (assuming you create shaders in ShaderFX that have the same funcionality as your game engine).
If an artist wants to plug textures in manually to the base node in order to use it as a basic shader, they can still do that, or they can expose those texture inputs if they want (just as you have). Leaving it up to the artist is going to allow them to do whatever they need.
Hey,
Shouldn't be an issue i think. Swatches as far as I know is the small shader node preview image inside the ShaderFX editor.
Darker than what? Your expectations or any other system you are used to?
Did you load all textures? Fiddle with any of the multiplier values? Using a cube map? Got "Use all lights" active in the viewport?
Let me know how it goes.
Just want to chime in here because there seems to be some general confusion.
A BRDF is a mathematical approximation of a lighting model, examples being GGX, Blinn-Phong, Phong, Lambert, etc. The Disney reflectivity BRDF is GGX.
BRDF has nothing to do with the specular or metalness workflow. These are two different methods for storing reflectivity content in texture maps, and are not mutually inclusive or exclusive to a specific BRDF. I wrote a bit on this subject here, maybe it will help to clear it up a bit: http://www.marmoset.co/toolbag/learn/pbr-conversion
Kodde, sorry for the rant in your thread dude. The shader is looking nice, its great to see you continuing to work on it.
EQ> Thanks. No problem. I always just assumed that the term BRDF was any way of approximating reflectance where you used two input directions such as incoming light light angle and surface normal. The term pretty much says it all right?
JedTheKrampus> Does this work for ShaderFX texture nodes as well? Think I'll try this out, would be nice if it did but I'm skeptical. :P
Nice setting though. Had no idea about it.
I'm thinking I want a default setup, and also expose inputs more easily for those who want to deviate and modify the shader network on their own to fit their needs.
What file format are you using for a cube map? Ive found the input to be sometimes buggy. Also depending on what version you are using there was a bug in the first shaderfx and cubes came in upside down
I'm going to keep the legacy way of exposing all data as separate channels and also adding a layout where you use packed data as well as metalness instead of a substance texture. Also exposing all inputs in a more easy fashion in the shader network to more easily allow users to tweak to their own liking.
Working on finishing the next version as we speak. Should hopefully be done later today or tomorrow.
Otherwise the MEL command "shaderfx -update" works quite well also if you just make a shelf button or hotkey.
You can get it here: http://www.kostas.se/shaderfx-tga-pbl-shader/
From 1.0 RC3 -> 1.0 RC4:
-"Texture Setup" setting which now also enables "metalness approach" where you use a metalness texture instead of a substance texture.
-Re-organized the shader network which now has an easily accessible "Inputs" group where you can plug in your own texture setup in whatever manner you like. Cube Map is not exposed in the "Inputs" group as it is more intricate to how it works in the shader.
-Added a "Invert Roughness" checkbox under Tweaks.
-GGX specularity
-Specular/Reflection sharpness/blurriness better matched when using Lys(knaldtech.com) generated specular(ggx)cube maps.
-Roughness no longer gamma corrected to better match UE4's results.
New AE layout highlighting Texture Setup, Metalness texture and Invert Roughness:
New shader network layout to more easily allow users to customize their input data:
This is my first post here and I really appreciate any feed back.
I have the latest version of Maya and I get this error:
assignCreatedShader "ShaderfxShader" "" ShaderfxShader1 "pCube1";
sets -e -forceElement ShaderfxShader1SG;
// ShaderfxShader1SG //
// Created shader ShaderfxShader and assigned to the selected objects. //
select -r ShaderfxShader1 ;
// Error: The compile returned an error. //
// Error: //
// cgfxShaderNode::cgErrorCallBack
// Error: The compile returned an error. //
// Error: //
select -cl ;
Any ideas?
Thanks for you time.
As you can see when i import the shader graph i dont get the correct menu within the attributes panel.
Now when i add the shaderfx shader and import the graph i get this result.
Heres what the shader graph looks like when i import it in
Bit hard to see the actual nodes, so i moved them and zoomed in so you can actually see whats going on
Had it somewhat working before when i posted my last question, all the pbr texture inputs were in the attributes. Not sure why this is happening.
( also as a side note, why the hell does maya & max not have a native pbr shader yet?)
Are you guys using Service Pack 5?
Did you change viewport ViewPort 2.0 to use DirectX instead of OpenGL? You change this in the settings/preferences under Display.
So now it's working again! yay
In my previous question i posted last year regarding a dark result i didn't have any lights enabled. I was kinda assuming i'd be able to light my object using just the cubemap, is that not possible? I get a darker result that what i think the cubemap should give. For instance, shouldn't a sunny cubemap light an object sufficiently? Perhaps i have some sort of misconception as to how the cubemap works? I have a feeling like this how it's suppose to work and i just dont understand it properly.
Here's an example (albedo is pure white, one side of the sphere is 100% roughness and the other is 0%):
It's pretty flatly lit by the cubemap
rather than something like in substance designer:
Glad it works
Yes you should be able to light it just with the cube map if you like. You'd miss out on getting shadows though. The cube maps I've tried so far are LDR 8-bit ones, but there's a "Cube Map Multiplier" you can play around with. Remember you can always go higher than 1.0 which the slider probably defaults to as max value, just type in something higher.
Also note that the shader relies on using pre-blurred cube maps from Lys with the GGX setting for best result where the size of specular/specular reflection highlights will match in size. I've provided one cube map in the rar for testing purposes. I'm afraid that one is actually not processed properly with Lys *ashamed*. Although it does have pre-blurred mip levels and should work fine for just testing out the functionality.
I've also set the "Cube_map_size" setting under "Settings" to "512px/side" to match the mip lvl 0 resolution of " "un_Ditch_River.dds". This is an important setting to get right. Wish I could get this info automatically so the user didn't have to. I should change it to "512px/side" as default for next version since I'm also supplying a 512px reference cube map.
I'd probably advise you to use some directional/spot/point lights to light with as well, not primarily just a cube map. The directional light and spot light can use depth map shadows in the viewport with the shader.