ue3dUnity实现网格轮廓URP卡通描边效果

Unity实现网格轮廓URP卡通描边效果

分类:

Shader Graph 期望主节点中顶点输入的对象空间,在幕后将其转换为剪辑空间。所以如果你想用 ClipSpace 做一个效果,必须手动转换成 ClipSpace,转换回 Object Space ,然后 Shader Graph 再转换成 ClipSpace 。

ue3d - Unity实现网格轮廓URP卡通描边效果

你会在剪辑空间中创建网格的副本,然后使用法线扩展 x 和 y 使其更大。然后将 z 从相机推开,使其始终呈现在后面。

如果打开 噪波 选项,它将添加投影到顶点数据上的纹理结果,以获得更卡通的轮廓效果

带注释的着色器代码:

Shader "Toon/Ice Effect" {

	Properties{
		_TColor("Top Color", Color) = (0.64,0.94,0.64,1)// top gradient, light green
		_Ramp("Toon Ramp (RGB)", 2D) = "gray" {}
	_BottomColor("Bottom Color", Color) = (0.23,0,0.95,1)// bottom gradient, blue
		_RimBrightness("Rim Brightness", Range(3,4)) = 3.2 // ice rim brightness


	}

		SubShader{
		Tags{ "RenderType" = "Opaque" }

		LOD 200
		CGPROGRAM
#pragma surface surf ToonRamp 

		sampler2D _Ramp;

	// custom lighting function that uses a texture ramp based
	// on angle between light direction and normal
#pragma lighting ToonRamp 
	inline half4 LightingToonRamp(SurfaceOutput s, half3 lightDir, half atten)
	{
#ifndef USING_DIRECTIONAL_LIGHT
		lightDir = normalize(lightDir);
#endif

		half d = dot(s.Normal, lightDir)*0.5 + 0.5;
		half3 ramp = tex2D(_Ramp, float2(d,d)).rgb;

		half4 c;
		c.rgb = s.Albedo * _LightColor0.rgb * ramp * (atten * 2);
		c.a = 0;
		return c;
	}


	float4 _TColor;
	float4 _BottomColor;// bottom gradient color
	float _RimBrightness;// ice rim brightness


	struct Input {
		float3 viewDir; // view direction
		float3 worldPos; // world position

	};

	void surf(Input IN, inout SurfaceOutput o) {
		float3 localPos = saturate(IN.worldPos - mul(unity_ObjectToWorld, float4(0, 0, 0, 1)).xyz) + 0.4;// local position of the object, with an offset, clamped to make sure it doesn't go into negative

		float softRim = 1.0 - saturate(dot(normalize(IN.viewDir), o.Normal));// calculate a soft fresnel based on the view direction and the normals of the object
		float hardRim = round(softRim); // round it up for a harder edge
		o.Emission = _TColor * lerp(hardRim, softRim, (localPos.x + localPos.y))  * (_RimBrightness*localPos.y);	 // lerp the emission from the hard rim to the softer one, based on the position
		float innerRim = 1.5 + saturate(dot(normalize(IN.viewDir), o.Normal)); // softer inner rim 

		o.Albedo = _TColor *pow(innerRim, 0.7)*lerp(_BottomColor, _TColor, localPos.y); // multiply the main color by the inner rim, multiply that by the gradient color lerp

	}
	ENDCG

	}

		Fallback "Diffuse"
}

硬法线问题

ue3d - Unity实现网格轮廓URP卡通描边效果

所以这个着色器使用法线来膨胀网格,这对于平滑法线模型非常有效,但对于硬法线模型则不太适用。

ue3d - Unity实现网格轮廓URP卡通描边效果

你还可以将轮廓基于顶点位置,这在某些情况下效果更好。

在这两种方法之间添加了一个滑块,这不是一个很好的解决方案。

设置

URP 不支持多通道着色器,因此无法使用该选项,但我们还有其他 2 个选项:

方法 1 使用渲染器功能

ue3d - Unity实现网格轮廓URP卡通描边效果

找到 通用渲染管线资源,可以在 Edit > Project Settings > Graphics 中快速找到它

ue3d - Unity实现网格轮廓URP卡通描边效果

Universal Render Pipeline Asset 转到 Forward Renderer Data 资产

ue3d - Unity实现网格轮廓URP卡通描边效果

在底部,转到 添加渲染器功能 并选择 渲染对象

ue3d - Unity实现网格轮廓URP卡通描边效果

给它一个名字,将它设置为 EventAfterRenderingOpaques

为将使用轮廓效果的任何对象创建一个新图层,并在此处将其设置为图层蒙版。(不要忘记将对象设置到这一层)

将从链接着色器代码制作的材质分配给 Material Override

这是一个非常快速的设置,但对于每个对象都是相同的,没有针对每个对象的设置。

方法2:使用第二种材质

Mesh Renderer 中,转到 Materials 数组,并从链接的着色器代码中添加Unity材质

ue3d - Unity实现网格轮廓URP卡通描边效果

对于实际上无法做到的多通道非常有趣,但是对于这种效果应该没问题。

这更难处理,因为必须为每个想要有轮廓的对象设置额外的效果,但可以为每个对象设置不同的设置。

对于这个 Inky Effect Outline,只需使用渲染器功能就可以了。其他轮廓很快就会出现,只是将它们分开以便于搜索!

相关信息

  • 类型:知识
  • 字数:635
  • 字符:3628
  • 适用软件:Unity
  • 说明:无
  • 编号:61183

热门内容

提示:3D天堂作为服务提供者,尊重网络版权及知识产权,对某些行为的发生不具备充分的监控能力,若无意间侵犯到您的权利,请 联系我们,我们会在收到信息后尽快给予处理。

本站文章版权归本站自创作者所有,未经允许不得转载!