Unity Shader·几个科幻风小练习

review

之前测试选了FUI的题,复习一下相关内容,记录一下思路防止面试断片儿…

FUI

这次测试点亮了AE技能点…做帧动画还是很方便的,网络素材贼多,不过导出序列图片合并成spritesheet用的是额外的工具-GlueIT,略麻烦。

素材合集↓

Hologram

效果图↓(Dominator赛高 (๑•̀ㅂ•́)و✧)

代码

shader代码

Shader "Lapu/Holo" {
	Properties{

		//[Toggle(Display)] _enableDisplay("Display Mode", Float) = 0	//enable scan

		[HDR]_TintColor("Base Color", Color) = (0,0.5,1,1)
		[HDR]_RimColor("Rim Color", Color) = (0,1,1,1)
		[HDR]_FillColor("Fill Color", Color) = (0,0.5,1,1)
		_MainTex("Main Texture", 2D) = "white" {}
		_GlitchTime("Glitches Over Time", Range(0.01,300.0)) = 1.0
		_LineAmount("Line Amount", Range(1,200)) = 20
		_LineWidth("Line Width", Range(0,1)) = 0.5
		_LinesGlow("Line Brightness", Range(-1,2)) = 0.5
		_GlitchSegment("Glitch Segment Width", Range(0.01,30)) = 0.2
		_Speed("Speed", Range(-10 , 10)) = 4.5
		//_Amount("Amount", Range(-1, 1)) = 0.0
	}

		Category{
		Tags{"RenderType" = "Transparent" "Queue" = "Transparent"}

		SubShader{

		Pass{
			Cull Off 
			AlphaToMask On
			CGPROGRAM

	#pragma vertex vert
	#pragma fragment frag
	#pragma target 4.5

	#pragma shader_feature GRID

	#include "UnityCG.cginc"

	sampler2D _MainTex;
	fixed4 _TintColor, _FillColor;
	fixed4 _RimColor;


	struct appdata_t {
		float4 vertex : POSITION;
		float4 color : COLOR;
		float2 texcoord : TEXCOORD0;
		float3 normal : NORMAL; // vertex normal
	};

	struct v2f {
		float4 vertex : SV_POSITION;
		float4 color : COLOR;
		float2 texcoord : TEXCOORD0;
		float3 projPos : TEXCOORD2;
		float3 wpos : TEXCOORD1; // worldposition
		float3 normalDir : TEXCOORD3; // normal direction for rimlighting
	};

	float4 _MainTex_ST;
	float _GlitchTime;
	float _LineAmount;
	float _OptTime = 0;
	float _LineWidth;
	float _GlitchSegment;
	float _LinesGlow;
	float _Speed;
	float _Amount;

	v2f vert(appdata_t v)
	{
		v2f o;

		o.vertex = UnityObjectToClipPos(v.vertex);
		o.projPos = ComputeScreenPos(o.vertex);

		// Vertex glitching
		_OptTime = _OptTime == 0 ? sin(_Time.w * _GlitchTime) : _OptTime;// optimisation
		float glitchtime = step(0.99, _OptTime); // returns 1 when sine is near top, otherwise returns 0;
		float glitchPos = v.vertex.y + _SinTime.y;// position on model
		float glitchPosClamped = step(0, glitchPos) * step(glitchPos, _GlitchSegment);// clamped segment of model
		
		o.vertex.xz += glitchPosClamped * 0.1 * glitchtime * _SinTime.y;// moving the vertices when glitchtime returns 1;
		o.color = v.color;
		o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex);
		o.wpos = mul(unity_ObjectToWorld, v.vertex).xyz;
		o.normalDir = normalize(mul(float4(v.normal, 0.0), unity_WorldToObject).xyz);

		return o;
	}

	fixed4 frag(v2f i, fixed facing : VFACE) : SV_Target
	{
		float4 tex = tex2D(_MainTex, i.texcoord) * _TintColor;// texture
		float3 viewDirection = _WorldSpaceCameraPos.xyz - i.wpos.xyz;// view
		float rim = 1.0 - saturate(dot(normalize(viewDirection), i.normalDir));// add rim light

		// small scanlines down
		float fraclines = frac((i.wpos.y * _LineAmount) + _Time.y * _Speed);//small lines 
		float scanlines = step(fraclines, _LineWidth);// cut off based on 0.5

		fixed4 col = tex + (scanlines * _TintColor) * _LinesGlow + _RimColor * rim;// end result color 
		col.a = 0.8 * (scanlines + rim);
//#if Display...bug
//		return step(i.wpos.y - _Amount * 4, 0) * (facing > 0 ? col : _FillColor);//add vface color
//#else
		return (facing > 0 ? col : _FillColor);//add vface color
//#endif
	}
		ENDCG
	}
	}
		}
}

