Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unity3d 如何在后处理顶点和片段着色器中计算对象的径向距离_Unity3d_Shader_Vertex - Fatal编程技术网

Unity3d 如何在后处理顶点和片段着色器中计算对象的径向距离

Unity3d 如何在后处理顶点和片段着色器中计算对象的径向距离,unity3d,shader,vertex,Unity3d,Shader,Vertex,经过数小时的谷歌搜索、复制粘贴代码和玩游戏,我仍然找不到解决问题的办法 我尝试使用顶点和片段函数编写一个后处理着色器。我的问题是,我不知道如何计算当前顶点到摄影机位置(或任何其他给定位置)在世界坐标系中的径向距离 我的目标如下: 考虑一个非常大的3D平面,其中相机位于顶部,并向下精确地观察平面。我现在想要一个后处理着色器,它在平面上绘制一条白线,这样只有那些与摄影机有一定径向距离的像素才会被绘制成白色。预期结果将是一个白色圆圈(在此特定设置中) 原则上我知道怎么做,但问题是我无法找到如何计算到顶

经过数小时的谷歌搜索、复制粘贴代码和玩游戏,我仍然找不到解决问题的办法

我尝试使用顶点和片段函数编写一个后处理着色器。我的问题是,我不知道如何计算当前顶点到摄影机位置(或任何其他给定位置)在世界坐标系中的径向距离

我的目标如下: 考虑一个非常大的3D平面,其中相机位于顶部,并向下精确地观察平面。我现在想要一个后处理着色器,它在平面上绘制一条白线,这样只有那些与摄影机有一定径向距离的像素才会被绘制成白色。预期结果将是一个白色圆圈(在此特定设置中)

原则上我知道怎么做,但问题是我无法找到如何计算到顶点的径向距离

这里的问题可能是这是一个后处理着色器。因此,该着色器不会应用于特定对象。如果我这样做,我可以通过使用
mul(unity\u ObjectToWorld,v.vertex)
获得顶点的世界坐标,但对于后处理着色器,这给出了一个无意义的值

这是我针对此问题的调试代码:

Shader“非隐藏/TestShader”
{
性质
{
_MainTex(“纹理”,2D)=“白色”{}
}
子阴影
{
标记{“RenderType”=“Transparent”“Queue”=“Transparent-1”}
LOD 100
注销
通过
{
CGP程序
#pragma顶点顶点
#布拉格碎片碎片
#布拉格目标3.0
#包括“UnityCG.cginc”
取样器2D_MainTex;
取样器2D(U CameraDepthTexture);
均匀浮动4_MainTex_TexelSize;
//V2F
结构v2f{
浮动4输出:SV_位置;
浮动4世界位置:TEXCOORD0;
float3-rayDir:TEXCOORD1;
float3 camNormal:TEXCOORD2;
};
//采样深度
浮动采样深度(浮动2 uv){
返回线01深度(
统一样本深度(
tex2D(_-CameraDepthTexture,uv));
}
//顶点
v2f垂直(appdata_tan v)
{
切线空间旋转;
v2fo;
o、 outpos=单位对象到顶点(v顶点);
o、 worldPos=mul(unity_ObjectToWorld,v.vertex);
o、 rayDir=mul(旋转,ObjSpaceViewDir(v.vertex));
o、 camNormal=UNITY\u MATRIX\u IT\u MV[2].xyz;
返回o;
}
//碎片
固定4框架(v2f英寸):SV_目标
{
//获取uv坐标
float2 uv=IN.outpos.xy*(_ScreenParams.zw-1.0f);
//如有必要,翻一翻
#如果UNITY从顶部开始
如果(_MainTex_TexelSize.y<0)
{
uv.y=1-uv.y;
}
#恩迪夫
//获得深度
浮动深度=采样深度(uv);
//定色
固定4色=0;
if(深度x<1)
{
color.r=IN.worldPos.x;
color.g=IN.worldPos.y;
color.b=IN.worldPos.z;
}
返回颜色;
}       
ENDCG
}
}
}
当前状态 此图显示了相机俯视平面时的结果: 蓝色值(无论出于何种原因)在每个像素中为25。红色和绿色区域反映屏幕的x-y坐标

即使我稍微旋转相机,在相同的屏幕坐标下也会得到完全相同的着色:

这表明计算出的“worldPos”坐标是屏幕坐标,与平面的世界坐标无关

预期结果 我希望看到的结果如下:

这里,与相机具有相同(径向)距离的像素具有相同的颜色

我需要如何更改上述代码以实现此效果?使用rayDir(在vert函数中计算),我尝试至少获得从相机中心到当前像素的方向向量,这样我就可以使用深度信息计算径向距离。但是rayDir对所有像素都有一个常量值


在这一点上,我还必须说,我真的不明白什么是计算内的垂直函数。这是我在互联网上找到并尝试过的东西。

好吧,我找到了一些解决问题的方法,因为我在这里找到了这段视频:

视频描述中有一个指向相应GIT存储库的链接。我下载、分析并重写了代码,使其符合我的目的,更易于阅读和理解

我学到的主要东西是,没有内置的方法来使用后处理着色器计算径向距离(如果我错了,请纠正我!)。因此,为了得到径向距离,唯一的方法似乎实际上是使用从摄影机到顶点的方向向量和深度缓冲区。由于方向向量也不能以内置方式使用,因此使用了一个技巧:

可以使用自定义Blit函数来设置一些附加着色器变量,而不是在后处理脚本中使用Graphics.Blit函数。在这种情况下,相机的平截头体存储在第二组纹理坐标中,这些坐标在着色器代码中作为TEXCOORD1可用。这里的技巧是,相应的着色器变量自动包含一个插值uv值,该值与我要查找的方向向量(“平截头体光线”)相同

调用脚本的代码现在如下所示:

使用UnityEngine;
使用Sy