Unity制作薄膜干涉效果,色彩斑斓的黑色石头
大家好,我是阿赵。
这次来做一个模拟薄膜干涉的彩色效果,Shader是使用ASE来连接,也算是ASE做复杂一点的效果的一个例子吧。
以下解释来源于百度百科:假设照射一束光波于薄膜,由于折射率不同,光波会被薄膜的上界面与下界面分别反射,因相互干涉而形成新的光波,这现象称为薄膜干涉。
比如这种肥皂泡,在表面,会看到很多彩色的效果,这就是薄膜干涉想效果了。
从原理来说,这个薄膜干涉的效果是通过多次不同折射率反射的光波叠加得到的,如果真的用这个算法去实现,消耗有点大。不过作为游戏里面的美术效果,有很多方法可以模拟的。
首先需要分析一下,薄膜干涉的效果是怎样形成的。
1、由于是薄膜的上下界面分别反射的效果,所以按道理来说,应该有2个环境投影
2、环境投影过来的色彩,经过了叠加置换,形成了五彩斑斓的效果。
知道了这两个效果之后,就可以逐个去模拟了。
如果要真的反射或者折射场景本身的东西作为效果,那样消耗很大。但之前已经多次用过的一种手段,可以帮助我们模拟假反射效果,那就是Matcap了。
所以要实现2个环境投影的效果,实际上我们可以通过添加2张Matcap贴图来叠加实现
想实现多种颜色的叠加,除了真的算出来以外,还有一种更简单的办法,就是我们直接指定一张色彩渐变的图,作为多种色彩的采样图,然后再根据一定的规则去计算UV,就能得到一种假的色彩斑斓的效果。
既然上面已经有了思路,那么下面就比较快的用ASE节点连接一下,实现这种效果。
首先,我们要实现的是整个表面的薄膜干涉:
这里有一个甲虫的模型,赋予上漫反射贴图和法线贴图后的效果是这样:
现在的ASE连线是这样:
首先漫反射贴图和颜色的控制,是基本固定下来了,所以给他注册一个变量
这是基础效果,接下来开始逐个效果加进去,让他形成最终的效果:
虽然是两层Matcap,但Matcap采样的UV是一样的,所以可以先算出Matcap的UV:
为了能有一个变量同时控制2层Matcap的强度,所以先注册了一个变量
接下来很简单,拿刚才算出的UV采样2张Matcap贴图,然后乘以强度控制的变量,最后叠加在一起就行了。
现在我们已经有了Matcap假环境反射效果,所以可以和原来的漫反射颜色叠加,由于法线贴图已经在计算Matcap的时候使用过了,这里其实可以不用再赋予法线贴图给输出:
上面分析原理的时候说过,我们是模拟效果,所以是用一张彩色渐变图来实现的,比如这样:
想达到的效果是通过世界法线方向和观察方向做点乘(NdotV,和做轮廓光的计算一样),然后在作为UV采样彩色渐变图,让这张渐变图有一种跟随这法线方向从中间到四周渐变彩色的效果。
由于是要改变漫反射的颜色,所以把求得的ramVal和漫反射颜色相乘,然后再加上Matcap的颜色:
再根据实际情况调整一下之前Matcap的强度控制值,就能得到效果:
到这一步,这个效果差不多是做完了,可以先看看ASE生成的代码,用ASE打开,可以看看节点的连接情况:
// Made with Amplify Shader Editor
// Available at the Unity Asset Store - http://u3d.as/y3X
Shader "azhao/ThinFilm"
{
Properties
{
_diffuseTex1("_diffuseTex", 2D) = "white" {}
_diffuseCol1("diffuseCol", Color) = (0.5377358,0.5377358,0.5377358,0)
_matCapTex1("_matCapTex", 2D) = "white" {}
_matCap2Tex1("_matCap2Tex", 2D) = "white" {}
_matcapLen1("_matcapLen", Float) = 1
_matcap2Len1("_matcap2Len", Float) = 1
_matcapStr1("matcapStr", Range( 0 , 1)) = 0
[Normal]_normalTex2("_normalTex", 2D) = "bump" {}
_ramTex1("_ramTex", 2D) = "white" {}
_min1("min", Range( 0 , 1)) = 0
_max1("max", Range( 0 , 1)) = 1
[HideInInspector] _texcoord( "", 2D ) = "white" {}
[HideInInspector] __dirty( "", Int ) = 1
}
SubShader
{
Tags{ "RenderType" = "Opaque" "Queue" = "Geometry+0" }
Cull Back
CGINCLUDE
#include "UnityShaderVariables.cginc"
#include "UnityPBSLighting.cginc"
#include "Lighting.cginc"
#pragma target 3.0
#ifdef UNITY_PASS_SHADOWCASTER
#undef INTERNAL_DATA
#undef WorldReflectionVector
#undef WorldNormalVector
#define INTERNAL_DATA half3 internalSurfaceTtoW0; half3 internalSurfaceTtoW1; half3 internalSurfaceTtoW2;
#define WorldReflectionVector(data,normal) reflect (data.worldRefl, half3(dot(data.internalSurfaceTtoW0,normal), dot(data.internalSurfaceTtoW1,normal), dot(data.internalSurfaceTtoW2,normal)))
#define WorldNormalVector(data,normal) half3(dot(data.internalSurfaceTtoW0,normal), dot(data.internalSurfaceTtoW1,normal), dot(data.internalSurfaceTtoW2,normal))
#endif
struct Input
{
float2 uv_texcoord;
float3 worldNormal;
INTERNAL_DATA
float3 worldPos;
};
uniform sampler2D _diffuseTex1;
uniform float4 _diffuseTex1_ST;
uniform float4 _diffuseCol1;
uniform sampler2D _ramTex1;
uniform float _min1;
uniform float _max1;
uniform sampler2D _matCap2Tex1;
uniform sampler2D _normalTex2;
uniform float4 _normalTex2_ST;
uniform float _matcap2Len1;
uniform float _matcapStr1;
uniform sampler2D _matCapTex1;
uniform float _matcapLen1;
void surf( Input i , inout SurfaceOutputStandard o )
{
o.Normal = float3(0,0,1);
float2 uv_diffuseTex1 = i.uv_texcoord * _diffuseTex1_ST.xy + _diffuseTex1_ST.zw;
float4 diffuseCol5 = ( tex2D( _diffuseTex1, uv_diffuseTex1 ) * _diffuseCol1 );
float3 ase_worldNormal = WorldNormalVector( i, float3( 0, 0, 1 ) );
float3 ase_worldPos = i.worldPos;
float3 ase_worldViewDir = normalize( UnityWorldSpaceViewDir( ase_worldPos ) );
float dotResult44 = dot( ase_worldNormal , ase_worldViewDir );
float clampResult48 = clamp( ( 1.0 - dotResult44 ) , _min1 , _max1 );
float2 temp_cast_0 = (clampResult48).xx;
float4 ramVal50 = tex2D( _ramTex1, temp_cast_0 );
float2 uv_normalTex2 = i.uv_texcoord * _normalTex2_ST.xy + _normalTex2_ST.zw;
float2 matcapUV38 = ( ( (mul( float4( (WorldNormalVector( i , UnpackNormal( tex2D( _normalTex2, uv_normalTex2 ) ) )) , 0.0 ), UNITY_MATRIX_V ).xyz).xy + 1.0 ) * 0.5 );
float matcapStrength27 = _matcapStr1;
float4 matcapCol26 = ( ( tex2D( _matCap2Tex1, matcapUV38 ) * ( _matcap2Len1 * matcapStrength27 ) ) + ( tex2D( _matCapTex1, matcapUV38 ) * ( _matcapLen1 * matcapStrength27 ) ) );
o.Albedo = ( ( diffuseCol5 * ramVal50 ) + matcapCol26 ).rgb;
o.Alpha = 1;
}
ENDCG
CGPROGRAM
#pragma surface surf Standard keepalpha fullforwardshadows
ENDCG
Pass
{
Name "ShadowCaster"
Tags{ "LightMode" = "ShadowCaster" }
ZWrite On
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 3.0
#pragma multi_compile_shadowcaster
#pragma multi_compile UNITY_PASS_SHADOWCASTER
#pragma skip_variants FOG_LINEAR FOG_EXP FOG_EXP2
#include "HLSLSupport.cginc"
#if ( SHADER_API_D3D11 || SHADER_API_GLCORE || SHADER_API_GLES || SHADER_API_GLES3 || SHADER_API_METAL || SHADER_API_VULKAN )
#define CAN_SKIP_VPOS
#endif
#include "UnityCG.cginc"
#include "Lighting.cginc"
#include "UnityPBSLighting.cginc"
struct v2f
{
V2F_SHADOW_CASTER;
float2 customPack1 : TEXCOORD1;
float4 tSpace0 : TEXCOORD2;
float4 tSpace1 : TEXCOORD3;
float4 tSpace2 : TEXCOORD4;
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
v2f vert( appdata_full v )
{
v2f o;
UNITY_SETUP_INSTANCE_ID( v );
UNITY_INITIALIZE_OUTPUT( v2f, o );
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO( o );
UNITY_TRANSFER_INSTANCE_ID( v, o );
Input customInputData;
float3 worldPos = mul( unity_ObjectToWorld, v.vertex ).xyz;
half3 worldNormal = UnityObjectToWorldNormal( v.normal );
half3 worldTangent = UnityObjectToWorldDir( v.tangent.xyz );
half tangentSign = v.tangent.w * unity_WorldTransformParams.w;
half3 worldBinormal = cross( worldNormal, worldTangent ) * tangentSign;
o.tSpace0 = float4( worldTangent.x, worldBinormal.x, worldNormal.x, worldPos.x );
o.tSpace1 = float4( worldTangent.y, worldBinormal.y, worldNormal.y, worldPos.y );
o.tSpace2 = float4( worldTangent.z, worldBinormal.z, worldNormal.z, worldPos.z );
o.customPack1.xy = customInputData.uv_texcoord;
o.customPack1.xy = v.texcoord;
TRANSFER_SHADOW_CASTER_NORMALOFFSET( o )
return o;
}
half4 frag( v2f IN
#if !defined( CAN_SKIP_VPOS )
, UNITY_VPOS_TYPE vpos : VPOS
#endif
) : SV_Target
{
UNITY_SETUP_INSTANCE_ID( IN );
Input surfIN;
UNITY_INITIALIZE_OUTPUT( Input, surfIN );
surfIN.uv_texcoord = IN.customPack1.xy;
float3 worldPos = float3( IN.tSpace0.w, IN.tSpace1.w, IN.tSpace2.w );
half3 worldViewDir = normalize( UnityWorldSpaceViewDir( worldPos ) );
surfIN.worldPos = worldPos;
surfIN.worldNormal = float3( IN.tSpace0.z, IN.tSpace1.z, IN.tSpace2.z );
surfIN.internalSurfaceTtoW0 = IN.tSpace0.xyz;
surfIN.internalSurfaceTtoW1 = IN.tSpace1.xyz;
surfIN.internalSurfaceTtoW2 = IN.tSpace2.xyz;
SurfaceOutputStandard o;
UNITY_INITIALIZE_OUTPUT( SurfaceOutputStandard, o )
surf( surfIN, o );
#if defined( CAN_SKIP_VPOS )
float2 vpos = IN.pos;
#endif
SHADOW_CASTER_FRAGMENT( IN )
}
ENDCG
}
}
Fallback "Diffuse"
CustomEditor "ASEMaterialInspector"
}
/*ASEBEGIN
Version=18500
522;578;1920;715;1433.327;283.2714;1.3;True;True
Node;AmplifyShaderEditor.CommentaryNode;11;-2151.8,-962.4486;Inherit;False;1282.428;497.9202;Comment;10;38;37;36;35;34;33;32;31;30;29;matcapUV;1,1,1,1;0;0
Node;AmplifyShaderEditor.SamplerNode;29;-2079.031,-869.7596;Inherit;True;Property;_normalTex2;_normalTex;7;1;[Normal];Create;True;0;0;False;0;False;-1;None;bcace47d828d6584ca2e497db46da532;True;0;True;bump;Auto;True;Object;-1;Auto;Texture2D;8;0;SAMPLER2D;;False;1;FLOAT2;0,0;False;2;FLOAT;0;False;3;FLOAT2;0,0;False;4;FLOAT2;0,0;False;5;FLOAT;1;False;6;FLOAT;0;False;7;SAMPLERSTATE;;False;5;FLOAT3;0;FLOAT;1;FLOAT;2;FLOAT;3;FLOAT;4
Node;AmplifyShaderEditor.WorldNormalVector;30;-1760.862,-891.8605;Inherit;False;False;1;0;FLOAT3;0,0,1;False;4;FLOAT3;0;FLOAT;1;FLOAT;2;FLOAT;3
Node;AmplifyShaderEditor.ViewMatrixNode;31;-1745.651,-711.2565;Inherit;False;0;1;FLOAT4x4;0
Node;AmplifyShaderEditor.SimpleMultiplyOpNode;32;-1552.764,-824.0817;Inherit;False;2;2;0;FLOAT3;0,0,0;False;1;FLOAT4x4;0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1;False;1;FLOAT3;0
Node;AmplifyShaderEditor.SwizzleNode;33;-1415.188,-864.1566;Inherit;False;FLOAT2;0;1;2;3;1;0;FLOAT3;0,0,0;False;1;FLOAT2;0
Node;AmplifyShaderEditor.RangedFloatNode;34;-1523.613,-692.6346;Inherit;False;Constant;_Float1;Float 0;0;0;Create;True;0;0;False;0;False;1;0;0;0;0;1;FLOAT;0
Node;AmplifyShaderEditor.SimpleAddOpNode;36;-1348.294,-741.2067;Inherit;False;2;2;0;FLOAT2;0,0;False;1;FLOAT;0;False;1;FLOAT2;0
Node;AmplifyShaderEditor.CommentaryNode;41;-2055.848,506.4452;Inherit;False;1372.112;427.2333;Comment;9;50;49;48;47;46;45;44;43;42;ramVal;1,1,1,1;0;0
Node;AmplifyShaderEditor.RangedFloatNode;35;-1467.336,-562.9716;Inherit;False;Constant;_Float2;Float 1;0;0;Create;True;0;0;False;0;False;0.5;0;0;0;0;1;FLOAT;0
Node;AmplifyShaderEditor.CommentaryNode;12;-781.2891,-759.7816;Inherit;False;704.9028;218.6006;Comment;2;28;27;matcapStrengthg;1,1,1,1;0;0
Node;AmplifyShaderEditor.SimpleMultiplyOpNode;37;-1265.293,-579.9235;Inherit;False;2;2;0;FLOAT2;0,0;False;1;FLOAT;0;False;1;FLOAT2;0
Node;AmplifyShaderEditor.RangedFloatNode;28;-719.2891,-703.7806;Inherit;False;Property;_matcapStr1;matcapStr;6;0;Create;True;0;0;False;0;False;0;0.117;0;1;0;1;FLOAT;0
Node;AmplifyShaderEditor.ViewDirInputsCoordNode;42;-1985.25,738.8439;Inherit;False;World;False;0;4;FLOAT3;0;FLOAT;1;FLOAT;2;FLOAT;3
Node;AmplifyShaderEditor.WorldNormalVector;43;-1992.847,590.2448;Inherit;False;False;1;0;FLOAT3;0,0,1;False;4;FLOAT3;0;FLOAT;1;FLOAT;2;FLOAT;3
Node;AmplifyShaderEditor.DotProductOpNode;44;-1760.65,647.6448;Inherit;False;2;0;FLOAT3;0,0,0;False;1;FLOAT3;0,0,0;False;1;FLOAT;0
Node;AmplifyShaderEditor.RegisterLocalVarNode;27;-348.5472,-708.1805;Inherit;False;matcapStrength;-1;True;1;0;FLOAT;0;False;1;FLOAT;0
Node;AmplifyShaderEditor.RegisterLocalVarNode;38;-1109.383,-672.5885;Inherit;False;matcapUV;-1;True;1;0;FLOAT2;0,0;False;1;FLOAT2;0
Node;AmplifyShaderEditor.CommentaryNode;13;-2157.141,-259.6156;Inherit;False;1457.371;571.3273;Comment;13;26;25;24;23;22;21;20;19;18;17;16;15;14;MatcapCol;1,1,1,1;0;0
Node;AmplifyShaderEditor.RangedFloatNode;46;-1709.831,754.3938;Inherit;False;Property;_min1;min;9;0;Create;True;0;0;False;0;False;0;0.218;0;1;0;1;FLOAT;0
Node;AmplifyShaderEditor.CommentaryNode;1;-2045.915,-1593.317;Inherit;False;882.3721;436.7761;Comment;4;5;4;3;2;diffuseCol;1,1,1,1;0;0
Node;AmplifyShaderEditor.OneMinusNode;45;-1598.85,653.5448;Inherit;False;1;0;FLOAT;0;False;1;FLOAT;0
Node;AmplifyShaderEditor.RangedFloatNode;15;-1595.132,-141.8086;Inherit;False;Property;_matcap2Len1;_matcap2Len;5;0;Create;True;0;0;False;0;False;1;2.63;0;0;0;1;FLOAT;0
Node;AmplifyShaderEditor.RangedFloatNode;47;-1708.947,855.3768;Inherit;False;Property;_max1;max;10;0;Create;True;0;0;False;0;False;1;0.541;0;1;0;1;FLOAT;0
Node;AmplifyShaderEditor.GetLocalVarNode;24;-1592.537,199.5534;Inherit;False;27;matcapStrength;1;0;OBJECT;;False;1;FLOAT;0
Node;AmplifyShaderEditor.GetLocalVarNode;14;-2109.24,64.27048;Inherit;False;38;matcapUV;1;0;OBJECT;;False;1;FLOAT2;0
Node;AmplifyShaderEditor.GetLocalVarNode;16;-1589.362,-59.90956;Inherit;False;27;matcapStrength;1;0;OBJECT;;False;1;FLOAT;0
Node;AmplifyShaderEditor.RangedFloatNode;23;-1573.821,99.57846;Inherit;False;Property;_matcapLen1;_matcapLen;4;0;Create;True;0;0;False;0;False;1;-0.1;0;0;0;1;FLOAT;0
Node;AmplifyShaderEditor.ColorNode;3;-1927.229,-1344.125;Inherit;False;Property;_diffuseCol1;diffuseCol;1;0;Create;True;0;0;False;0;False;0.5377358,0.5377358,0.5377358,0;1,1,1,0;True;0;5;COLOR;0;FLOAT;1;FLOAT;2;FLOAT;3;FLOAT;4
Node;AmplifyShaderEditor.SamplerNode;17;-1896.613,-208.7635;Inherit;True;Property;_matCap2Tex1;_matCap2Tex;3;0;Create;True;0;0;False;0;False;-1;None;7b6c994ca124f7844933ff29a828e014;True;0;False;white;Auto;False;Object;-1;Auto;Texture2D;8;0;SAMPLER2D;;False;1;FLOAT2;0,0;False;2;FLOAT;0;False;3;FLOAT2;0,0;False;4;FLOAT2;0,0;False;5;FLOAT;1;False;6;FLOAT;0;False;7;SAMPLERSTATE;;False;5;COLOR;0;FLOAT;1;FLOAT;2;FLOAT;3;FLOAT;4
Node;AmplifyShaderEditor.SamplerNode;18;-1916.894,41.37045;Inherit;True;Property;_matCapTex1;_matCapTex;2;0;Create;True;0;0;False;0;False;-1;None;63f4deeba79a05045a23bd4efde60741;True;0;False;white;Auto;False;Object;-1;Auto;Texture2D;8;0;SAMPLER2D;;False;1;FLOAT2;0,0;False;2;FLOAT;0;False;3;FLOAT2;0,0;False;4;FLOAT2;0,0;False;5;FLOAT;1;False;6;FLOAT;0;False;7;SAMPLERSTATE;;False;5;COLOR;0;FLOAT;1;FLOAT;2;FLOAT;3;FLOAT;4
Node;AmplifyShaderEditor.ClampOpNode;48;-1395.935,658.2618;Inherit;False;3;0;FLOAT;0;False;1;FLOAT;0;False;2;FLOAT;1;False;1;FLOAT;0
Node;AmplifyShaderEditor.SimpleMultiplyOpNode;22;-1348.521,129.2014;Inherit;False;2;2;0;FLOAT;0;False;1;FLOAT;0;False;1;FLOAT;0
Node;AmplifyShaderEditor.SimpleMultiplyOpNode;19;-1359.421,-106.9806;Inherit;False;2;2;0;FLOAT;0;False;1;FLOAT;0;False;1;FLOAT;0
Node;AmplifyShaderEditor.SamplerNode;2;-1995.915,-1543.317;Inherit;True;Property;_diffuseTex1;_diffuseTex;0;0;Create;True;0;0;False;0;False;-1;None;dece56f96937a38409c05ec12d763248;True;0;False;white;Auto;False;Object;-1;Auto;Texture2D;8;0;SAMPLER2D;;False;1;FLOAT2;0,0;False;2;FLOAT;0;False;3;FLOAT2;0,0;False;4;FLOAT2;0,0;False;5;FLOAT;1;False;6;FLOAT;0;False;7;SAMPLERSTATE;;False;5;COLOR;0;FLOAT;1;FLOAT;2;FLOAT;3;FLOAT;4
Node;AmplifyShaderEditor.SimpleMultiplyOpNode;21;-1198.078,8.469454;Inherit;False;2;2;0;COLOR;0,0,0,0;False;1;FLOAT;0;False;1;COLOR;0
Node;AmplifyShaderEditor.SamplerNode;49;-1233.468,629.3298;Inherit;True;Property;_ramTex1;_ramTex;8;0;Create;True;0;0;False;0;False;-1;617568684d4604945b0e1e0268720cd6;d41989414fad7d9429737d617855f3f0;True;0;False;white;Auto;False;Object;-1;Auto;Texture2D;8;0;SAMPLER2D;;False;1;FLOAT2;0,0;False;2;FLOAT;0;False;3;FLOAT2;0,0;False;4;FLOAT2;0,0;False;5;FLOAT;1;False;6;FLOAT;0;False;7;SAMPLERSTATE;;False;5;COLOR;0;FLOAT;1;FLOAT;2;FLOAT;3;FLOAT;4
Node;AmplifyShaderEditor.SimpleMultiplyOpNode;20;-1187.935,-175.5155;Inherit;False;2;2;0;COLOR;0,0,0,0;False;1;FLOAT;0;False;1;COLOR;0
Node;AmplifyShaderEditor.SimpleMultiplyOpNode;4;-1604.776,-1450.349;Inherit;False;2;2;0;COLOR;0,0,0,0;False;1;COLOR;0,0,0,0;False;1;COLOR;0
Node;AmplifyShaderEditor.RegisterLocalVarNode;50;-907.7362,642.6719;Inherit;False;ramVal;-1;True;1;0;COLOR;0,0,0,0;False;1;COLOR;0
Node;AmplifyShaderEditor.RegisterLocalVarNode;5;-1388.002,-1447.403;Inherit;False;diffuseCol;-1;True;1;0;COLOR;0,0,0,0;False;1;COLOR;0
Node;AmplifyShaderEditor.SimpleAddOpNode;25;-1044.312,-90.04456;Inherit;False;2;2;0;COLOR;0,0,0,0;False;1;COLOR;0,0,0,0;False;1;COLOR;0
Node;AmplifyShaderEditor.GetLocalVarNode;7;-269.9716,-100.0286;Inherit;False;5;diffuseCol;1;0;OBJECT;;False;1;COLOR;0
Node;AmplifyShaderEditor.GetLocalVarNode;51;-275.8423,19.81351;Inherit;False;50;ramVal;1;0;OBJECT;;False;1;COLOR;0
Node;AmplifyShaderEditor.RegisterLocalVarNode;26;-920.8224,-80.59351;Inherit;False;matcapCol;-1;True;1;0;COLOR;0,0,0,0;False;1;COLOR;0
Node;AmplifyShaderEditor.GetLocalVarNode;40;-237.3033,141.2637;Inherit;False;26;matcapCol;1;0;OBJECT;;False;1;COLOR;0
Node;AmplifyShaderEditor.SimpleMultiplyOpNode;52;-36.84229,-31.18649;Inherit;False;2;2;0;COLOR;0,0,0,0;False;1;COLOR;0,0,0,0;False;1;COLOR;0
Node;AmplifyShaderEditor.SimpleAddOpNode;39;115.6226,21.99689;Inherit;False;2;2;0;COLOR;0,0,0,0;False;1;COLOR;0,0,0,0;False;1;COLOR;0
Node;AmplifyShaderEditor.StandardSurfaceOutputNode;0;263.2036,22.30539;Float;False;True;-1;2;ASEMaterialInspector;0;0;Standard;azhao/ThinFilm;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;Back;0;False;-1;0;False;-1;False;0;False;-1;0;False;-1;False;0;Opaque;0.5;True;True;0;False;Opaque;;Geometry;All;14;all;True;True;True;True;0;False;-1;False;0;False;-1;255;False;-1;255;False;-1;0;False;-1;0;False;-1;0;False;-1;0;False;-1;0;False;-1;0;False;-1;0;False;-1;0;False;-1;False;2;15;10;25;False;0.5;True;0;0;False;-1;0;False;-1;0;0;False;-1;0;False;-1;0;False;-1;0;False;-1;0;False;0;0,0,0,0;VertexOffset;True;False;Cylindrical;False;Relative;0;;-1;-1;-1;-1;0;False;0;0;False;-1;-1;0;False;-1;0;0;0;False;0.1;False;-1;0;False;-1;False;16;0;FLOAT3;0,0,0;False;1;FLOAT3;0,0,0;False;2;FLOAT3;0,0,0;False;3;FLOAT;0;False;4;FLOAT;0;False;5;FLOAT;0;False;6;FLOAT3;0,0,0;False;7;FLOAT3;0,0,0;False;8;FLOAT;0;False;9;FLOAT;0;False;10;FLOAT;0;False;13;FLOAT3;0,0,0;False;11;FLOAT3;0,0,0;False;12;FLOAT3;0,0,0;False;14;FLOAT4;0,0,0,0;False;15;FLOAT3;0,0,0;False;0
WireConnection;30;0;29;0
WireConnection;32;0;30;0
WireConnection;32;1;31;0
WireConnection;33;0;32;0
WireConnection;36;0;33;0
WireConnection;36;1;34;0
WireConnection;37;0;36;0
WireConnection;37;1;35;0
WireConnection;44;0;43;0
WireConnection;44;1;42;0
WireConnection;27;0;28;0
WireConnection;38;0;37;0
WireConnection;45;0;44;0
WireConnection;17;1;14;0
WireConnection;18;1;14;0
WireConnection;48;0;45;0
WireConnection;48;1;46;0
WireConnection;48;2;47;0
WireConnection;22;0;23;0
WireConnection;22;1;24;0
WireConnection;19;0;15;0
WireConnection;19;1;16;0
WireConnection;21;0;18;0
WireConnection;21;1;22;0
WireConnection;49;1;48;0
WireConnection;20;0;17;0
WireConnection;20;1;19;0
WireConnection;4;0;2;0
WireConnection;4;1;3;0
WireConnection;50;0;49;0
WireConnection;5;0;4;0
WireConnection;25;0;20;0
WireConnection;25;1;21;0
WireConnection;26;0;25;0
WireConnection;52;0;7;0
WireConnection;52;1;51;0
WireConnection;39;0;52;0
WireConnection;39;1;40;0
WireConnection;0;0;39;0
ASEEND*/
//CHKSM=0B2FF8580E96CBA9E432244BACE7B0766F17EA8A
刚才做的甲虫,表面算是比较的光滑,整体的出现薄膜干涉也是很正常的。文章开头有一个视频,上面这块金属,是不应该整体出现薄膜干涉的,他只是在高光强烈的地方,产生了色彩斑斓的效果。
这个效果我就不给源码了,大概给一下思路,各位可以自己试试:
1、彩色贴图采样的ramVal不要和漫反射直接相乘,而是先和Matcap的结果相乘,这样就不会在整个模型产生彩色,二只有在Matcap反射强烈的地方产生彩色
2、通过一个参数来控制Matcap和ramVal之间的互补关系
大概的连线是这样的:
这里我是连到Emission里面,这个通道是自发光,所以最后得到的颜色会稍微更亮一些,如果连到漫反射的albedo通道,其实也是可以的,颜色就稍微没那么亮。