纳金网

标题: 汽车喷漆效果的实现原理 [打印本页]

作者: 晃晃    时间: 2011-9-8 08:16
标题: 汽车喷漆效果的实现原理
给汽车身体喷漆是一个复杂的过程,车身油漆是昂贵分层形式,往往包含染料层,搪瓷金属箔悬浮层.

由于这些接二连三油漆表面层,展示出了一种复杂的光学交互,使车看起来平滑,光泽。

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

s***ct 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;



}
此代码所使用的算法,经验更大于真实的物理属性,所以需要不断得调整常数值,

来使最终得到一个满意的效果.


作者: Asen    时间: 2011-9-8 09:24

作者: 奇    时间: 2012-3-30 23:20
都闪开,介个帖子,偶来顶

作者: C.R.CAN    时间: 2012-4-6 23:21
凡系斑竹滴话要听;凡系朋友滴帖要顶

作者: markq    时间: 2012-4-12 22:46
不错 非常经典 实用
作者: 晃晃    时间: 2012-6-26 23:21
不错 非常经典  实用

作者: 奇    时间: 2012-7-23 23:22
我是老实人,我来也!

作者: 驰骋的风    时间: 2012-7-24 09:37
高手速来赐教!kismet里面怎么加一个延迟DELAY??



unity特效大家PP_武功盖世呀








【严重分享】Unity3D_3.0破解版[安装包][下载]






高手请赐教!用模型做的特效动画材质丢失








antares_universe(vizio)可视化编辑

作者: C.R.CAN    时间: 2012-12-4 23:22
我看看就走,你们聊!





欢迎光临 纳金网 (http://rs.narkii.com/club/) Powered by Discuz! X2.5