当前位置: 首页 > news >正文

Unity模拟薄膜干涉效果

Unity制作薄膜干涉效果,色彩斑斓的黑色石头

  大家好,我是阿赵。
  这次来做一个模拟薄膜干涉的彩色效果,Shader是使用ASE来连接,也算是ASE做复杂一点的效果的一个例子吧。

一、什么是薄膜干涉

  以下解释来源于百度百科:假设照射一束光波于薄膜,由于折射率不同,光波会被薄膜的上界面与下界面分别反射,因相互干涉而形成新的光波,这现象称为薄膜干涉。
  比如这种肥皂泡,在表面,会看到很多彩色的效果,这就是薄膜干涉想效果了。
在这里插入图片描述

二、模拟薄膜干涉效果的思路

  从原理来说,这个薄膜干涉的效果是通过多次不同折射率反射的光波叠加得到的,如果真的用这个算法去实现,消耗有点大。不过作为游戏里面的美术效果,有很多方法可以模拟的。
  首先需要分析一下,薄膜干涉的效果是怎样形成的。
1、由于是薄膜的上下界面分别反射的效果,所以按道理来说,应该有2个环境投影
2、环境投影过来的色彩,经过了叠加置换,形成了五彩斑斓的效果。
  知道了这两个效果之后,就可以逐个去模拟了。

1、先看第一个效果,2个环境投影。

  如果要真的反射或者折射场景本身的东西作为效果,那样消耗很大。但之前已经多次用过的一种手段,可以帮助我们模拟假反射效果,那就是Matcap了。
所以要实现2个环境投影的效果,实际上我们可以通过添加2张Matcap贴图来叠加实现

2、色彩斑斓的效果

  想实现多种颜色的叠加,除了真的算出来以外,还有一种更简单的办法,就是我们直接指定一张色彩渐变的图,作为多种色彩的采样图,然后再根据一定的规则去计算UV,就能得到一种假的色彩斑斓的效果。

三、在Unity里面实现模拟薄膜干涉

  既然上面已经有了思路,那么下面就比较快的用ASE节点连接一下,实现这种效果。
  首先,我们要实现的是整个表面的薄膜干涉:
  这里有一个甲虫的模型,赋予上漫反射贴图和法线贴图后的效果是这样:
在这里插入图片描述

  现在的ASE连线是这样:
  首先漫反射贴图和颜色的控制,是基本固定下来了,所以给他注册一个变量
在这里插入图片描述

  然后简单的把漫反射颜色和法线贴图连接一下给输出
在这里插入图片描述

  这是基础效果,接下来开始逐个效果加进去,让他形成最终的效果:
在这里插入图片描述

1、2层Matcap效果的实现:

  虽然是两层Matcap,但Matcap采样的UV是一样的,所以可以先算出Matcap的UV:
在这里插入图片描述

  为了能有一个变量同时控制2层Matcap的强度,所以先注册了一个变量
在这里插入图片描述

  接下来很简单,拿刚才算出的UV采样2张Matcap贴图,然后乘以强度控制的变量,最后叠加在一起就行了。
在这里插入图片描述

  现在我们已经有了Matcap假环境反射效果,所以可以和原来的漫反射颜色叠加,由于法线贴图已经在计算Matcap的时候使用过了,这里其实可以不用再赋予法线贴图给输出:
在这里插入图片描述

  现在甲虫的效果是这样的:
在这里插入图片描述

  现在反射了2种环境:
在这里插入图片描述

2、做色彩斑斓的效果

  上面分析原理的时候说过,我们是模拟效果,所以是用一张彩色渐变图来实现的,比如这样:
在这里插入图片描述

  接下来,通过特殊的UV计算,对这张彩色渐变图进行采样:
