当前位置: 首页 > 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;反复提示需要…...

【NGINX--2】高性能负载均衡

1、HTTP 负载均衡 将负载分发到两台或多台 HTTP 服务器。 在 NGINX 的 HTTP 模块内使用 upstream 代码块对 HTTP 服务器实施负载均衡&#xff1a; upstream backend {server 10.10.12.45:80 weight1;server app.example.com:80 weight2;server spare.example.com:80 backup; …...

Android studio run 手机或者模拟器安装失败,但是生成了debug.apk

错误信息如下&#xff1a;Error Installation did not succeed. The application could not be installed&#xff1a;List of apks 出现中文乱码&#xff1b; 我首先尝试了打包&#xff0c;能正常安装&#xff0c;再次尝试了debug的安装包&#xff0c;也正常安装&#xff1…...

【面试经典150 | 数学】加一

文章目录 写在前面Tag题目来源解题思路方法一&#xff1a;加一 其他语言python3 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带一些对于本题涉及到的数据结…...

Rust unix domain socket

先用起来再说 use std::io::prelude::*; use std::os::unix::net::UnixStream;fn main() {let mut stream: UnixStream;let mut buffer vec![0u8; 4096];match UnixStream::connect("/tmp/hello.world.serv") {Ok(handle) > {stream handle;match stream.write_…...

初识分布式键值对存储etcd

欢迎大家到我的博客浏览。胤凯 (oyto.github.io)大家好&#xff0c;今天我带大家来学习一下 etcd。 一、什么是 etcd etcd 是一个开源的分布式键值存储系统&#xff0c;主要用于构建分布式系统中那点服务发现、配置管理、分布式锁等场景。它采用 Raft 一致性算法来确保所有节…...

docker swarm集群部署

文章目录 前言一、安装docker1.1 解压1.2 配置docker 存储目录和dns1.3 添加docker.service文件1.4 docker 启动验证 二、docker swarm 集群配置2.1 关闭selinux2.2 设置主机名称并加入/etc/hosts2.3 修改各个服务器名称&#xff08;uname -a 进行验证&#xff09;2.4 初始化sw…...

MySQL进阶_9.事务基础知识

文章目录 第一节、数据库事务概述1.1、基本概念1.2、事务的ACID特性 第二节、如何使用事务 第一节、数据库事务概述 1.1、基本概念 事务 一组逻辑操作单元&#xff0c;使数据从一种状态变换到另一种状态。事务处理的原则 保证所有事务都作为 一个工作单元 来执行&#xff0c;…...

IDEA调用接口超时,但Postman可成功调用接口

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;欢迎加入我们一起学习&#xff01;&#x1f4e2;资源分享&#xff1a;耗时200小时精选的「软件测试」资…...

TableUtilCache:针对CSV表格进行的缓存

TableUtilCache:针对CSV表格进行的缓存 文件结构 首先来看下CSV文件的结构&#xff0c;如下图&#xff1a; 第一行是字段类型&#xff0c;第二行是字段名字&#xff1b;再往下是数据。每个元素之间都是使用逗号分隔。 看一下缓存里面存储所有表数据的字段 如下图&#xff…...

java源码-工程讲解

说明&#xff1a; 源码工程目录讲解部分&#xff0c;讲解过程会让大家对后端源码工程有一个大致的了解&#xff0c;能让大家在此改造&#xff0c;就可以衍生出一些新的功能&#xff0c;需要对java技术深入了解&#xff0c;需要看后续java技术讲解部分&#xff0c;源码也是以前很…...