边缘光实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wodownload2/article/details/89553427

参考网址:https://blog.csdn.net/poem_qianmo/article/details/51764028
代码参考:https://github.com/QianMo/Awesome-Unity-Shader/blob/master/Volume 14 边缘发光Shader(Rim Shader)的两种实现形态/BasicRimShader.shader

之前也写过这个文章,参考:
https://blog.csdn.net/wodownload2/article/details/78934564
https://blog.csdn.net/wodownload2/article/details/79213846
一个是原理,一个是使用surface shader进行实现。
这里再重新回顾下原理,如何判断边缘?我们知道边缘的的法线与边缘点到视点的向量有个夹角。
在边缘的时候,这个夹角很大。可以利用这个夹角的余弦值衡量。余弦值越小,越靠近边缘。注意这里余弦值和夹角是成反比。而我们希望越靠近边缘其越亮。所以使用1-余弦值,作为系数。然后用这个系数与颜色相乘,作为自发光的颜色。

所谓的自发光,就是物体本身有个颜色,将这个颜色和算出来的其他颜色相加就可以了。
这里我们不考虑那么负责,就是用一个采样的颜色+自发光颜色,简单实现表边缘发光效果。

选择计算空间为世界空间。
将法线转换到世界空间:
fixed3 normalDir = normalize(mul(x.normal, (float3x3)unity_WorldToObject));
将模型空间的顶点转换到世界空间:
o.worldPos= mul(unity_ObjectToWorld,v.vertex);
视线的计算,在片段着色器中计算:
float3 viewDirection = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz);

Shader "MyShader/RimShader"
{
	Properties
	{
		_MainTex ("Texture", 2D) = "white" {}
		_RimColor("RimColor",Color)=(1,1,1,1)
		_RimPower("RimPower",Range(0,16))=1
		_RimIntensity("RimIntensity",Range(0,10))=1
	}
	SubShader
	{
		Tags { "RenderType"="Opaque" }
		LOD 100

		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			
			#include "UnityCG.cginc"

			struct appdata
			{
				float4 vertex : POSITION;
				float2 uv : TEXCOORD0;
				float3 normal:NORMAL;
			};

			struct v2f
			{
				float4 vertex : SV_POSITION;
				float2 uv : TEXCOORD0;
				float4 worldPos:TEXCOORD1;
				float3 normal:NORMAL;
			};

			sampler2D _MainTex;
			float4 _MainTex_ST;
			uniform float4 _RimColor;
			uniform float _RimPower;
			uniform float _RimIntensity; 
			
			v2f vert (appdata v)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.uv = TRANSFORM_TEX(v.uv, _MainTex);
				o.worldPos = mul(unity_ObjectToWorld, v.vertex);
				o.normal = normalize(mul(v.normal, (float3x3)unity_WorldToObject));
				return o;
			}
			
			fixed4 frag (v2f i) : SV_Target
			{
				fixed3 col = tex2D(_MainTex, i.uv).rgb;
				float3 viewDirection = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz);
				float3 normalDirection = normalize(i.normal);
				half factor = 1.0 - max(0, dot(i.normal, viewDirection));
				float3 emissive = _RimColor.rgb * pow(factor, _RimPower) *_RimIntensity;
				col += emissive;
				return fixed4(col, 1);
			}
			ENDCG
		}
	}
}

最后实现效果:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/wodownload2/article/details/89553427
今日推荐