53 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
		
		
			
		
	
	
			53 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| 
								 | 
							
								## 前言
							 | 
						|||
| 
								 | 
							
								思路是使用平面方程来判断模型裁切,之后在另一面使用UnLit的自发光材质显示剖面。但Ue4的BlendingMaterialAttributes不能指定UnLit作为ShaderModel。所以可以使用我之前开发的多Pass插件搞定。
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								## 外部普通表面材质
							 | 
						|||
| 
								 | 
							
								使用平面方程来做一个Mask即可。
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								## 内部剖面材质
							 | 
						|||
| 
								 | 
							
								坡面材质需要使用UnLit材质模型,这样就不会有阴影与法线的干扰了。但Unlit不能翻转法线,所以需要再勾选**双面渲染**选项。
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								## 使用方法说明
							 | 
						|||
| 
								 | 
							
								https://zhuanlan.zhihu.com/p/69139579
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								1. 使用上面链接介绍的代码,新建一个蓝图类并且挂载UStrokeStaticMeshComponent。
							 | 
						|||
| 
								 | 
							
								2. 赋予UStrokeStaticMeshComponent所需剖切的模型,以及上文制作好的外部表面材质。
							 | 
						|||
| 
								 | 
							
								3. 赋予SecondPassMaterial内部剖面材质,并勾选UStrokeStaticMeshComponent的NeedSecondPass变量。
							 | 
						|||
| 
								 | 
							
								4. 将蓝图类拖到关卡中,并且设置2个材质的PlaneNormal与PlanePoint。PlanePoint为世界坐标,PlaneNormal需要归一化。
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								## 最终效果
							 | 
						|||
| 
								 | 
							
								锯齿是因为垃圾笔记本散热差,把效果开低的关系。
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								## 错误的尝试
							 | 
						|||
| 
								 | 
							
								之前还尝试WorldPositionOffset的思路来做,不过后来发现没有实用性。因为剖面的大小与形状是不确定的,用投射的方式来平移内部可见顶点,会造成多余的顶点平移到平面外的问题。所以只适合拿来做规整模型的剖切效果。
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								错误结果:
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								实现节点如下:
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								CustomNode代码:
							 | 
						|||
| 
								 | 
							
								```
							 | 
						|||
| 
								 | 
							
								// Input PlaneNormal
							 | 
						|||
| 
								 | 
							
								// Input PlanePoint
							 | 
						|||
| 
								 | 
							
								// Input WorldPosition
							 | 
						|||
| 
								 | 
							
								float NormalPower2= pow(PlaneNormal.x,2) + pow(PlaneNormal.y,2) + pow(PlaneNormal.z,2);
							 | 
						|||
| 
								 | 
							
								float D=dot(PlaneNormal.xyz,PlanePoint.xyz)*-1;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								float posX= ((pow(PlaneNormal.y,2) + pow(PlaneNormal.z,2))*WorldPosition.x-PlaneNormal.x*(PlaneNormal.y*WorldPosition.y+PlaneNormal.z*WorldPosition.z+D))/NormalPower2;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								float posY=((pow(PlaneNormal.x,2) + pow(PlaneNormal.z,2))*WorldPosition.y-PlaneNormal.y*(PlaneNormal.x*WorldPosition.x+PlaneNormal.z*WorldPosition.z+D))/NormalPower2;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								float posZ=((pow(PlaneNormal.x,2) + pow(PlaneNormal.y,2))*WorldPosition.z-PlaneNormal.z*(PlaneNormal.x*WorldPosition.x+PlaneNormal.y*WorldPosition.y+D))/NormalPower2;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								return float3(posX,posY,posZ)-WorldPosition.xyz;
							 | 
						|||
| 
								 | 
							
								```
							 |