unity 卡通动物 shader 包含边缘光,ramp,描边

unity 卡通动物 shader 包含边缘光,ramp,描边
在这里插入图片描述
在这里插入图片描述
上shader

Shader "Unlit/TestShader"
{
	    Properties {
        _Diff ("Diff", 2D) = "white" {}
        _MainColor ("MainColor", Color) = (0,0,0,1) //模型主颜色
		_RAMP ("RAMP", 2D) = "white" {}
        _Light ("Light", Vector) = (0,0,0,0)
		_InSideRimColor ("InSideRimColor", Color) = (1,1,1,1)//内边缘光颜色
		_InSideRimPower("InSideRimPower", Range(0.0,5)) = 0 //边缘光强度  ,这个值可以控制菲涅尔影响范围的大小,这个值越大,效果上越边缘化
		_InSideRimIntensity("InSideRimIntensity", Range(0.0, 10)) = 0  //边缘光强度系数 这个值是反射的强度, 值越大,返回的强度越大,导致边缘的颜色不那么明显  
		//描边
		_Outline_Width ("Outline_Width", Float ) = 1
        _Outline_Color ("Outline_Color", Color) = (0.5,0.5,0.5,1)
	    _Outline_Offset_X ("Outline_Offset_X", Float) = 0
		_Outline_Offset_Y ("Outline_Offset_Y", Float) = 0

		 _GradHeight ("GradHeight",float) =1
		 _GradColor ("GradColor", Color) = (0.125,0.125,0.125,1)
    }
    SubShader {
        Tags {
            "RenderType"="Opaque"
        }
		LOD 100
        Pass {
            Name "ForwardBase"
            Tags {
                "LightMode"="ForwardBase" "Queue" = "Geometry"
            }
            
            Fog {Mode Off}
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            //#include "AutoLight.cginc"
	        //#include "Lighting.cginc"
            #pragma multi_compile_fwdbase_fullshadows
            #pragma exclude_renderers xbox360 ps3 flash d3d11_9x 
            #pragma target 2.0
            uniform sampler2D _Diff; uniform float4 _Diff_ST;
            uniform float4 _MainColor;
			uniform sampler2D _RAMP; uniform float4 _RAMP_ST;
			uniform float4 _Light;
			uniform float4 _InSideRimColor;
			uniform float  _InSideRimPower;
			uniform float _InSideRimIntensity;  
			uniform fixed4 _GradColor;
			uniform half _GradHeight;
			uniform float _Outline_Offset_X;
			uniform float _Outline_Offset_Y;
            struct VertexInput {
                float4 vertex : POSITION;
				float2 uv : TEXCOORD0;
				float3 normal : NORMAL;
            };
            struct VertexOutput {
                float2 uv : TEXCOORD0;
				float3 normal : TEXCOORD1;
				float4 vertex : SV_POSITION;
				float4 vertexWorld : TEXCOORD2;
				half grad:TEXCOORD3;
            };
            VertexOutput vert (VertexInput v) {
                VertexOutput o = (VertexOutput)0;
				o.normal = mul(unity_ObjectToWorld, float4(v.normal,0)).xyz;
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.vertexWorld = mul(unity_ObjectToWorld, v.vertex);
				o.uv = v.uv;
				o.grad = mul(unity_ObjectToWorld, v.vertex).y;
				return o;
            }
            fixed4 frag(VertexOutput i) : COLOR {
                i.normal = normalize(i.normal);//下面计算方式套用菲涅尔计算
				float3 worldViewDir = normalize(_WorldSpaceCameraPos.xyz - i.vertexWorld.xyz);//获取单位视角方向   相机世界空间位置减去顶点世界空间位置
				half NdotV = max(0, dot(i.normal, worldViewDir));//计算法线方向和视角方向点积,约靠近边缘夹角越大,值约小,那就是会越在圆球中间约亮,越边缘约暗
				NdotV = 1.0-NdotV;//这里需求是越边缘约亮,所以需要反一下,这里用1 减下
				float fresnel =pow(NdotV,_InSideRimPower)*_InSideRimIntensity;//使用上面的属性参数,这里不多说
			    float3  Emissive=_InSideRimColor.rgb*fresnel; //配置上属性里面的内边缘光颜色

				float4 _Diff_var = tex2D(_Diff,TRANSFORM_TEX(i.uv, _Diff));	
				float4 FinalCompOut = _Diff_var*_MainColor;

				//float RampUV_var = max(0,dot(_Light.rgb,i.normal));
				float RampUV_var = max(0,dot(mul( unity_WorldToObject, float4(_Light.rgb,0) ).xyz,i.normal));
                float2 RampUV = float2(RampUV_var,RampUV_var);
                float4 _RAMP_var = tex2D(_RAMP,TRANSFORM_TEX(RampUV, _RAMP));
				FinalCompOut.rgb*=_RAMP_var.rgb;

				FinalCompOut.rgb = FinalCompOut.rgb+Emissive;//最后加在本体主颜色就即可
				FinalCompOut.xyz = lerp(_GradColor.xyz*FinalCompOut.xyz,FinalCompOut.xyz,clamp(i.grad,0,_GradHeight)/_GradHeight);
				return FinalCompOut;
            }
            ENDCG
        }
	    Pass {
            Name "Outline"
            Tags {
			 "Queue" = "Transparent"
            }
            Cull Front
            ZWrite Off
			Offset [_Outline_Offset_X], [_Outline_Offset_Y]
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #pragma exclude_renderers xbox360 ps3 flash d3d11_9x 
            #pragma target 3.0
			//描边
			uniform float _Outline_Width;
            uniform float4 _Outline_Color;
           struct VertexInput {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
            };
            struct VertexOutput {
                float4 pos : SV_POSITION;
            };
            VertexOutput vert (VertexInput v) {
                VertexOutput o = (VertexOutput)0;
				o.pos = UnityObjectToClipPos(v.vertex);
				float3 norm   = mul ((float3x3)UNITY_MATRIX_IT_MV, v.normal);
				float2 offset = TransformViewToProjection(norm.xy);
 
				o.pos.xy += offset * o.pos.z * _Outline_Width;
                return o;
            }
			float4 frag(VertexOutput i, float facing : VFACE) : SV_Target{
                return _Outline_Color;

            }
            ENDCG
        }
    }
    FallBack "Diffuse"
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
对于Unity中的描边效果,可以使用Shader来实现。下面是一个简单的描边Shader示例: 首先,创建一个新的Shader文件,并将其命名为"OutlineGlowShader"(或其他你喜欢的名称)。然后,将以下代码粘贴到Shader文件中: ```csharp Shader "Custom/OutlineGlowShader" { Properties { _MainTex ("Base Texture", 2D) = "white" {} } SubShader { Tags { "Queue"="Transparent" "RenderType"="Transparent" } LOD 200 CGPROGRAM #pragma surface surf Lambert sampler2D _MainTex; fixed4 _Color; struct Input { float2 uv_MainTex; }; void surf (Input IN, inout SurfaceOutput o) { o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb; o.Emission = _Color.rgb; // 设置发颜色 // 描边效果 float3 normal = UnpackNormal(tex2D(_MainTex, IN.uv_MainTex)); float rim = 1.0 - dot(normal, float3(0, 0, -1)); // 调整描边的强度 o.Emission += rim * _Color.rgb; // 将描边颜色叠加到发颜色上 } ENDCG } FallBack "Diffuse" } ``` 上述代码中,我们定义了一个名为`OutlineGlowShader`的自定义Shader。该Shader有一个名为`_MainTex`的纹理属性,用于接收基本纹理。在`surf`函数中,我们使用`tex2D`函数获取基本纹理的颜色,并将其设置为表面的Albedo(漫反射)属性。然后,我们使用`_Color`变量作为发颜色,并将其设置为表面的Emission(发)属性。 为了实现描边效果,我们首先获取基本纹理的法线,并计算法线与视线方向的点积。然后,我们使用该点积来计算描边的强度(通过`1.0 - dot(normal, float3(0, 0, -1))`)。最后,我们将描边颜色叠加到发颜色上,以达到描边的效果。 请注意,这只是一个简单的示例,你可以根据自己的需求进行调整和扩展。将此Shader应用到你的材质上,然后在Unity中预览效果。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值