当前位置: 首页 > news >正文

万网网站后台留言在哪外贸公司销售渠道

万网网站后台留言在哪,外贸公司销售渠道,做网站免责声明,郑州专业做网站公根据深度重建世界坐标证明世界坐标重建正确的方法首先#xff0c;得先找到一种证明反推回世界空间位置正确的方法。这里#xff0c;我在相机前摆放几个物体#xff0c;尽量使之在世界坐标下的位置小于1#xff0c;方便判定颜色如下图#xff1a;然后将几个物体的shader换成…根据深度重建世界坐标证明世界坐标重建正确的方法首先得先找到一种证明反推回世界空间位置正确的方法。这里我在相机前摆放几个物体尽量使之在世界坐标下的位置小于1方便判定颜色如下图然后将几个物体的shader换成如下的一个打印世界空间位置的shader//puppet_master//https://blog.csdn.net/puppet_master//2018.6.10//打印对象在世界空间位置Shader DepthTexture/WorldPosPrint{SubShader{Tags { RenderTypeOpaque }LOD 100Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include UnityCG.cgincstruct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;};struct v2f{float3 worldPos : TEXCOORD0;float4 vertex : SV_POSITION;};v2f vert (appdata v){v2f o;o.vertex UnityObjectToClipPos(v.vertex);o.worldPos mul(unity_ObjectToWorld, v.vertex);return o;}fixed4 frag (v2f i) : SV_Target{return fixed4(i.worldPos, 1.0);}ENDCG}}//fallback使之有shadow caster的passFallBack Legacy Shaders/Diffuse}然后挂上上面的重建世界坐标位置的脚本在开启和关闭脚本前后屏幕输出完全无变化说明通过后处理重建世界坐标位置与直接用shader输出世界坐标位置效果一致逆矩阵方式重建深度重建有几种方式先来看一个最简单粗暴但是看起来最容易理解的方法我们得到的屏幕空间深度图的坐标xyz都是在(0,1)区间的需要经过一步变换变换到NDC空间OpenGL风格的话就都是(-1,1)区间所以需要首先对xy以及xy对应的深度z进行*2 - 1映射。然后再将结果进行VP的逆变换就得到了世界坐标。shader代码如下//puppet_master//https://blog.csdn.net/puppet_master//2018.6.10//通过逆矩阵的方式从深度图构建世界坐标Shader DepthTexture/ReconstructPositionInvMatrix{CGINCLUDE#include UnityCG.cgincsampler2D _CameraDepthTexture;float4x4 _InverseVPMatrix;fixed4 frag_depth(v2f_img i) : SV_Target{float depthTextureValue SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv);//自己操作深度的时候需要注意Reverse_Z的情况#if defined(UNITY_REVERSED_Z)depthTextureValue 1 - depthTextureValue;#endiffloat4 ndc float4(i.uv.x * 2 - 1, i.uv.y * 2 - 1, depthTextureValue * 2 - 1, 1);float4 worldPos mul(_InverseVPMatrix, ndc);worldPos / worldPos.w;return worldPos;}ENDCGSubShader{Pass{ZTest OffCull OffZWrite OffFog{ Mode Off }CGPROGRAM#pragma vertex vert_img#pragma fragment frag_depthENDCG}}}C#部分/********************************************************************FileName: ReconstructPositionInvMatrix.csDescription:从深度图构建世界坐标逆矩阵方式Created: 2018/06/10history: 10:6:2018 13:09 by puppet_masterhttps://blog.csdn.net/puppet_master*********************************************************************/using System.Collections;using System.Collections.Generic;using UnityEngine;[ExecuteInEditMode]public class ReconstructPositionInvMatrix : MonoBehaviour {private Material postEffectMat null;private Camera currentCamera null;void Awake(){currentCamera GetComponent();}void OnEnable(){if (postEffectMat null)postEffectMat new Material(Shader.Find(DepthTexture/ReconstructPositionInvMatrix));currentCamera.depthTextureMode | DepthTextureMode.Depth;}void OnDisable(){currentCamera.depthTextureMode ~DepthTextureMode.Depth;}void OnRenderImage(RenderTexture source, RenderTexture destination){if (postEffectMat null){Graphics.Blit(source, destination);}else{var vpMatrix currentCamera.projectionMatrix * currentCamera.worldToCameraMatrix;postEffectMat.SetMatrix(_InverseVPMatrix, vpMatrix.inverse);Graphics.Blit(source, destination, postEffectMat);}}}效果如下重建ok看起来比较简单但是其中有一个/w的操作如果按照正常思维来算应该是先乘以w然后进行逆变换最后再把world中的w抛弃即是最终的世界坐标不过实际上投影变换是一个损失维度的变换我们并不知道应该乘以哪个w所以实际上上面的计算并非按照理想的情况进行的计算而是根据计算推导而来(更加详细推导请参考这篇文章不过我感觉这个推导有点绕)。已知条件(M为VP矩阵M^-1即为其逆矩阵Clip为裁剪空间ndc为标准设备空间world为世界空间)ndc Clip.xyzw / Clip.w Clip / Clip.wworld M^-1 * Clip二者结合得world M ^-1 * ndc * Clip.w我们已知M和ndc然而还是不知道Clip.w但是有一个特殊情况是world的w坐标经过变换后应该是1即1 world.w (M^-1 * ndc).w * Clip.w进而得到Clip.w 1 / (M^ -1 * ndc).w带入上面等式得到world (M ^ -1 * ndc) / (M ^ -1 * ndc).w所以世界坐标就等于ndc进行VP逆变换之后再除以自身的w。不过这种方式重建世界坐标性能比较差一般来说我们都是逐顶点地进行矩阵运算毕竟定点数一般还是比较少的但是全屏幕逐像素进行矩阵运算这个计算量就不是一般的大了性能肯定是吃不消的。补充如果是DepthNormalTexture中的depth通过逆矩阵方式重建计算方式略有不同float depth;float3 normal;float4 cdn tex2D(_CameraDepthNormalsTexture, i.uv);DecodeDepthNormal(cdn, depth, normal);//float depth SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv);//逆矩阵的方式使用的是1/z非线性深度而_CameraDepthNormalsTexture中的是线性的进行一步Linear01Depth的逆运算depth (1.0/depth - _ZBufferParams.y) /_ZBufferParams.x ;//自己操作深度的时候需要注意Reverse_Z的情况#if defined(UNITY_REVERSED_Z)depth 1 - depth;#endiffloat4 ndc float4(i.uv.x * 2 - 1, i.uv.y * 2 - 1, depth * 2 - 1, 1);float4 worldPos mul(_InverseVPMatrix, ndc);worldPos / worldPos.w;屏幕射线插值方式重建这种方式的重建可以参考Secrets of CryENGINE 3 Graphics Technology这个CryTech 2011年的PPT。借用一张图然后偶再画个平面的图上图中A为相机位置G为空间中我们要重建的一点那么该点的世界坐标为A(worldPos) 向量AG我们要做的就是求得向量AG即可。根据三角形相似的原理三角形AGH相似于三角形AFC则得到AH / AC AG / AF。由于三角形相似就是比例关系所以我们可以把AH / AC看做01区间的比值那么AC就相当于远裁剪面距离即为1AH就是我们深度图采样后变换到01区间的深度值即Linear01Depth的结果d。那么AG AF * d。所以下一步就是求AF即求出相机到屏幕空间每个像素点对应的射线方向。看到上面的立体图其实我们可以根据相机的各种参数求得视锥体对应四个边界射线的值这个操作在vertex阶段进行由于我们的后处理实际上就是渲染了一个Quad上下左右四个顶点把这个射线传递给pixel阶段时就会自动进行插值计算也就是说在顶点阶段的方向值到pixel阶段就变成了逐像素的射线方向。那么我们要求的其实就相当于AB这条向量的值以上下平面为例三维向量只比二维多一个维度我们已知远裁剪面距离F相机的三个方向(相机transform.forward.right.up)AB AC CB|BC| tan(0.5fov) * |AC||AC| FarAC transorm.forward * FarCB transform.up * tan(0.5fov) * Far。我直接使用了远裁剪面对应的位置计算了三个方向向量进而组合得到最终四个角的向量。用远裁剪面的计算代码比较简单(恩我懒)不过《ShaderLab入门精要》中使用的是近裁剪面比例计算不确定是否有什么考虑(比如精度没有测出来如果有大佬知道还望不吝赐教)。shader代码如下//puppet_master//https://blog.csdn.net/puppet_master//2018.6.16//通过深度图重建世界坐标视口射线插值方式Shader DepthTexture/ReconstructPositionViewPortRay{CGINCLUDE#include UnityCG.cgincsampler2D _CameraDepthTexture;float4x4 _ViewPortRay;struct v2f{float4 pos : SV_POSITION;float2 uv : TEXCOORD0;float4 rayDir : TEXCOORD1;};v2f vertex_depth(appdata_base v){v2f o;o.pos UnityObjectToClipPos(v.vertex);o.uv v.texcoord.xy;//用texcoord区分四个角就四个点if无所谓吧int index 0;if (v.texcoord.x 0.5 v.texcoord.y 0.5)index 0;else if (v.texcoord.x 0.5 v.texcoord.y 0.5)index 1;else if (v.texcoord.x 0.5 v.texcoord.y 0.5)index 2;elseindex 3;o.rayDir _ViewPortRay[index];return o;}fixed4 frag_depth(v2f i) : SV_Target{float depthTextureValue SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv);float linear01Depth Linear01Depth(depthTextureValue);//worldpos campos 射线方向 * depthfloat3 worldPos _WorldSpaceCameraPos linear01Depth * i.rayDir.xyz;return fixed4(worldPos, 1.0);}ENDCGSubShader{Pass{ZTest OffCull OffZWrite OffFog{ Mode Off }CGPROGRAM#pragma vertex vertex_depth#pragma fragment frag_depthENDCG}}}C#代码如下/********************************************************************FileName: ReconstructPositionViewPortRay.csDescription:通过深度图重建世界坐标视口射线插值方式Created: 2018/06/16history: 16:6:2018 16:17 by puppet_masterhttps://blog.csdn.net/puppet_master*********************************************************************/using System.Collections;using System.Collections.Generic;using UnityEngine;[ExecuteInEditMode]public class ReconstructPositionViewPortRay : MonoBehaviour {private Material postEffectMat null;private Camera currentCamera null;void Awake(){currentCamera GetComponent();}void OnEnable(){if (postEffectMat null)postEffectMat new Material(Shader.Find(DepthTexture/ReconstructPositionViewPortRay));currentCamera.depthTextureMode | DepthTextureMode.Depth;}void OnDisable(){currentCamera.depthTextureMode ~DepthTextureMode.Depth;}void OnRenderImage(RenderTexture source, RenderTexture destination){if (postEffectMat null){Graphics.Blit(source, destination);}else{var aspect currentCamera.aspect;var far currentCamera.farClipPlane;var right transform.right;var up transform.up;var forward transform.forward;var halfFovTan Mathf.Tan(currentCamera.fieldOfView * 0.5f * Mathf.Deg2Rad);//计算相机在远裁剪面处的xyz三方向向量var rightVec right * far * halfFovTan * aspect;var upVec up * far * halfFovTan;var forwardVec forward * far;//构建四个角的方向向量var topLeft (forwardVec - rightVec upVec);var topRight (forwardVec rightVec upVec);var bottomLeft (forwardVec - rightVec - upVec);var bottomRight (forwardVec rightVec - upVec);var viewPortRay Matrix4x4.identity;viewPortRay.SetRow(0, topLeft);viewPortRay.SetRow(1, topRight);viewPortRay.SetRow(2, bottomLeft);viewPortRay.SetRow(3, bottomRight);postEffectMat.SetMatrix(_ViewPortRay, viewPortRay);Graphics.Blit(source, destination, postEffectMat);}}}开关后处理前后效果仍然不变这里我用了默认非线性的深度图进行的深度计算需要先进行Linear01Depth计算如果用了线性深度比如DepthNormalTexture那么就进行一步简单的线性映射即可。整体的射线计算我用了Linear01Depth * 外围计算好的距离。也可以用LinearEyeDepth * 外围计算好的方向。总之方案还是蛮多的变种也很多还有自己重写Graphic.Blit自己设置Quad的值把index设置在顶点的z值中。屏幕射线插值方式重建视空间坐标补充一条屏幕空间深度重建坐标的Tips。如果我们要求视空间的位置的话有一种更简便并且性能更好的方式。这种方式与上面的屏幕射线插值的方式重建世界坐标的原理一致。只需要输入一个投影矩阵的逆矩阵即在vertex阶段从NDC坐标系的四个远裁剪面边界(-1-111)乘以逆投影矩阵得到视空间的四个远裁剪面坐标位置然后除以齐次坐标转化到普通坐标下。这样的四个点的位置也就是视空间下从相机到该点的射线方向经过插值到fragment阶段直接乘以01区间深度就得到了该像素点的视空间位置了。那么就只有一个问题没有解决在于应该如何获得NDC坐标系下的边界点。上面推导中提到过在后处理阶段实际上就是绘制了一个Quad对应整个屏幕。这个Quad的四个边界点刚好对应屏幕的四个边界点uv是(0,1)区间的刚好对应屏幕空间我们通过*2 - 1将其转化到(-1,1)区间就可以得到四个边界对应NDC坐标系下的xy坐标了。v2f vert (appdata v){float4 clipPos float4(v.uv * 2 - 1.0, 1.0, 1.0);float4 viewRay mul(_InverseProjectionMatrix, clipPos);o.viewRay viewRay.xyz / viewRay.w;return o;}fixed4 frag (v2f i) : SV_Target{float depthTextureValue SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv);float linear01Depth Linear01Depth(depthTextureValue);float3 viewPos _WorldSpaceCameraPos.xyz linear01Depth * i.viewRay;}此处的InverseProjectionMatrix与上文中一样也需要自己传入因为在后处理阶段内置矩阵已经被替换了。
http://wiki.neutronadmin.com/news/298771/

