Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

Question BRDF model doubts

Discussion in 'General Graphics' started by MatheusMarkies, May 30, 2021.

  1. MatheusMarkies

    MatheusMarkies

    Joined:
    Apr 16, 2017
    Posts:
    67
    Good evening! Need help. I am developing a BSDF model. However the results are not so good.
    Can anyone tell me where I'm going wrong?
    My model:
    fdssgdsffg.png

    Another model:
    params_core_2021x.png

    My model code:
    Code (CSharp):
    1.  
    2. #ifndef BSSRDF_INCLUDED
    3. #define BSSRDF_INCLUDED
    4.  
    5. struct BRDF {
    6.     float3 diffuse;
    7.     float3 specular;
    8.     float perceptualRoughness;
    9.     float roughness;
    10.     float fresnel;
    11. };
    12.  
    13. #define MIN_REFLECTIVITY 0.04
    14.  
    15. #define MEDIUMP_FLT_MAX    65504.0
    16. #define saturateMediump(x) min(x, MEDIUMP_FLT_MAX)
    17.  
    18. float OneMinusReflectivity (float metallic) {
    19.     float range = 1.0 - MIN_REFLECTIVITY;
    20.     return range - metallic * range;
    21. }
    22.  
    23. BRDF GetBRDF (Surface surface) {
    24.     BRDF brdf;
    25.     float oneMinusReflectivity = OneMinusReflectivity(surface.metallic);
    26.  
    27.     brdf.diffuse = surface.color * oneMinusReflectivity;
    28.     brdf.specular = lerp(MIN_REFLECTIVITY, surface.color, surface.metallic);
    29.  
    30.     brdf.perceptualRoughness = max(PerceptualSmoothnessToPerceptualRoughness(surface.smoothness),0.01);
    31.     brdf.roughness = PerceptualRoughnessToRoughness(brdf.perceptualRoughness);
    32.     brdf.fresnel = saturate(surface.smoothness + 1.0 - oneMinusReflectivity);
    33.     return brdf;
    34. }
    35.  
    36. BRDF GetBRDF(Surface surface, bool PremultiplyAlpha) {
    37.     BRDF brdf;
    38.     float oneMinusReflectivity = OneMinusReflectivity(surface.metallic);
    39.  
    40.     brdf.diffuse = surface.color * oneMinusReflectivity * surface.alpha;
    41.     brdf.specular = lerp(MIN_REFLECTIVITY, surface.color, surface.metallic);
    42.    
    43.     brdf.perceptualRoughness = PerceptualSmoothnessToPerceptualRoughness(surface.smoothness);
    44.     brdf.roughness = PerceptualRoughnessToRoughness(brdf.perceptualRoughness);
    45.     brdf.fresnel = saturate(surface.smoothness + 1.0 - oneMinusReflectivity);
    46.     return brdf;
    47. }
    48. float IORtoF0(float ior) {
    49.     return ((ior - 1) * (ior - 1)) / ((ior + 1) * (ior + 1));
    50. }
    51. //GGX
    52. float SpecularStrength(Surface surface, BRDF brdf,float3 L,float3 V,float3 N,float3 H) {
    53.     float3 h = H;
    54.     float NoH = dot(N, h);
    55.     float3 NxH = cross(N, h);
    56.     float a = NoH * brdf.roughness;
    57.     float k = brdf.roughness / (dot(NxH, NxH) + a * a);
    58.     float d = k * k * (1.0 / PI);
    59.     return saturateMediump(d);
    60. }
    61.  
    62. float3 shiftTangent(float3 T, float3 N, float shift)
    63. {
    64.     return normalize((T + shift)*N);
    65. }
    66.  
    67. float3 irradianceOclusion(float3 n) {
    68. return unity_SHAr + unity_SHAg * (n.y) + unity_SHAb * (n.z) + unity_SHBr * (n.x) + unity_SHBg * (n.y * n.x) + unity_SHBb * (n.y * n.z) + unity_SHC * (3.0 * n.z * n.z - 1.0);
    69. }
    70.  
    71. float schlickWeight(float cosTheta) {
    72.     float m = clamp(1.0 - cosTheta, 0.0, 1.0);
    73.     return (m * m) * (m * m) * m;
    74. }
    75.  
    76. float3 Subsurface(float NoL, float NoV, float LoH, float roughness, Surface surface) {
    77.  
    78.     float FL = schlickWeight(NoL), FV = schlickWeight(NoV);
    79.     float Fss90 = LoH * LoH * roughness;
    80.     float Fss = lerp(1.0, Fss90, FL) * lerp(1.0, Fss90, FV);
    81.     float ss = 1.25 * (Fss * (1.0 / (NoL + NoV) - 0.5) + 0.5);
    82.  
    83.     return ss * surface.subSurfaceColor;
    84. }
    85.  
    86. float SpecularStrengthAnisotropy(Surface surface, BRDF brdf, Light light) {
    87.     float at = max(brdf.roughness * (1.0 + surface.anisotropic), 0.005);
    88.     float ab = max(brdf.roughness * (1.0 - surface.anisotropic), 0.005);
    89.  
    90.     float3 h = SafeNormalize(light.direction + surface.viewDirection);
    91.     float NoH = sqrt(1 - dot(normalize(surface.normal), h) * dot(normalize(surface.normal), h));
    92.  
    93.     float ToH = dot(shiftTangent(normalize(surface.tangent), normalize(surface.normal), 0.1), h);
    94.  
    95.     float3 b = normalize(cross(normalize(surface.normal), surface.tangent));//normalize(cross(surface.normal, surface.tangent.xyz) * surface.tangent.w);
    96.  
    97.     float BoH = dot(b, h);
    98.     float a2 = at * ab;
    99.     float3 v = float3(ab * ToH, at * BoH, a2 * NoH);
    100.     float v2 = dot(v, v);
    101.     float w2 = a2 / v2;
    102.     return a2 * w2 * w2 * (1.0 / PI);
    103. }
    104.  
    105. float3 OrenNayar( float3 l,float3 n,  float3 v, float r, Surface surface)
    106. {
    107.     float r2 = r * r;
    108.     float a = 1.0 - 0.5 * (r2 / (r2 + 0.57));
    109.     float b = 0.45 * (r2 / (r2 + 0.09));
    110.  
    111.     float nl = dot(n, l);
    112.     float nv = dot(n, v);
    113.  
    114.     float ga = dot(v - n * nv, n - n * nl);
    115.  
    116.     return max(0.0, nl) * (a + b * max(0.0, ga) * sqrt((1.0 - nv * nv) * (1.0 - nl * nl)) / max(nl, nv)) * surface.color;
    117. }
    118.  
    119. float FresnelTransmissionBRDF(float f0, float f90, float u)
    120. {
    121. //energyCompensation = 1.0 + NoL * (1.0 / (1.1 - brdf.roughness) - 1.0);
    122.     float x = 1.0 - u;
    123.     float x2 = x * x;
    124.     float x5 = x * x2 * x2;
    125.     return (1.0 - f90 * x5) - f0 * (1.0 - x5);
    126.  
    127. //float f90 = 0.5 + (brdf.perceptualRoughness + brdf.perceptualRoughness * LoV);
    128.  
    129. }
    130.  
    131. float FresnelBRDF(Surface surface) {
    132.     float NoV = dot(surface.normal, surface.viewDirection);
    133.     float f = pow(1.0 - NoV, 4.0);
    134.     return f * 0.5 + NoV * (1.0 - f) * surface.metallic;
    135. }
    136.  
    137. float FresnelSchlick(float f0, float f90, float u)
    138. {
    139.     float x = 1.0 - u;
    140.     float x2 = x * x;
    141.     float x5 = x * x2 * x2;
    142.     return (f90 - f0) * x5 + f0;
    143. }
    144.  
    145. float3 Sheen(float LdotH, Surface material) {
    146.     float FH = schlickWeight(LdotH);
    147.     float Cdlum = .3 * material.color.r + .6 * material.color.g + .1 * material.color.b;
    148.  
    149.     float3 Ctint = material.color / Cdlum;
    150.     float3 Csheen = lerp(float3(1,1,1), Ctint, material.sheenTint);
    151.     float3 Fsheen = FH * material.sheen * Csheen;
    152.     return FH * material.sheen * Csheen;
    153. }
    154.  
    155. float3 CharlieD(float roughness, float ndoth, Surface material)
    156. {
    157.     float Cdlum = .3 * material.color.r + .6 * material.color.g + .1 * material.color.b;
    158.     float3 Ctint = material.color / Cdlum;
    159.     float3 Csheen = lerp(float3(1, 1, 1), Ctint, material.sheenTint);
    160.  
    161.     float invR = 1. / roughness;
    162.     float cos2h = ndoth * ndoth;
    163.     float sin2h = 1. - cos2h;
    164.  
    165.     return (2. + invR) * pow(sin2h, invR * .5) / (2. * PI) * Csheen;
    166. }
    167.  
    168. float AshikhminV(float ndotv, float ndotl)
    169. {
    170.     return 1. / (4. * (ndotl + ndotv - ndotl * ndotv));
    171. }
    172.  
    173. float3 DirectBSSRDF (Surface surface, BRDF brdf, Light light,float ior) {
    174.  
    175.     float NoL = dot(surface.normal, light.direction);
    176.  
    177.     float3 energyCompensation = 1.0 + NoL * (1.0 / (1.1-brdf.roughness) - 1.0);
    178.  
    179.     float3 h = SafeNormalize(light.direction + surface.viewDirection);
    180.     float LoH = dot(light.direction, h);
    181.     float LoV = dot(light.direction, surface.viewDirection);
    182.     float NoH = dot(surface.normal, h);
    183.     float NoV = dot(surface.normal, surface.viewDirection);
    184.  
    185.     float f90 = 0.5 + (brdf.perceptualRoughness + brdf.perceptualRoughness * LoV);
    186.  
    187.     float D = 0;
    188.     if (surface.anisotropic == 0)
    189.         D = SpecularStrength(surface, brdf, light.direction, surface.viewDirection, surface.normal, SafeNormalize(light.direction + surface.viewDirection)) * FresnelTransmissionBRDF(IORtoF0(ior), f90, dot(h, surface.viewDirection));
    190.     else
    191.         D = SpecularStrengthAnisotropy(surface, brdf, light) * FresnelTransmissionBRDF(IORtoF0(ior), f90, dot(h, surface.viewDirection));
    192.  
    193.     D = lerp(D, CharlieD(brdf.roughness, NoH, surface), surface.sheen) * (surface.metallic);
    194.  
    195.     float3 l = light.direction + 2 * surface.normal * (-light.direction * surface.normal);
    196.     D += surface.transmission * SpecularStrength(surface, brdf, l, surface.viewDirection, surface.normal, SafeNormalize(l + surface.viewDirection)) * (1-FresnelTransmissionBRDF(IORtoF0(ior), f90, dot(h, surface.viewDirection)));
    197.  
    198.     D += FresnelSchlick(IORtoF0(ior), f90, dot(h, surface.viewDirection));
    199.  
    200.     return (D +
    201. (lerp(OrenNayar(light.direction, surface.normal, surface.viewDirection, brdf.roughness, surface), Subsurface( NoL,  NoV,  LoH, brdf.roughness, surface),surface.subsurface)) * (1. - surface.metallic))
    202. * AshikhminV(NoV, NoL);
    203.     //return disneyDiffuse( NoV, NoL, LoH, brdf.roughness) * brdf.diffuse;
    204.     //return disneyDiffuse( NoL, NoV, LoH, brdf.roughness, surface);
    205. }
    206. float3 IndirectBRDF(Surface surface, BRDF brdf, float3 diffuse, float3 specular, float ior) {
    207.  
    208.     float3 reflection = specular * lerp(brdf.specular, brdf.fresnel, IORtoF0(ior));
    209.     reflection /= brdf.roughness * brdf.roughness + 1.0;
    210.  
    211.     return (diffuse + reflection) * surface.color * surface.occlusion;
    212. }
    213.  
    214. #endif
    215.