zoukankan      html  css  js  c++  java
  • XDRender_ObjPass_ShaderMode_Cloth(2) 布料渲染模型 绒

    XDRender_ObjPass_ShaderMode_Cloth(2) 布料渲染模型 绒

    image-20201111202248360

    ​ 灯芯绒

    image-20201115213047000

    前言


    正文


    绒: 稀疏,交错

    -----------------在掠射角处产生镜面高光

    Sheen-brdf

    基于 Estevez 和 Kulla[Estevez2017]的 Sheen-brdf 闭包,是一个微表面 Sheen-brdf。它模拟了织物的外观,其中表面的面是圆柱形的“纤维”,其轴线平行于表面发现,在掠射角处产生镜面高光。从概念上讲,这位于基础底的顶部,因此传输到基础底层的能量被光泽反射降低

    sheen_layer = sheen * sheen_color * sheen_brdf(...) + (1 - sheen * reflectance(sheen_brdf)) * base_mix
    光泽 _ 层=光泽光泽 _ 颜色光泽 _brdf(…)+(1-光泽反射(光泽 _brdf))基础 _ 混合

    其中基础混合闭包定义如下

    Name 名称 Type 类型 Default 默认值 Description 描述
    sheen*光泽 float 0.8 sheen_brdf反射权重
    sheen_color*光泽颜色 color 1,1,1 sheen_brdf反射颜色
    sheen_roughness*光泽粗糙度 float 0.3 sheen_brdf反射粗糙度, 范围 [0,1]

    简化的模拟

    第一种 gazing

    这里可以参考Unity, 可以提前计算出掠射角的反射率,(半导体)

     half oneMinusReflectivity = OneMinusReflectivityMetallic(metallic);
                half reflectivity = 1.0 - oneMinusReflectivity;
    
                outBRDFData.diffuse = albedo * oneMinusReflectivity;
                outBRDFData.specular = lerp(kDieletricSpec.rgb, albedo, metallic);
            #endif 
            outBRDFData.grazing = saturate(smoothness + reflectivity);
    

    ​ 其中reflectivity:

    ​ 0.04一个电解质最低的F0

    #define kDieletricSpec half4(0.04, 0.04, 0.04, 1.0 - 0.04) 
    half OneMinusReflectivityMetallic(half metallic)
    {
        // We'll need oneMinusReflectivity, so
        //   1-reflectivity = 1-lerp(dielectricSpec, 1, metallic) = lerp(1-dielectricSpec, 0, metallic)
        // store (1-dielectricSpec) in kDieletricSpec.a, then
        //   1-reflectivity = lerp(alpha, 0, metallic) = alpha + metallic*(0 - alpha) =
        //                  = alpha - metallic * alpha
        half oneMinusDielectricSpec = kDieletricSpec.a;
        return oneMinusDielectricSpec - metallic * oneMinusDielectricSpec;
    }
    

    第二种 自定义实现

    属性部分

    ​ 1、我用CustomData的第一分量表示Cloth值(或者Sheen值), 第二个分量表示绒毛扩展度.

    _CustomData("Cloth-SpecFabExtendScale", VECTOR) = (1, 0, 0, 1)
    

    ​ 2、扩散,这一步还是按照上一节的实现. 并且用_SurfaceColor来存储.(由于绒毛我还不需要真实次表面, 就用Wrap来实现

    _SurfaceColor("SurfaceColor", Color) = (0, 0, 0, 1)
    
    实现部分
    1、扩散的计算
    	float FabricScatterSale = saturate(pBRDF.surfacecolorScale);
    float3 FuzzColor =  pBRDF.surfacecolor * LightSurfaceWrap(context.NoL,FabricScatterSale);
     
    float   diffcuseTerm = Diffuse_Burley_Disney(pBRDF.perceptualRoughness,context.NoV,context.NoL,context.VoH);
    float3  diffuseResult = pBRDF.diffuse * diffcuseTerm * lightColor * FuzzColor;//;  
    
    2、高光

    ​ 这里先实现自己的,然后是UE的, DISN的

    ​ 2.1.1 减弱FD的部分,这里直接利用NH来求F

    
    inline float FabricD (float NdotH)
    {
         return 0.96 * pow(1 - NdotH, 2) + 0.057;
    }
    

    ​ 2.2.2 根据Rough来做区分

    float NDF = D_GGX_Smis(pRoughness*pRoughness,pContext.NoH);
        float G   = GeometrySmith(pContext.NoV, pContext.NoL, pRoughness); 
        float VxD= pRoughness > 0.8 ? 1 * FabricD (pContext.NoH) : NDF * G;
    

    ​ 2.2.3 更细碎的绒毛搞起

    //--扩展细碎的绒毛
        float3 specFabExtend = float3(1.0,1.0,1.0);//lerp(0.1,lightColor,pBRDF.roughness);
        specFabExtend *= (context.NoL*0.5 + 0.5) * FabricScatterFresnelLerp(context.NoV, specFabExtendScale);
        specFab += specFabExtend;
    

    ​ 2.2.4 插值高光

    ​ 插值值: 就是前面说到的CustomData.x, 这里也可以在内部多加一个. 但编辑器表现为Cloth

    float clothValue = saturate(pBRDF.customData.x);
    float specFabExtendScale = saturate(pBRDF.customData.y);
    

    
    FDirectLightingResult DirectLightResult;
        DirectLightResult.Diffuse = diffuseResult;
        //--------------就是这里---------
        DirectLightResult.Specular = lerp(specdefault,specFab,clothValue);
        DirectLightResult.Transmission = 0;
    

    第三种 迪斯尼

    当然我们也可以按lum来做

    //迪斯尼BRDF的扩散漫反射和高光
    float3 Cdlin = mon2lin(baseColor);
                    float Cdlum = .3*Cdlin[0] + .6*Cdlin[1]  + .1*Cdlin[2]; // luminance approx.
     
                    float3 Ctint = Cdlum > 0 ? Cdlin/Cdlum : float3(1,1,1); // normalize lum. to isolate hue+sat
                    float3 Cspec0 = lerp(_specular*.08*lerp(float3(1,1,1), Ctint, specularTint), Cdlin, metallic);
                    float3 Csheen = lerp(float3(1,1,1), Ctint, sheenTint);
                    
    // 漫反射多出的sheen
    float3 Fsheen = FH * sheen * Csheen;
    
    // 高光的F项
    float3 Fs = lerp(Cspec0, float3(1,1,1), FH);
    
    //最后的漫反射
    ((1/PI) * lerp(Fd, ss, subsurface)*Cdlin + Fsheen)* (1-metallic)
    //高光
    Gs*Fs*Ds
    

    最后合成下

    #if UEClothSpec
            // Cloth - Asperity Scattering - Inverse Beckmann Layer 
            float3 specFab = FabricSpecularUnreal(pBRDF.specular,pBRDF.roughness,context)* lightColor;
        #elif DisnyClothSpec
            // Cloth - Asperity Scattering - Inverse Beckmann Layer 
            float3 specFab = FabricSpecularDisny(pBRDF.specular,pBRDF.roughness,context)* lightColor;
        #else
            //this is fab do extend
            float3 specFab = FabricSpecularGGX(pBRDF.specular,pBRDF.roughness,context) * lightColor;
        #endif
    

    现实环境

    灯芯绒

    灯芯绒组织采用两组纬纱与一组经纱交织的纬二重组织,地组织有平纹斜纹等。灯芯绒由一组经纱和二组纬纱织成,其中一组纬纱(称地纬)与经纱交织成固结绒毛的地布,另一组纬纱(称绒纬)与经纱交织构成有规律的浮纬,割断后形成绒毛。

    灯芯绒采用纬二重组织织制、再经割绒整理,布面呈灯芯状绒条的织物,又称条绒

    现实环境下的灯芯绒

    image-20201115201422408

    image-20201115201437241

    下面是UNREAL的

    image-20201115204754315

    天鹅绒

    天鹅绒使用桑蚕丝作原料也可用桑蚕丝作经,棉纱作纬交织的地组织上,以桑蚕丝或人造丝起绒圈。织造时每织四根绒线后织入一根起绒杆(细铁丝),织到一定长度时(约20厘米左右),即在机上用割刀沿铁丝剖割,铁丝脱离织物,则成毛绒。此毛绒根据纹样的设计,就能使纹样清晰地显示在缎面上,并有光泽。构成织物的纹样有两种形式,一种是绒花缎地,即漳缎;一种是绒地缎花,即天鹅绒。

    image-20201115201836495

    image-20201115201909097

    总结


    备注

    人生当苦,笑着看看
  • 相关阅读:
    中缀、后缀、前缀表达式
    Salesforce图片上传
    VSCode格式化Apex代码
    Reporting Services已有帐号出现无法登录的问题
    EF-查询缓存
    visual studio 2015将已有项目添加到码云(gitee)
    asp.net页面加载两次的坑
    EF的性能瓶颈
    微信JS-SDK上传多张照片
    Python20-Day02
  • 原文地址:https://www.cnblogs.com/BaiPao-XD/p/13967231.html
Copyright © 2011-2022 走看看