在这里插入图片描述

  想达到的效果是通过世界法线方向和观察方向做点乘(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 BackCGINCLUDE#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))#endifstruct Input{float2 uv_texcoord;float3 worldNormal;INTERNAL_DATAfloat3 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;}ENDCGCGPROGRAM#pragma surface surf Standard keepalpha fullforwardshadows ENDCGPass{Name "ShadowCaster"Tags{ "LightMode" = "ShadowCaster" }ZWrite OnCGPROGRAM#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_IDUNITY_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;#endifSHADOW_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

3、表面凹凸的材质薄膜干涉

在这里插入图片描述

  刚才做的甲虫,表面算是比较的光滑,整体的出现薄膜干涉也是很正常的。文章开头有一个视频,上面这块金属,是不应该整体出现薄膜干涉的,他只是在高光强烈的地方,产生了色彩斑斓的效果。
  这个效果我就不给源码了,大概给一下思路,各位可以自己试试:
1、彩色贴图采样的ramVal不要和漫反射直接相乘,而是先和Matcap的结果相乘,这样就不会在整个模型产生彩色,二只有在Matcap反射强烈的地方产生彩色
2、通过一个参数来控制Matcap和ramVal之间的互补关系
大概的连线是这样的:
在这里插入图片描述

  这里我是连到Emission里面,这个通道是自发光,所以最后得到的颜色会稍微更亮一些,如果连到漫反射的albedo通道,其实也是可以的,颜色就稍微没那么亮。

相关文章:

Unity模拟薄膜干涉效果

Unity制作薄膜干涉效果,色彩斑斓的黑色石头 大家好,我是阿赵。   这次来做一个模拟薄膜干涉的彩色效果,Shader是使用ASE来连接,也算是ASE做复杂一点的效果的一个例子吧。 一、什么是薄膜干涉 以下解释来源于百度百科&#xff1…...

AIGC ChatGPT4对Gbase数据库进行总结

ChatGPT4 用一个Prompt完成Gbase数据库的总结。 AIGC ChatGPT 职场案例 AI 绘画 与 短视频制作 PowerBI 商业智能 68集 数据库Mysql 8.0 54集 数据库Oracle 21C 142集 Office 2021实战应用 Python 数据分析实战, ETL Informatica 数据仓库案例实战 Excel 2021实操 …...

OSI网络模型与TCP/IP协议

OSI, Open system Interconnection Reference Model 开放式系统互联通信参考模型。是国际标准化组织在1984年定义的一个概念框架,用于协调制定进程间通信标准。OSI作为一个协议规范集,定义了七个层次,包括层次之间的相互关系及各层…...

C语言的5个内存段你了解吗?( 代码段/数据段/栈/堆)

前言:这些内存段在程序运行时起着不同的作用,有不同的分配方式和存储内容。对于 C 语言程序员来说,了解这些内存段的特性和用途有助于更好地理解内存管理、变量的存储位置以及程序执行过程中的内存分配情况 1. 代码段 (Code Segment) 内容&a…...

智能合约检测:新一代区块链技术的安全守护

目录 1、智能合约检测:新一代区块链技术的安全守护 2、智能合约性能检测步骤...

Flutter笔记:缩放手势

Flutter笔记 缩放手势 作者:李俊才 (jcLee95):https://blog.csdn.net/qq_28550263 邮箱 :291148484163.com 本文地址:https://blog.csdn.net/qq_28550263/article/details/134485138 目 录 1. 概述2. 缩放手…...

JAXB:用XmlElement注解复杂类型的Java属性,来产生多层嵌套的xml元素

例如&#xff0c;下面这段请求的xml代码&#xff0c;在元素body下面又多了一层&#xff0c;嵌套了4个元素&#xff1a; <?xml version"1.0" encoding"UTF-8"?><request><reqtype>04</reqtype><secret>test</secret>…...

万字长文 - Python 日志记录器logging 百科全书 - 高级配置之 日志分层

万字长文 - Python 日志记录器logging 百科全书 - 高级配置之 日志分层 前言 在 Python 的logging模块中&#xff0c;它不仅提供了基础的日志功能&#xff0c;还拥有一系列高级配置选项来满足复杂应用的日志管理需求。 说到logging 模块的高级配置&#xff0c;必须提及日志分…...

工作记录---为什么双11当天不能申请退款?(有趣~)

为什么&#xff1f; 服务降级了 服务降级&#xff1a; 当服务器压力剧增的情况下&#xff0c;根据实际业务情况及流量&#xff0c;对一些服务和页面有策略的不处理或换种简单的方式处理&#xff0c;从而释放服务器资源以保证核心交易正常运作或高效运作。 分布式系统的降级…...

ElasticSearch在Windows上的下载与安装

Elasticsearch是一个开源的分布式搜索和分析引擎&#xff0c;它可以帮助我们快速地搜索、分析和处理大量数据。Elasticsearch能够快速地处理结构化和非结构化数据&#xff0c;支持全文检索、地理位置搜索、自动补全、聚合分析等功能&#xff0c;能够承载各种类型的应用&#xf…...

软件测试/测试开发/人工智能丨基于Spark的分布式造数工具:加速大规模测试数据构建

随着软件开发规模的扩大&#xff0c;测试数据的构建变得越来越复杂&#xff0c;传统的造数方法难以应对大规模数据需求。本文将介绍如何使用Apache Spark构建分布式造数工具&#xff0c;以提升测试数据构建的效率和规模。 为什么选择Spark&#xff1f; 分布式计算&#xff1a;…...

ClickHouse的 MaterializeMySQL引擎

1 概述 MySQL 的用户群体很大&#xff0c;为了能够增强数据的实时性&#xff0c;很多解决方案会利用 binlog 将数据写入到 ClickHouse。为了能够监听 binlog 事件&#xff0c;我们需要用到类似 canal 这样的第三方中间件&#xff0c;这无疑增加了系统的复杂度。 ClickHouse 20.…...

Ubuntu 22.04安装Rust编译环境并且测试

我参考的博客是《Rust使用国内Crates 源、 rustup源 |字节跳动新的 Rust 镜像源以及安装rust》 lsb_release -r看到操作系统版本是22.04,uname -r看到内核版本是uname -r。 sudo apt install -y gcc先安装gcc&#xff0c;要是结果给我的一样的话&#xff0c;那么就是安装好了…...

制作Go程序的Docker容器(以及容器和主机的网络问题)

今天突然遇到需要将 Go 程序制作成 Docker 的需求&#xff0c;所以进行了一些研究。方法很简单&#xff0c;但是官方文档和教程有些需要注意的地方&#xff0c;所以写本文进行记录。 源程序 首先介绍一下示例程序&#xff0c;示例程序是一个 HTTP 服务器&#xff0c;会显示si…...

mysql清除数据痕迹_MySQL使用痕迹清理~/.mysql_history - milantgh

mysql会给出我们最近执行的SQL命令和脚本&#xff1b;同linux command保存在~/.bash_history一样&#xff0c;你用mysql连接MySQL server的所有操作也会被记录到~/.mysql_history文件中&#xff0c;这样就会有很大的安全风险了&#xff0c;如添加MySQL用户的sql也同样会被明文记…...

PDF控件Spire.PDF for .NET【转换】演示:自定义宽度、高度将 PDF 转 SVG

我们在上一篇文章中演示了如何将 PDF 页面转换为 SVG 文件格式。本指南向您展示如何使用最新版本的 Spire.PDF 以及 C# 和 VB.NET 指定输出文件的宽度和高度。 Spire.Doc 是一款专门对 Word 文档进行操作的 类库。在于帮助开发人员无需安装 Microsoft Word情况下&#xff0c;轻…...

01背包 P1507 NASA的食物计划

P1507 NASA的食物计划 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 普通01背包状态表示&#xff1a;f(i, j)表示前i件物品放入一个容量为j的背包可以获得的最大价值。 本题类似&#xff0c;f(i, j, k)表示前i件物品放入一个限制为j&#xff0c;且另一个限制为k的背包中可以…...

平衡二叉树c语言版

一、定义二叉树结点结构体 /*** 定义平衡二叉树结点 */ struct avlbinarytree { //数据域NodeData* data;///树高int h;struct avlbinarytree* left;struct avlbinarytree* right; }; typedef struct avlbinarytree AVLNode; 二、声明函数的操作 /*** 创建结点 */ AV…...

初始环境配置

目录 一、JDK1、简介2、配置步骤 二、Redis1、简介2、配置步骤 三、MySQL1、简介2、配置步骤 四、Git1、简介2、配置步骤 五、NodeJS1、简介2、配置步骤 六、Maven1、简介2、配置步骤 七、Tomcat1、简介2、配置步骤 一、JDK 1、简介 JDK 是 Oracle 提供的 Java 开发工具包&…...

记GitLab服务器迁移后SSH访问无法生效的问题解决过程

公司IT心血来潮对GitLab服务器进行安全升级&#xff0c;升级后无法启动。。。只得启用备用服务器&#xff0c;具体的备份机制不祥&#xff0c;只知道原数据都在&#xff0c;但文件系统是否完全一样不清楚。切换为备用服务器后使用SSH下载代码死活不成功&#xff0c;反复提示需要…...

生成 Git SSH 证书

&#x1f511; 1. ​​生成 SSH 密钥对​​ 在终端&#xff08;Windows 使用 Git Bash&#xff0c;Mac/Linux 使用 Terminal&#xff09;执行命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" ​​参数说明​​&#xff1a; -t rsa&#x…...

MODBUS TCP转CANopen 技术赋能高效协同作业

在现代工业自动化领域&#xff0c;MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步&#xff0c;这两种通讯协议也正在被逐步融合&#xff0c;形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

Spring Boot面试题精选汇总

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

Android15默认授权浮窗权限

我们经常有那种需求&#xff0c;客户需要定制的apk集成在ROM中&#xff0c;并且默认授予其【显示在其他应用的上层】权限&#xff0c;也就是我们常说的浮窗权限&#xff0c;那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

IT供电系统绝缘监测及故障定位解决方案

随着新能源的快速发展&#xff0c;光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域&#xff0c;IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选&#xff0c;但在长期运行中&#xff0c;例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...

【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具

第2章 虚拟机性能监控&#xff0c;故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令&#xff1a;jps [options] [hostid] 功能&#xff1a;本地虚拟机进程显示进程ID&#xff08;与ps相同&#xff09;&#xff0c;可同时显示主类&#x…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念&#xff0c;其实 Fiori当中还有 V4&#xff0c;咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务)&#xff0c;代理中间件&#xff08;ui5-middleware-simpleproxy&#xff09;-CSDN博客…...