三平面映射TriPlanar

shader效果中存在“缝隙”:(最后的代码中已经注释的很清楚了)
出现缝隙的原因:因为UV坐标是不连续的,所以会有缝隙。。。(法线的T,B,是根据U和V生成的,所以用法线也会有裂缝,这里的法线和下面用作mask的用法是不一样的)
在这里插入图片描述
三平面映射的效果:图中的边界是有过渡和缓冲,如下图
在这里插入图片描述

基本展示:
世界空间XY平面效果:
在这里插入图片描述世界空间XZ展示:

在这里插入图片描述

存在的问题(不可避免的问题):!!!!!!!!!

在这里插入图片描述

宏观思路 :
(1)

三平面映射原理
(2)法线遮罩效果 和 思路:

在这里插入图片描述
(3)
在这里插入图片描述换成noise图看不出缝隙!!!!
在这里插入图片描述

Shader "Unlit/TriPlanar_Code"
{
	Properties
	{
		_MainTex ("Texture", 2D) = "white" {}
		_Tilling("Main Tilling",Vector) = (1,1,1,1)
		_Contrast("Contrast",Range(1,10)) = 5
	}
	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
			{
				float2 uv : TEXCOORD0;	
				float4 vertex : SV_POSITION;
				float3 worldPos : TEXCOORD01;
				float3 worldPivot : TEXCOORD02;
				float3 worldNormal : TEXCOORD03;
			};

			sampler2D _MainTex;
			float4 _MainTex_ST;
			float4 _Tilling;
			float _Contrast;
			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).xyz;
				o.worldPivot = mul(unity_ObjectToWorld, float4(0,0,0,1)).xyz;
				o.worldNormal = UnityObjectToWorldNormal(v.normal);
				return o;
			}

			// 根据法线的 三个轴  , 生成遮罩
			float3 NormalMask(float3 wNormal)
			{
				float3 tempNormal =  pow(abs(wNormal),_Contrast);
				float3 mask = tempNormal /(tempNormal.x + tempNormal.y + tempNormal.z);
				return mask;
			}

			float4 TriPlanar(float3 maskValue,float3 worldPos,float3 worldPivot)
			{
				float3 tempPos = ((worldPos - worldPivot) * _Tilling.xyz).xyz;
				//  xy 平面的像素正常显示 但是  其他轴对应平面的值不正确,所以 乘以 maskValue.z,屏蔽掉其它轴面的值。
				float4 colorZ = tex2D(_MainTex,tempPos.xy) * maskValue.z;
				float4 colorY = tex2D(_MainTex,tempPos.xz) * maskValue.y;
				float4 colorX = tex2D(_MainTex,tempPos.yz) * maskValue.x;
				//  三个轴面的正确结果相加  ,  归一化
				return normalize(colorX + colorY + colorZ); 
			}


			
			fixed4 frag (v2f i) : SV_Target
			{
				float3 maskValue = NormalMask(i.worldNormal);
				float4 triColor = TriPlanar(maskValue,i.worldPos,i.worldPivot);
				return triColor;
			}
			ENDCG
		}
	}
}

平面映射的延申

TriPlanar

在这里插入图片描述
通过 在3DMax中的 ”顶点色“ 来控制顶点的运动幅度。。。
顶点动画在播放 但是 眼睛不要动, 骨头的根部不要动。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
VTK(Visualization Toolkit)是一个用于可视化和图形处理的开源软件库。它提供了广泛的功能,包括维可视化、体绘制、图形处理、图像处理、科学可视化等。在VTK中,可以使用标记点来标记维场景中的特定位置。而平面映射则是将维场景中的物体投影到二维平面上,以便于展示和处理。 下面是VTK中实现维标记点平面映射的步骤: 1. 创建一个VTK Renderer和RenderWindow对象,用于显示场景。 2. 创建一个VTK PolyData对象,用于存储标记点的位置和属性。 3. 创建一个VTK PolyDataMapper对象,将PolyData对象映射到场景中。 4. 创建一个VTK Actor对象,将Mapper对象添加到Actor中。 5. 将Actor对象添加到Renderer中。 6. 创建一个VTK Plane对象,用于进行平面映射。 7. 创建一个VTK ProjectPoints对象,将标记点投影到平面上。 8. 将投影结果添加到PolyData对象中。 9. 更新RenderWindow对象,显示投影结果。 下面是实现代码示例: ```python import vtk # create a renderer and render window renderer = vtk.vtkRenderer() render_window = vtk.vtkRenderWindow() render_window.AddRenderer(renderer) # create polydata object to store marker points polydata = vtk.vtkPolyData() # create mapper object to map polydata to scene mapper = vtk.vtkPolyDataMapper() mapper.SetInputData(polydata) # create actor object to add mapper to renderer actor = vtk.vtkActor() actor.SetMapper(mapper) renderer.AddActor(actor) # create plane object for projection plane = vtk.vtkPlane() # create project points object for projection project_points = vtk.vtkProjectPoints() project_points.SetInputData(polydata) project_points.SetPlane(plane) project_points.Update() # add projection result to polydata polydata.SetPoints(project_points.GetOutput().GetPoints()) # update render window to show projection result render_window.Render() ``` 以上代码演示了如何创建一个VTK场景,并将标记点投影到平面上以显示投影结果。根据需要,可以调整代码以适应不同的应用场景。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值