material.chunk 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. bool GetMetallicAlbedoFromDiffuseSpecularMathematic(out float metallic, out vec3 albedo, vec3 diffuse, vec3 specular, float channelFaultTolerant /*= 0.2*/, float f0 /*= 0.04*/)
  2. {
  3. // inaccuracy match first
  4. //GetMetallicAlbedoFromDiffuseSpecular(metallic, albedo, diffuse, specular);
  5. // avoid illegal solver
  6. diffuse += vec3(f0 + 0.01);
  7. specular += vec3(f0 + 0.01);
  8. vec3 delta = (diffuse + specular) * (diffuse + specular) - 4.0 * f0 * diffuse;
  9. vec3 deltaSqrt = sqrt(max(vec3(0.0), delta));
  10. // solver
  11. vec3 m = (-diffuse - specular + 2.0 * f0 + deltaSqrt) / (2.0 * f0);
  12. vec3 weight = diffuse + specular;
  13. weight /= dot(weight, vec3(1.0));
  14. float solverMetallic = dot(m, weight);
  15. vec3 solverAlbedo = diffuse + specular - f0 * (1.0 - solverMetallic);
  16. bool isValidSolver = delta.x >= 0.0 && delta.y >= 0.0 && delta.z >= 0.0
  17. && abs(m.x - m.y) < channelFaultTolerant && abs(m.x - m.z) < channelFaultTolerant
  18. && m.x >= 0.0 && m.y >= 0.0 && m.z >= 0.0
  19. && m.x <= 1.0 && m.y <= 1.0 && m.z <= 1.0;
  20. metallic = isValidSolver ? solverMetallic : metallic;
  21. albedo = isValidSolver ? solverAlbedo : albedo;
  22. return isValidSolver;
  23. }
  24. bool GetMetallicAlbedoFromDiffuseSpecularWithoutColor(out float metallic, out vec3 albedo, vec3 diffuse, vec3 specular, float f0 /*= 0.04*/)
  25. {
  26. float d = max(max(diffuse.x, diffuse.y), diffuse.z);
  27. vec3 normalizedColor = diffuse / (d + (d < EPSILON_LOWP ? EPSILON_LOWP : 0.0));
  28. normalizedColor = d < EPSILON_LOWP ? specular : normalizedColor; //change specular to gray with intensity of max channel of specular
  29. float s = max(max(specular.x, specular.y), specular.z);
  30. float delta = (d + s) * (d + s) - 4.0 * f0 * d;
  31. float deltaSqrt = sqrt(max(0.0, delta));
  32. // solver
  33. float solverMetallic = (-d - s + 2.0 * f0 + deltaSqrt) / (2.0 * f0);
  34. vec3 solverAlbedo = (d + s) * normalizedColor - vec3(f0 * (1.0 - solverMetallic));
  35. bool isValidSolver = delta >= 0.0;
  36. metallic = isValidSolver ? clamp(solverMetallic, 0.0, 1.0) : 0.0;
  37. albedo = isValidSolver ? vec3(max(0.0, solverAlbedo.x), max(0.0, solverAlbedo.y), max(0.0, solverAlbedo.z)) : diffuse;
  38. return isValidSolver;
  39. }