-
-
Notifications
You must be signed in to change notification settings - Fork 21.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Incorrect PBR Shading #40753
Comments
We use a different PBR model from Blender. So some differences are expected and are completely acceptable. Remember, Godot is a game engine, we trade speed for physical accuracy wherever it makes sense. A clear example is the |
This part seems somewhat counter intuitive to me. Sidenote: Blender's PBR model is based on Disney's Principal Shader work, as it is a fairly widely used model across VFX and game industry and used for broad compatibility and because it is very 'artist friendly' with intuitive parameters for materials, it's the same model used for Pixar's Renderman, Substance Painter, Unreal Engine and Unity. Information about it can be found here: https://clarissewiki.com/4.0/disney-principled.html I appreciate your feedback and thank you for your patience, I wish to explain why I feel this PBR model in Godot is problematic from my perspective as a professional 3D artist. I do not wish to sound like I'm complaining, I just wish to offer my perspective: When for example, I export models from other software, the texture sets they export often include a specular texture map. I can say from experience, every 3D software I've ever used, if it has exported or used specular texture maps, they are used to control the strength of specular reflection. Everything from Blender to Three.js. If for example you go to any number of free CC0 texture websites, such as texturehaven, the specular texture maps control specular reflection strength, where black = no specular. Example Compounding this, even though 'specular' means something different in Godot, Godot does import specular texture maps for materials on model imports. This adds to the confusion from an artist perspective. For example if I export a model from Blender in GLTF format with textures, and import it into Godot, if the GLTF asset includes specular textures, the specular textures are loaded in Godot during import and assigned to the specular texture property in SpatialMaterial, as if they serve the same function. But obviously they don't, so the resulting material looks very different. This for me is an issue of interoperability with other software (Blender, Unity, Unreal Engine, Substance Painter...) It means I can't design materials or assets in other software with any sense of what they will look like in Godot, as Godot is interpretting the specular property in a very different way to everything else I use. Also, putting aside all that for a moment, shouldn't an albedo/base colour of solid black produce a solid black material? Even with a roughness of 0, it should be possible to have a solid black material with no specular highlight? Where is the specular coming from and how can an artist control it's strength? Should we not have a material property to directly control specular reflection strength? From an artist, software compatibility and interoperability perspective, it would be much more convenient and easier for me if Godot's PBR shading was compatible with other industry software. Again I don't wish to sound like I'm complaining, I just wish to explain from my perspective why I feel this way. |
My apologies. I seemed to have caused some confusion. Godot's PBR model is based on the Disney PBR model. In fact, we use many of the same methods that Unreal does. To be more clear. I meant to say that one cannot expect exact parity between the way a model looks in Blender and the way a model looks in Godot. This is the same difference between Blender and any other game engine (including Unreal). When you take a material from a 3D DCC which has correctness as a priority it will look different in a game engine which has speed as a priority. Thank you for clearing up what specular model blender uses. I thought they might still use a blended specular approach Again my apologies. My comment earlier seemed like it made you think that Godot's PBR model was incompatible with the Disney model. Now, back to your original post. I would be interested to see how other game engines handle specular metals with a base color of black. While we aim to be as similar as possible to Eevee, in many places we have to make tradeoffs. So the useful knowledge for us is, do other game engines make those tradeoffs, or do they match the behaviour of Eevee? edit: I did some research to figure out what physically correct results should be. I came open the excellent Filament docs, we often turn to them to assist in our PBR implementation. They explain that in the real world, metals have a luminosity between 67% to 100%. Which correspond to sRGB colors between the 170-255 range https://google.github.io/filament/images/material_chart.jpg. The takeaway is that values outside this range are no longer based in reality as the model only holds for the data set it was designed for. |
@clayjohn I can confirm so far that Unreal Engine materials produce the same result as Blender, when given a specular of 0 will not show any reflection. This is confirmed by their documentation here. Quote from the page:
They also describe how to use specular here in this section of their documentation. Screenshot of the relevant section: Sidenote: I don't know if this is still the case but in 2013 they did a Siggraph presentation explaining they used GGX for computing specular and described it as "well worth the cost", Blender also uses GGX for Eevee and Cycles. Link to presentation notes here. And that is true for metals that those are the realistic values ranges for base colour for raw metals (with exceptions for special circumstances, such as materials that are made up of layers of materials, such as paint layers, etc). For me the issue is more that when something is 0.0 metallic, 0.0 specular, it should no longer be showing a reflection. That chart you linked does show what I am referring to, there they refer to specular as reflectance and with a value of 0.0, I can't see a reflection on the surface. Likewise with metallic at 0.0, there should be no metallic property to a surface and no reflection from that either. |
I understand. Game engines separate specular reflections from various light sources (e.g. OmniLights, DirectionLight, and IBL lighting from the Sky). The specular reflection from each light source is added when the light is calculated. The light from the Sky (IBL) is unique though, it is precalculated into a LUT and then read at render time. The BRDF for IBL lighting we use comes from Unreal. We use their analytic approximation that is intended for mobile. Being an approximation, it is not quite accurate, but it is very fast. For other light sources we use the more correct BRDFs (which dont need to be precomputed). My guess is the slight bit of remaining specular reflection is caused by this approximation. If so, the solution would be to replace it with a proper LUT. |
I appreciate the effort for the explanation, and you offering me your time and patience on this! That solution you suggest sounds great. |
Isn't this just a confusion about the difference between specular workflow and roughness / metallic workflow? https://marmoset.co/posts/pbr-texture-conversion/
But afaik godot spatial material doesn't have a specular property? |
@lawnjelly I don't believe this issue is related to that. I understand there are different PBR workflows, one based around metallic and the other based on specular and that can cause issues of it's own but I don't believe that is the cause of this issue. In this situation, this is all metallic / roughness workflow in Godot/Blender/UE/etc, so it's not the conversion issue. Godot's spatial material does have a specular property, there's some videos up in my original post showing the effect of it's slider and comparisons to Blender Eevee, and further down images from Unreal Engine. |
Ah ignore me, clayjohn has pointed out there is a specular option in metallic for f0, just not a specular texture map, I get the confusion now. |
@clayjohn suggested solution sounds great to me, I'd be happy for that. Edit: Ignore this, see following message.
|
Correction, obviously the specular won't show for the omnilight if I have a roughness of 0.0, because omnilights in Godot have no 'size' so they won't show unless a surface is at least a bit rough. I increased roughness to 0.1 and now it does show. Base colour black (0.0, 0.0, 0.0), metallic 0.0, specular 0.0 and roughness of 0.1 with an omnilight, no environment lights or light probes: Surely that specular highlight shouldn't be there. |
I just did a comparison between Godot, Unreal, and Blender. It is interesting to note that in Unreal when you reduce |
@clayjohn Maybe it's a performance optimisation? Experimenting with Godot's specular property and omni lights, 0.0 specular in Godot "feels" like around '0.25' in Blender Eevee in comparison. |
@mindinsomnia Thanks for the link! It's making me think more and more that Unreal is using specular as an easy way of reducing the strength of specular reflections. Note the linked article Everything is shiny and the tip in the documentation you linked
A specular value of 0 doesnt really make sense in a PBR system. My guess is that Unreal has taken advantage of this and changed the behaviour of specular when it is outside physically normal values. By sticking to the plain PBR equations, Godot looks different. That being said, this issue seems to be converging with #33616 where the user wanted a setting to disable specular altogether (even though that would not be physically correct). The solution reduz and I discussed was adding a |
I understand where you're coming from on this. It's a balancing act in my opinion. On the one hand, as a 3D artist I've learnt the rules of PBR and I ensure my materials adhere to (or at least appear to adhere to) the rules, such as one of the first rules I learnt, 'everything is shiny'. But with art, knowing the rules is just as important as knowing when to break them. There is value in my opinion in Unreal and Blender's approach in permitting the rule range of specular values, even if going down to 0.0 is usually not physically correct for most surfaces. There are times when you just want to precisely control the amount of specular being added to something to achieve the exact look you're going for. Sometimes it's because you are going for something hyper real, fantastical, stylised, cartoony, etc, other times it might be just because you're trying to 'cheat', like if you have a deep cavity in your textured surface that due to self shadowing shouldn't be receiving any specular reflections, or at least greatly reduced specular highlights: Or if you're trying to fake a particular realistic complex lighting interaction and can't quite get there while operating within the rules. Or whatever the reason, there's usually something that comes up, eventually you end up having to dial something in manually with the specular slider. |
@clayjohn Isn't there already a specular mode property in StandardMaterial3D? IIRC, it has a Disabled mode since SpatialMaterial was added in 3.0. |
@Calinou it only applies to the specular blob, not specular from IBL. So we need something more. |
Hi, Please can you check the roughness value? A low value like 0, will make the object reflect the environment because its become really smooth. If you want to check this correctly in Blender, you need to have a HDRI background, so when the value is low, you will see reflection like in the screenshot. If you increase the roughness value to a high value, it will diffuse the environment from the reflection make it appear "rough", hence you should not see these reflection spots from the surface. All this discussion seem to be really how Godot PBR model treat the roughness channel. If you want to diffuse the specular spot, increase the roughness. Want to make it real smooth and shiny reduce it... For the values in the metallic channel, change the appearance of the surface, as a low value, will make it look soft like plastic/cloth, and a high value will make it look harder, like metal/glass. |
@christianclavet I believe the point of this issue is to show the inconsistency of Godot's |
You are absolutely correct, that is indeed precisely the point of this issue and all I was trying to convey. |
Closing in favor of godotengine/godot-proposals#3792, as feature proposals are now tracked on the Godot proposals repository. |
Godot version: v3.2.2
OS/device including version: Windows 10 & Linux Mint 20, GLES3
Issue description:
Godot's implementation of PBR shading seems to be producing incorrect results.
With a base colour of completely solid black, a surface should reflect no light, but for some reason, even with a base colour of complete blackness, a reflection is still present on surfaces.
Here are some videos to compare Godot vs Blender Eevee:
Here is a purely metallic material in Blender. Note as the base colour reaches completely black, the reflections on the surface completely disappear and the surface turns completely black.
Here is the same material in Godot. Even with a base colour of black, there are still reflections on the surface.
Also, when a material has no metallic property (metallic = 0.0) or specular property (specular = 0.0) it should not produce any reflections, the surface should be 'diffuse', because that's the only BSDF left when all metallic and specular reflection is removed.
Here is an example of a grey sphere:
Note in Blender, with a grey sphere, with no metallic or specular, the surface is purely diffuse, as it should be.
The same material in Godot still shows reflections. Even though this surface has a low roughness value, that does not mean it should show a reflection, because there is no specular or metallic property to induce one.
Steps to reproduce:
Minimal reproduction project:
Test PBR Material.zip
The text was updated successfully, but these errors were encountered: