zoukankan      html  css  js  c++  java
  • 汽车喷漆效果的实现

    给汽车身体喷漆是一个复杂的过程,车身油漆是昂贵分层形式,往往包含染料层,搪瓷金属箔悬浮层.
    由于这些接二连三油漆表面层,展示出了一种复杂的光学交互,使车看起来平滑,光泽。


    完整的HLSL像素着色器代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    struct PsInput
    {
          float2 Tex : TEXCOORD0;
          float3 Tangent : TEXCOORD1;
          float3 Binormal : TEXCOORD2;
          float3 Normal : TEXCOORD3;
          float3 View : TEXCOORD4;
          float3 SparkleTex : TEXCOORD5;
    };
     
    float4 main(PsInput i) : COLOR
    {
          // 取得当前的法线图
          float3 vNormal = tex2D( normalMap, i.Tex );
          // 缩放和偏移让其在[-1.0, 1.0]区域内:
          vNormal = 2.0f * vNormal - 1.0f;
     
          // 获得高频率扰动的法线,通过查询一个噪声图。
          float3 vFlakesNormal = tex2D(microflakeNMap, i.SparkleTex);
          // 别忘了转换到 [-1.0, 1.0] 区域内:
          vFlakesNormal = 2 * vFlakesNormal - 1.0;
     
          // 计算以下公式
          // Np1 = ( a * Np + b * N ) / || a * Np + b * N || where a << b
          //
          float3 vNp1 = microflakePerturbationA * vFlakesNormal + normalPerturbation * vNormal ;
     
          // 计算以下公式
          // Np2 = ( c * Np + d * N ) / || c * Np + d * N || where c == d
          float3 vNp2 = microflakePerturbation * ( vFlakesNormal + vNormal ) ;
     
          // 因为需要与法线点乘求夹角,所以我们必须将它归一化一下
          float3 vView = normalize( View );
     
          // 把表面法线转换好世界空间中来,计算bump map的方法。
          float3x3 mTangentToWorld = transpose( float3x3( Tangent, Binormal, Normal ) );
          float3 vNormalWorld = normalize( mul( mTangentToWorld, vNormal ));
     
          // 计算夹角余玄
          float fNdotV = saturate(dot( vNormalWorld, vView));
     
          // 计算出反射向量
          float3 vReflection = 2 * vNormalWorld * fNdotV - vView;
     
          // 我们需要一个gloss值来读环境图,在真实的demo中,反射效果会有轻微的模糊。
          float fEnvBias = glossLevel;
     
          // 用反射向量采样环境图。
          float4 envMap = texCUBEbias( showroomMap, float4( vReflection, fEnvBias ) );
     
          //乘以亮度值,在a通道中储存 RGBE
          envMap.rgb = envMap.rgb * envMap.a;
     
          // 再乘以一个亮度系数
          envMap.rgb *= brightnessFactor;
     
          // 将切线空间中的法线变换到世界坐标中来.
          float3 vNp1World = normalize( mul( mTangentToWorld, vNp1) );
     
          // 法线和视线点乘,得到斐涅尔系数
          float fFresnel1 = saturate( dot( vNp1World, vView ));
     
          // 将第二个法线也同样重切线空间中变换到世界坐标中来.
          float3 vNp2World = normalize( mul( mTangentToWorld, vNp2 ));
     
          // 同样的方法得到第二个斐涅尔系数.
          float fFresnel2 = saturate( dot( vNp2World, vView ));
     
          // 开始合成所有层了.
          // 根据公式三
          float fFresnel1Sq = fFresnel1 * fFresnel1;
          float4 paintColor = fFresnel1 * paintColor0 +
          fFresnel1Sq * paintColorMid +
          fFresnel1Sq * fFresnel1Sq * paintColor2 +
          pow( fFresnel2, 16 ) * flakeLayerColor;
     
          // 最后与反射的环境贴图合成在一起,形成最终的结果.
          float fEnvContribution = 1.0 - 0.5 * fNdotV;
          float4 finalColor;
          finalColor.a = 1.0;
          finalColor.rgb = envMap * fEnvContribution + paintColor;
          return finalColor;
    }

    结论
    此代码所使用的算法,经验更大于真实的物理属性,所以需要不断得调整常数值,
    来使最终得到一个满意的效果.

  • 相关阅读:
    JBoss中配置虚拟目录以及设置浏览器地址输入框支持中文的方法
    实现表格鼠标经过变色,点击变色并选中项目
    JBoss4.0与金山词霸有端口冲突
    Hibernate查询方式比较
    数字证书使用Javascript在浏览器中自动安装的解决方案
    JBoss设置URI编码,使浏览器URL支持中文
    VC++中list的使用方式
    使用JBoss管理数据库连接的方法(JDNI方式)
    CefSharp中实现Chrome中jS导出Excel
    WP7备注(27)(DependencyProperty|RoutedPropertyChangedEventHandler)
  • 原文地址:https://www.cnblogs.com/android-blogs/p/6038499.html
Copyright © 2011-2022 走看看