PBR Metalness equation

Started by
16 comments, last by dpadam450 8 years, 5 months ago

I've been messing around with some texturing in some programs that have PBR viewport shaders. From a little reading and messing around, it seems like the only thing that the metalness changes in the lighting equation is whether the specular is multiplied or added. Metal = multiply, non-metal = add.

Is that correct?

NBA2K, Madden, Maneater, Killing Floor, Sims http://www.pawlowskipinball.com/pinballeternal

Advertisement

No. Specular lighting is always added.

Metalness is a replacement for the "specular map", or the "F0" value -- it's an easier way of authoring specular maps. It also ties in with the main colour texture though.

Metalness of 0/black means that you should use an F0 value of ~0.03 (~8/255 in a specular map).

Metalness of 1/white means that you should read the main "color" texture and use that as F0 (and also replace the "diffuse color" with black).

Metalness of grey means you do something in-between those two extremes (diffuse color becomes party black, specular color is a lerp of 0.03 and the color map).

I use a value of 0.08 as multiplier of the specular value, 0.03 is more correct ?


SurfaceData.DiffuseColor = Diffuse_Lambert( FinalBaseColor.rgb - ( FinalBaseColor.rgb * Metallic ) );
SurfaceData.SpecularColor = lerp( 0.08f * Specular, FinalBaseColor.rgb, Metallic );

I use 3% in my engine. UE4 uses 4%. Just depends what you want your minimum/default non-metal reflectivity to be.

For reference, water is 2% and most organic materials are 3-5%. Diamonds are 18%.

Lot's of things confusing me here. In the Marmoset example, F0 is in range 0 to 1, but your second comment says to use a color for F0. I guess that is fine because is the amount of R,G,B independent reflection. Either way, just a multiplication on the specular computation.

Q1: For a non metal that is glossy, if F0 = vec3(.03,.03,.03), then how will the equation ever reflect full light? I'm definitely missing some equations here.

For a shiny plastic, say a guitar or piece of marble. roughness = 0, metal= 0, diffuse = dark green:
---->dark green * textureCube(mipLevel 0) + textureCube(mipLevel0)*vec3(.03, .03, .03) ?

My current understanding which must be wrong because shiny dark green plastic just comes out to be shiny dark green plastic with a super tiny amount of specular.

Q2: What is used for the incoming light values for diffuse?

IncomingSpecularLightValueAtPixel = textureCube( reflected eye over surface normal, roughnessValue)

IncomingDiffuseLightValueAtPixel = same thing?

NBA2K, Madden, Maneater, Killing Floor, Sims http://www.pawlowskipinball.com/pinballeternal

For a non metal that is glossy, if F0 = vec3(.03,.03,.03), then how will the equation ever reflect full light?

There are two elements to this question,

First, a non metal material will tend to have a dimmer reflection of the surrounding (because some of the light will be absorbed and/or diffused). You can usually still see bright spots because the intensity of point lights is so much higher than the surrounding.

Second, that color F0 is the minimum total reflection. If you are seeing things from a grazing angle, the reflection is closer to one (if you take the Fresnel effect into account).

Here's an illustration : http://media.codermind.com/lighting/dielectric-ggx-rough-0-2.mp4

There's a bright spot from the sun, it is dim when it is facing the camera but becomes much whiter as it is seen from increasingly grazing angles on the edges of the sphere.

I'll have to start implementing this tonight and come back. I'm thinking what I'm missing is that the amount of reflection is not actually additive with non-metals.

Ex. Dark green shiny plastic
reflectiveness = matrialReflectiveProperty + Fresnel

FinalColor = (1.0- reflectiveness)*darkGreen + reflectiveness*textureCube(envTexture, roughness)


I'm thinking this is more what the equation would have to look like. And in the case of metals something like:

reflectiveness = matrialReflectiveProperty + Fresnel
FinalColor = /*(1.0- reflectiveness)*darkGreen*/ + reflectiveness*textureCube(envTexture, roughness)*metalColor

That seems more correct. If a material is 100% reflective, the diffuse doesn't matter right? I can't find any actual code used for PBR. That was how I did my car shader, but then what is F0?

NBA2K, Madden, Maneater, Killing Floor, Sims http://www.pawlowskipinball.com/pinballeternal


If a material is 100% reflective, the diffuse doesn't matter right?

No. What's stored in the diffuse texture always matters, it just means different things in different cases. In the setup you're trying to use, if a material is 100% metal, the value in the diffuse texture is re-purposed to be the F0 value. Otherwise, for non-metal (dielectric) materials you hard-code F0 to ~0.03-~0.04 for most materials (see Hodgman's comment), and the value in the diffuse texture is the diffuse color you're used to. I haven't used Marmoset, but from seeing what a few other places are doing, the 0 to 1 mapping for F0 will probably do something like change the value from ~0.01 to ~0.08.

I think what you're referring to as reflectiveness is what most people refer to as roughness (or shininess). This is stored in its own texture and is used alongside the others to control how shiny the surface is - this is what controls the specular highlights for direct lighting, and the mip selection for indirect lighting. It is used as part of a larger equation to control surface appearance.

Most approaches use the following (or close variations) as the starting point of textures using physically based rendering.

Diffuse (or Base Color): for dielectrics, exactly what's in the texture. for metals, the f0 value

Metal: 0 - dielectric. 1 - metal.

Roughness: how rough the microsurfaces along the geometry are (alternatively, this can be Shininess, which is just 1.0 - roughness)

Normal: plain old normal map

There are a few variations to the above that different engines use, but that should give you the gist of where values are coming from.

As far as finding actual code used for PBR (btw, you need to read this stuff - start with the Physics of Math and Shading presentation and go from there):

http://blog.selfshadow.com/publications/s2013-shading-course/

http://blog.selfshadow.com/2014/08/12/physically-based-shading-at-siggraph-2014/

http://blog.selfshadow.com/publications/s2015-shading-course/

Ok I see F0 is when the angle to the surface is 0. I already understood this idea, just didn't know what it was. I'll respond if I end up getting with this shader.

NBA2K, Madden, Maneater, Killing Floor, Sims http://www.pawlowskipinball.com/pinballeternal

I'm close but I don't get how F0 = a color. Fresnel is a scalar I thought? An amount of reflectivness given a direction of the viewer to the surface. So how do I plug a color in to the fresnel equation?


This picture demonstrates why I'm confused. I have Roughness = 0. BaseColor = Red. Then the top image is pure metal, bottom is pure plastic.

Metal
Since metal has no diffuse, the red must come from the specular portion of the equation, which means my cube map must multiplied by red. However in image 3, we have the fresnel effect, where at high angles, it is not multiplied by red. So the only equation that works for this is.

Output = 0*red + mix( cubeMap*red, cubeMap, fresnelAmount);

So we are either direct on viewing a tinted cubemap or at high angles fresnel goes to 1.0, in which case the cubemap takes over completely. For some reason I feel like this is wrong but based on these images that is the only mathematics that makes sense to what I see.

Plastic
To arrive at this plastic value which is image #2, it seems like:
Output = red*cubeMap + cubeMap*fresnelAmount;

Our diffuse material reflects only red values based on light intensity incoming and then we have specular added ontop of this, which appears to be untinted specular.

However, I feel like both of these are wrong.

2cgeie0g66gj3q7zg.jpg

NBA2K, Madden, Maneater, Killing Floor, Sims http://www.pawlowskipinball.com/pinballeternal

This topic is closed to new replies.

Advertisement