Unity中使用Shader实现3D打印机效果

思路很简单,我们指定一个裁剪高度_ConstructY,如果模型上某个点的的世界坐标高度大于裁剪高度,就discard(擦除)掉,而裁剪高度到边缘光(白色的扫光)高度之间的点,使用指定颜色渲染。然后我们动态改变_ConstructY,就能实现这个效果。表面着色器代码:

		void surf (Input IN, inout SurfaceOutputStandard o) {
			//点的世界坐标高度在裁剪高度下,正常渲染
			if (IN.worldPos.y < _ConstructY)
			{
				fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
				o.Albedo = c.rgb;
				o.Alpha = c.a;
				building = 0;
			}
			else
			{
				//点的世界坐标高度在裁剪高度下,正常渲染
				float s = +sin((IN.worldPos.x * IN.worldPos.z) * 240 + _Time[3] + o.Normal) / 120;
				o.Albedo = _ConstructColor.rgb;
				o.Alpha = _ConstructColor.a;
				building = 1;
				//扫光之上的像素,擦除掉
				if (IN.worldPos.y > _ConstructY + _ConstructGap + s)
				{
					discard;
				}
			}
			o.Metallic = _Metallic;
			o.Smoothness = _Glossiness;
		}

接下来,我们要将扫光禁用光照渲染,而正常显示的部分,使用正常的光照渲染,这里通过 building变量来告诉光照模型函数是否正常渲染

		inline half4 LightingUnlit(SurfaceOutputStandard s, half3 lightDir, UnityGI gi)
		{
			if (building)
			{
				return _ConstructColor; // 不使用光照模型渲染
			}
			if (dot(s.Normal, lightDir) < 0) //避免出现模型空洞
				return _ConstructColor;


			return LightingStandard(s, lightDir, gi); // Unity5 PBR
		}


		inline void LightingUnlit_GI(SurfaceOutputStandard s, UnityGIInput data, inout UnityGI gi)
		{
			LightingStandard_GI(s, data, gi);
		}


此外,我们要将面裁剪关掉,避免出现模型穿破

Cull Off

完整的Shader文件和C#文件:https://pan.baidu.com/s/1bo5CKu7


猜你喜欢

转载自blog.csdn.net/leohijack/article/details/54603420