网格渲染、流光、模型切割集合

                                   UnityShader之网格渲染、流光、模型切割

shader的东西虽然接触的已经有一些时间了,但是一直都没有系统的学过,都是自己看到哪学到哪,有时看见有趣的例子也会记录下来,便于以后查阅,今天记录一个几种效果集合的shader例子


首先,大家都知道在untiy scene场景中有一种渲染模式为wireframe,此种模式下模型为纯网格展示,非常有科技感的赶脚


于是想着实现一下,不过后来是在网上看到的例子,这里记录一下 #pragma geometry g

Geometry Shader是继Vertex Shader和Fragment Shader之后,由Shader Model 4(第四代显卡着色架构)正式引入的第三个着色器。  性能差因为不像 V和F那样高度并行.

 
Geometry Shader 是vertex和pixel之间的一个optional的stage.
V的功能是处理顶点,G是处理图元,最后光栅化后传给F. 通俗理解:G是用来处理三角形的
V的输出 传给 G 作为输入,G 处理完成后,G的输出 传给 F作为输入
G输出的是最后的齐次裁剪空间,也就是经过mvp。

还有就是加了流光和模型切割,直接贴上代码好了

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Custom/Wireframe" 
{
	Properties 
	{
		_MainTex("texture",2D)="white"{}
		_Color("Color", Color) = (1,1,1,1)
		_DiffuseScale("diffuse",Range(0,1))=0.1

		_WireColor("WireColor", Color) = (1,0,0,1)

		_Speed("Flash_Speed", Float) = 1.0  
		_Angle("Flash_Angle",Range(-1.57,1.57)) = 0.78  
		_Length("Flash_Length",Float) = 0.3
        _FlashColor("flash",Color)=(1,1,1,1)  


		_ClipLineY("clipy",Float) = 10
		_ClipLine_Y("clip_y",Float)=-10
		_ClipLine_X("clip_x",Float) = 10
        _ClipLineX("clipx",Float)=-10
		_ClipLine_Z("clip_z",Float)=10
        _ClipLineZ("clipz",Float)=-10
        _CutTex("CutTexture",2D) = "white"{}
		_CutColor("cutcolor",color)=(1,1,1,1)
		_Sensity("Sens",Float) = 1

	}
	SubShader 
	{

	   PASS{

		//blend srcalpha oneminussrcalpha
		//zwrite on
	    Cull FRONT
		CGPROGRAM
		// Physically based Standard lighting model, and enable shadows on all light types
		#pragma vertex vert

		// Use shader model 3.0 target, to get nicer looking lighting
		#pragma fragment frag
		#include "UnityCG.cginc"
		#include "lighting.cginc"

		float4 _CutColor;
		sampler2D _CutTex;
		// sampler2D unity_Lightmap;
		float4 _CutTex_ST;
		 // float4 unity_LightmapST;
		float _ClipLineY;
		float _ClipLineX;
		float _ClipLineZ;
		float _ClipLine_X;
		float _ClipLine_Y;
		float _ClipLine_Z;
		float _Sensity;


		struct v2f{
		   float4 pos:POSITION;
		   float4 vertex:COLOR;
		   float2 uv:TEXCOORD0;
		   };

		   v2f vert(appdata_base v)
		   {
		       v2f o;
		       o.pos = UnityObjectToClipPos(v.vertex);
			   o.vertex = v.vertex;
		       o.uv = TRANSFORM_TEX(v.texcoord,_CutTex);
		       return o;
		   }

		   fixed4 frag (v2f IN):COLOR
		   {
		     fixed4 col =tex2D(_CutTex,IN.uv)*_CutColor;
			 float4 tpos = mul(unity_ObjectToWorld, IN.vertex);



			 if (tpos.x < _ClipLineX*_Sensity||tpos.x>_ClipLine_X*_Sensity)
			 {
				 discard;
			 }

			 if (tpos.y > _ClipLineY*_Sensity||tpos.y<_ClipLine_Y*_Sensity)
			 {
				 discard;
			 }

			 if (tpos.z < _ClipLineZ*_Sensity||tpos.z>_ClipLine_Z*_Sensity) {
				 discard;
			 }
		     return col;		 		     
		   }

	
		ENDCG
		}

    	Pass 
    	{
    		Cull Back
			CGPROGRAM
			#include "UnityCG.cginc"
			#pragma target 5.0
			#pragma vertex vert
			#pragma geometry geom
			#pragma fragment frag
		
			
			half4 _WireColor, _Color;
			sampler2D _MainTex;
			float _DiffuseScale;

			float _Speed;
			float _Angle;
			float _Length;
			fixed4 _FlashColor;


			float4 _CutColor;
			sampler2D _CutTex;
			// sampler2D unity_Lightmap;
			float4 _CutTex_ST;
			 // float4 unity_LightmapST;
			float _ClipLineY;
			float _ClipLineX;
			float _ClipLineZ;
			float _ClipLine_X;
			float _ClipLine_Y;
			float _ClipLine_Z;
			float _Sensity;

			struct v2g 
			{
    			float4  pos : SV_POSITION;
    			float2  uv : TEXCOORD0;
    			float4  vert:COLOR;
			};
			
			struct g2f 
			{
    			float4  pos : SV_POSITION;
    			float2  uv : TEXCOORD0;
    			float3 dist : TEXCOORD1;
    			float4 vert:COLOR;
			};

			v2g vert(appdata_base v)
			{
    			v2g OUT;
    			OUT.pos = UnityObjectToClipPos(v.vertex);
    			OUT.uv = v.texcoord; //the uv's arent used in this shader but are included in case you want to use them
    			OUT.vert=v.vertex;
    			return OUT;
			}

			//网格渲染部分
			[maxvertexcount(3)]
			void geom(triangle v2g IN[3], inout TriangleStream<g2f> triStream)
			{
			
				float2 WIN_SCALE = float2(_ScreenParams.x/2.0, _ScreenParams.y/2.0);
				
				//frag position
				float2 p0 = WIN_SCALE * IN[0].pos.xy / IN[0].pos.w;
				float2 p1 = WIN_SCALE * IN[1].pos.xy / IN[1].pos.w;
				float2 p2 = WIN_SCALE * IN[2].pos.xy / IN[2].pos.w;
				
				//barycentric position
				float2 v0 = p2-p1;
				float2 v1 = p2-p0;
				float2 v2 = p1-p0;
				//triangles area
				float area = abs(v1.x*v2.y - v1.y * v2.x);
			
				g2f OUT;
				OUT.pos = IN[0].pos;
				OUT.uv = IN[0].uv;
				OUT.dist = float3(area/length(v0),0,0);
				OUT.vert = IN[0].vert;
				triStream.Append(OUT);

				OUT.pos = IN[1].pos;
				OUT.uv = IN[1].uv;
				OUT.dist = float3(0,area/length(v1),0);
				OUT.vert = IN[1].vert;
				triStream.Append(OUT);

				OUT.pos = IN[2].pos;
				OUT.uv = IN[2].uv;
				OUT.dist = float3(0,0,area/length(v2));
				OUT.vert = IN[2].vert;
				triStream.Append(OUT);
				
			}
			
			half4 frag(g2f IN) : COLOR
			{
			float4 tpos = mul(unity_ObjectToWorld, IN.vert);
			 if (tpos.x < _ClipLineX*_Sensity||tpos.x>_ClipLine_X*_Sensity)
			 {
				 discard;
			 }

			 if (tpos.y > _ClipLineY*_Sensity||tpos.y<_ClipLine_Y*_Sensity)
			 {
				 discard;
			 }

			 if (tpos.z < _ClipLineZ*_Sensity||tpos.z>_ClipLine_Z*_Sensity) {
				 discard;
			 }
			     
				//distance of frag from triangles center
				float d = min(IN.dist.x, min(IN.dist.y, IN.dist.z));
				//float d = min(IN.dist.x,max(IN.dist.y,IN.dist.z)*IN.dist.w);
				//fade based on dist from center
 				float I = exp2(-4.0*d*d);
 				float4 col = lerp(tex2D(_MainTex,IN.uv)+_Color*_DiffuseScale,_WireColor,I);

 				//流光部分
				float size = 1.f + abs(tan(_Angle));//在Y轴投影最大值/  
				if (_Length < 0.f)  
				_Length = 0.f;//宽度最低为0/  
				if (_Length > size)  
				_Length = size;  
				float bottom = fmod(_Time.y*_Speed, size);//取余,实现循环播放/  
				if (_Angle < 0.f)  
				bottom += tan(_Angle);//角度为负时需要将运动起始点向下移动tan(_Angle)的距离/  
				if (_Speed < 0.f)  
				bottom = size + bottom;  
				float top = bottom + _Length *(_Speed / abs(_Speed));//top为运动方向上的上方/  
				float alpha = min(1.f, abs(((bottom + top) / 2.f - IN.uv.x*tan(_Angle)) - IN.uv.y) / (_Length/2.f));//根据该点距离闪光中心的距离设定alpha/  
				col.rgb = lerp(_FlashColor.rgb, col.rgb, alpha);//alpha越高,说明距离闪光中心越远,取值越接近原像素颜色/  
 				return col;				
			}
			
			ENDCG

    	}
	}
}

最后是效果图


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值