流光

用hologram魔改的代码,效果还蛮好…而且有点万金油(啊这

shader代码

Shader "Lapu/Scan"
{
	Properties
	{
		
		[Toggle(ScanMode)] _enableScanMode("Scan Mode", Float) = 0	//enable scan
		//[Toggle(WorldPosMode)] _enableWorldPos("World Pos", Float) = 0	//TODO: enable worldpos texture

		[Header(Texture Setting)]
		_Diffuse("Diffuse Texture", 2D) = "white" {}
		_HighLitTexture("High Lit Texture", 2D) = "white" {}
		_Color("Main Color", Color) = (1,1,1,0)
		[HDR]_Highcolor("Highcolor", Color) = (1.018156,2.249626,3.924528,1)
		_Opacity("Opacity", Range(0 , 1)) = 1
		_NoiseScale("Noise Scale", Range(0 , 10)) = 1

		[Header(Scane Setting)]
		_Width("Width", Range(0 , 30)) = 8.15
		_Speed("Speed", Range(-10 , 10)) = 4.5
		_Rotation("Rotation", Range(0 , 15)) = 0.85	//TODO: rotation

		[Header(Cut Off Setting)]
		_Cutoff("Cutoff Value",Range(-10,10)) = 1.1

		_HorizonIntensity("Horizon Intensity",  Range(0, 100)) = 3.3
		_HorizonHeight("Horizon Height", Range(-10,10)) = 10
		
		[HideInInspector] _texcoord2("", 2D) = "white" {}
		[HideInInspector] _texcoord("", 2D) = "white" {}
	}

		SubShader
		{
			Tags{ "RenderType" = "Transparent" "Queue" = "Transparent" }
			ZWrite Off
			Blend SrcAlpha OneMinusSrcAlpha
			CGPROGRAM

			#pragma target 4.6
			#pragma surface surf Lambert alpha 

			#pragma shader_feature ScanMode

			struct Input
			{
				float2 uv_texcoord;
				float2 uv2_texcoord2;
				float3 worldPos;// built in value to use the world space position
				float3 worldNormal; // world normal built-in value
			};

			float4 _Color, _Highcolor;
			sampler2D _Diffuse, _HighLitTexture;
			float4 _Diffuse_ST, _HighLitTexture_ST;
			float _Rotation, _Speed, _Width;
			float _Opacity, _Cutoff, _HorizonHeight, _HorizonIntensity, _NoiseScale;
		
			void surf(Input i, inout SurfaceOutput  o)
			{
				float3 blendNormal = saturate(pow(i.worldNormal * 1.4, 4));

				// normal noise triplanar for x, y, z sides
				float3 xn = tex2D(_HighLitTexture, i.worldPos.zy * _NoiseScale * 0.1);
				float3 yn = tex2D(_HighLitTexture, i.worldPos.zx * _NoiseScale * 0.1);
				float3 zn = tex2D(_HighLitTexture, i.worldPos.xy * _NoiseScale * 0.1);

				float3 noisetexture = zn;
				noisetexture = lerp(noisetexture, xn, blendNormal.x);
				noisetexture = lerp(noisetexture, yn, blendNormal.y);

				//rotation
				float Rot = _Rotation * (3.1415926f / 180.0f);
				float s = sin(Rot);
				float c = cos(Rot);

				//texture 
				float2 uv_Diffuse = i.uv_texcoord * _Diffuse_ST.xy + _Diffuse_ST.zw;
				float2 uv_HighLitTexture = (i.uv2_texcoord2 * _HighLitTexture_ST.xy + _HighLitTexture_ST.zw) * fixed2(s,c);

				float4 maincolor = tex2D(_Diffuse, uv_Diffuse);
				float4 highlitcolor = tex2D(_HighLitTexture, uv_HighLitTexture);
#if ScanMode
				float lerpvalue = lerp(uv_HighLitTexture.x, uv_HighLitTexture.y, _Rotation);
#else
				float lerpvalue = 1;
#endif
				float4 final = clamp(_Highcolor * pow(sin(noisetexture.r * lerpvalue + _Speed * _Time.y), exp(10.0 - _Width)), float4(0, 0, 0, 0), float4(1, 1, 1, 1));

				o.Albedo = (maincolor * _Color).rgb;
				o.Emission = final.rgb;
				o.Alpha = final.a * _Opacity;
			}

			ENDCG
		}
			Fallback "Diffuse"
}

Wireframe效果

Geometry Shader,看这篇

Scifi显示屏效果

应该是amplifid shader editor做的,大致思路是根据color ID分三类——静止部分、竖直移动部分、横向条纹动画,很有趣,效果非常好。外加屏幕distort效果。

代码

Shader "Lapu/HoloMonitor"
{
	Properties
	{
		_Emission("Emission", 2D) = "white" {}
		_Texture0("Texture 0", 2D) = "black" {}
		_Specular("Specular", Range(0 , 1)) = 0.5
		_Smoothness("Smoothness", Range(0 , 1)) = 0.5
		_Color1("Color 1", Color) = (1,1,1,0)
		_Background("Background", Color) = (0,0,0,0)
		_AlbedoPower("Albedo Power", Range(0 , 1)) = 0
		_EmissionPower("Emission Power", Range(0 , 1)) = 0
		_Distort("Distort", Range(0 , 1)) = 0.35
		[HideInInspector] _texcoord("", 2D) = "white" {}
		[HideInInspector] __dirty("", Int) = 1
	}

		SubShader
		{
			Tags{ "RenderType" = "Opaque"  "Queue" = "Geometry+0" "IsEmissive" = "true"  }
			Cull Back
			ZTest LEqual
			CGPROGRAM
			#include "UnityShaderVariables.cginc"
			#pragma target 3.0
			#pragma surface surf StandardSpecular keepalpha addshadow fullforwardshadows 
			struct Input
			{
				float2 uv_texcoord;
			};

			uniform float4 _Background;
			uniform float4 _Color1;
			uniform sampler2D _Texture0;
			uniform sampler2D _Emission;
			uniform float _Distort;
			uniform float _AlbedoPower;
			uniform float _EmissionPower;
			uniform float _Specular;
			uniform float _Smoothness;

			void surf(Input i , inout SurfaceOutputStandardSpecular o)
			{
				float2 panner337 = (_Time.y * float2(0,0.5) + i.uv_texcoord);
				float2 panner360 = (1.0 * _Time.y * float2(7,9) + i.uv_texcoord);
				float temp_output_362_0 = (_Time.w * 20.0);
				float clampResult372 = clamp((sin((temp_output_362_0 * 0.7)) + sin(temp_output_362_0) + sin((temp_output_362_0 * 1.3)) + sin((temp_output_362_0 * 2.5))) , 0.0 , 1.0);
				float2 temp_output_361_0 = (i.uv_texcoord + ((tex2D(_Texture0, panner360).b * clampResult372) * _Distort));
				float4 tex2DNode308 = tex2D(_Emission, temp_output_361_0);
				float2 panner312 = (_Time.y * float2(0,0.2) + temp_output_361_0);
				float2 panner331 = (_Time.y * float2(-0.2,0) + temp_output_361_0);
				float temp_output_343_0 = (_Time.y * 20.0);
				float clampResult349 = clamp((sin((temp_output_343_0 * 0.7)) + sin(temp_output_343_0) + sin((temp_output_343_0 * 1.3)) + sin((temp_output_343_0 * 2.5))) , 0.7 , 1.0);
				float4 lerpResult335 = lerp(_Background , _Color1 , ((tex2D(_Texture0, panner337).r + (((tex2DNode308.g * tex2D(_Emission, panner312).a) + (tex2DNode308.b * tex2D(_Emission, panner331).a)) + tex2DNode308.r)) + (0.0 + ((clampResult349 * tex2D(_Texture0, i.uv_texcoord).g) - 0.0) * (0.5 - 0.0) / (1.0 - 0.0))));
				o.Albedo = (lerpResult335 * _AlbedoPower).rgb;
				o.Emission = (lerpResult335 * _EmissionPower).rgb;
				float3 temp_cast_2 = (_Specular).xxx;
				o.Specular = temp_cast_2;
				o.Smoothness = _Smoothness;
				o.Alpha = 1;
			}

			ENDCG
		}
			Fallback "Diffuse"
}