相关文章:

  • 国外商业网站无锡网站建设收费
  • 网站建设需要学习哪些wordpress主题汉化版
  • 公司多个门户是做二级域名还是做多个网站百度站长官网
  • 长沙网站制作平台公司网站建设存在问题
  • 站长工具传媒手机公众平台网站开发
  • 昌平区手机网站制作服务深圳盐田建设交易中心网站
  • 做网站的服务器多少钱北京西站列车时刻表最新
  • 广西麒铭建设有限公司网站教做美食的网站
  • 网站管理助手4.0html音乐网页完整代码
  • 邢台网站制作的地方连云港seo优化
  • 西宁市网站设计企业西安网站制作服务商
  • 如何创建免费网站做谷歌seo要发大量文章吗
  • 建一个下载网站要什么cms系统怎么用.net做网站
  • 招聘网站建设人员用wordpress招商
  • 二手汽车手机网站模板网站建设商城模板下载
  • 让别人做网站多久开始注册域名万网张向东有多少资产
  • 视频手机网站开发黄石建网站
  • 网页和网站有什么区别做网站导航按钮怎么做
  • 东营做网站哪里好大连网站排名系统
  • vue 做的网站系统开发软件
  • 越秀微网站建设光棍天堂手机2019版免费观看
  • 公司网站建设素材中细软做的网站
  • 怎样在手机上做自己的网站网店美工课程
  • wordpress 空间商seo是什么职业合法吗
  • 做网站购买备案域名网站 建设运行情况报告
  • 找人做海报在什么网站找免费的ui设计的网站
  • 做网站免费搭建温州网站建设制作
  • 如何规划设计一个网站ueditor编辑器wordpress
  • 网站开发小图标怎么设置seo优化中商品权重主要由什么决定
  • 网站建设柒首先金手指1有经验的常州网站建设