| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647 |
- bool GetMetallicAlbedoFromDiffuseSpecularMathematic(out float metallic, out vec3 albedo, vec3 diffuse, vec3 specular, float channelFaultTolerant /*= 0.2*/, float f0 /*= 0.04*/)
- {
- // inaccuracy match first
- //GetMetallicAlbedoFromDiffuseSpecular(metallic, albedo, diffuse, specular);
- // avoid illegal solver
- diffuse += vec3(f0 + 0.01);
- specular += vec3(f0 + 0.01);
- vec3 delta = (diffuse + specular) * (diffuse + specular) - 4.0 * f0 * diffuse;
- vec3 deltaSqrt = sqrt(max(vec3(0.0), delta));
- // solver
- vec3 m = (-diffuse - specular + 2.0 * f0 + deltaSqrt) / (2.0 * f0);
- vec3 weight = diffuse + specular;
- weight /= dot(weight, vec3(1.0));
- float solverMetallic = dot(m, weight);
- vec3 solverAlbedo = diffuse + specular - f0 * (1.0 - solverMetallic);
- bool isValidSolver = delta.x >= 0.0 && delta.y >= 0.0 && delta.z >= 0.0
- && abs(m.x - m.y) < channelFaultTolerant && abs(m.x - m.z) < channelFaultTolerant
- && m.x >= 0.0 && m.y >= 0.0 && m.z >= 0.0
- && m.x <= 1.0 && m.y <= 1.0 && m.z <= 1.0;
- metallic = isValidSolver ? solverMetallic : metallic;
- albedo = isValidSolver ? solverAlbedo : albedo;
- return isValidSolver;
- }
- bool GetMetallicAlbedoFromDiffuseSpecularWithoutColor(out float metallic, out vec3 albedo, vec3 diffuse, vec3 specular, float f0 /*= 0.04*/)
- {
- float d = max(max(diffuse.x, diffuse.y), diffuse.z);
- vec3 normalizedColor = diffuse / (d + (d < EPSILON_LOWP ? EPSILON_LOWP : 0.0));
- normalizedColor = d < EPSILON_LOWP ? specular : normalizedColor; //change specular to gray with intensity of max channel of specular
- float s = max(max(specular.x, specular.y), specular.z);
- float delta = (d + s) * (d + s) - 4.0 * f0 * d;
- float deltaSqrt = sqrt(max(0.0, delta));
- // solver
- float solverMetallic = (-d - s + 2.0 * f0 + deltaSqrt) / (2.0 * f0);
- vec3 solverAlbedo = (d + s) * normalizedColor - vec3(f0 * (1.0 - solverMetallic));
- bool isValidSolver = delta >= 0.0;
- metallic = isValidSolver ? clamp(solverMetallic, 0.0, 1.0) : 0.0;
- albedo = isValidSolver ? vec3(max(0.0, solverAlbedo.x), max(0.0, solverAlbedo.y), max(0.0, solverAlbedo.z)) : diffuse;
- return isValidSolver;
- }
|