我的shader学习之一

写一个边缘发光shader,我想到如下内容。首先可能是有纹理的,那么我就要在物体的边缘对其颜色做一个修正,这个物体的边缘跟物体应该是无关的,而跟摄像机方向有关

那么在什么情况下会出现某个计算在物体中心颜色为0or很少颜色,在边缘颜色很深呢。

在边缘法线与该点到摄像机的夹角应该是超过90的,在中心位置这个夹角是0,那么我就需要一个从0到90+角度值增大的函数

ret smoothstep(e1, e2, e3)

unity的smoothstep是一个从e1到e2插值函数,用这个函数,我们要控制e3,如果e3在e1一下那么结果就是0,在e2以上就是1,在e1,e2之间就是插值

我们取法线和视角view方向的点乘,这个值是这样的,边缘可能略微大于120度

放一个简图

除此之外要控制一下e1和e2的数值

Shader "Custom/test4" {
	Properties{
		_MainTex ("Base (RGB)", 2D) = "white"{}    //这个没啥好说的,其实用不到纹理
		_Color("Main Color", Color) = (1,1,1,1)        //白光
		_RimColor("Rim Color", Color) = (1,1,1,1)    
		_RimWidth("Rim Width", float) = 0.9        //这个东西是拿来控制插值函数的起点的,如果这个值大,那麽显示成黄色的区域(即描边)会变大
		}
	SubShader{
		Pass{
			Lighting Off
			CGPROGRAM
			#pragma vertex vert //顶点着色器
			#pragma fragment frag //片段着色器
			#include "UnityCG.cginc"
			
			struct appdata
			{
				float4 vertex: POSITION;
				float3 normal:NORMAL;			
				float2 texcoord:TEXCOORD0;
			};
			
			struct v2f
			{
				float4 pos:SV_POSITION;
				float2 uv:TEXCOORD0;
				fixed3 color :COLOR;
			};
			
			uniform float4 _MainTex_ST;
			uniform fixed4 _RimColor;
			float _RimWidth;
			
			v2f vert (appdata_base v)
			{
				v2f o;
				o.pos = UnityObjectToClipPos(v.vertex);		//获得照相机空间坐标
				float3 viewDir = normalize(ObjSpaceViewDir(v.vertex));		
				//ObjSpaceViewDir这个函数输入一个模型空间的顶点位置,返回模型空间中从该点到摄像机的观察方向即 view方向
				
				float dotProduct = 1 - dot(v.normal, viewDir);			//这里算颜色,采用的是法线和视角的点乘是一个0-1的数值,中心区域的值比较大,等于这个dotProduct在中心位置比较小
				//我们想一下,在正中央的这个结果是什么,一个单位向量而且是正向的z,会得到一个结果就是0
				
				o.color = smoothstep(1 - _RimWidth,1.0, dotProduct); //这里的smoothstep,是一个平滑过渡函数, 对于1- RimWidth以下都是0,从1-RimWidth 到1逐渐增加到1, dotProduct控制平滑的参数,对于RimWidth大的情况,dotProduct在比较小的值的时候都不是0,dotProduct比较小的时候意味着是中心,即dot(v.normal, viewDir)比较大
				//那么对于dotProduct为0的中心点,这个值就是1
				o.color *= _RimColor;给它变个色,这个值在边缘比较大,中心小
				
				o.uv = v.texcoord.xy;
				return o;
			}
			
			uniform sampler2D _MainTex;
			uniform fixed4 _Color;
			
			fixed4 frag(v2f i):COLOR{
				//fixed4 texcol = tex2D(_MainTex, i.uv);			//纹理取样 没有纹理就是白光1111
				//texcol *= _Color;					
				fixed4 texcol = (1,1,1,1);
				texcol *= _Color;				//变成MainColor
				texcol.rgb += i.color;				//在这个上面叠加颜色
				return texcol;
			}
		ENDCG
		}
	}

	FallBack "Diffuse"
}

 

这里需要明确的是,RimWidth表示了描边的起点半径,而从这点开始到1是一个渐变过程,在边缘的部分描边颜色最明显

这里面的重点是在顶点着色器中计算颜色,核心是球面与view正对的点的法线与view方向的标准向量点积是最小的,边缘部分是最大的

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值