扫描仪-ShaderLab
着色器:
定义相关属性并从摄像机获取深度纹理,并在结构体中加入射线的变量
sampler2D _MainTex;
sampler2D _DetailTex;
sampler2D_float _CameraDepthTexture;
float4 _WorldSpaceScannerPos;
float _ScanDistance;
float _ScanWidth;
float _LeadSharp;
float4 _LeadColor;
float4 _MidColor;
float4 _TrailColor;
float4 _HBarColor;
在片元着色器中对深度纹理解码并进行线性转换,根据射线和深度得到ray的方向由此定位到扫描的起始位置。
定义在距离该位置的一定范围内生成半透明的圆环扫描仪效果,同时需要注意扫描效果对天空和不起作用。
float rawDepth = DecodeFloatRG(tex2D(_CameraDepthTexture, i.uv_depth));
float linearDepth = Linear01Depth(rawDepth);
float4 wsDir = linearDepth * i.interpolatedRay;
float3 wsPos = _WorldSpaceCameraPos + wsDir;
half4 scannerCol = half4(0, 0, 0, 0);
float dist = distance(wsPos, _WorldSpaceScannerPos);
if (dist < _ScanDistance && dist > _ScanDistance - _ScanWidth && linearDepth < 1)
{
float diff = 1 - (_ScanDistance - dist) / (_ScanWidth);
half4 edge = lerp(_MidColor, _LeadColor, pow(diff, _LeadSharp));
scannerCol = lerp(_TrailColor, edge, diff) + horizBars(i.uv) * _HBarColor;
scannerCol *= diff;
}
摄像机脚本:
从摄像机获取深度
void OnEnable()
{
_camera = GetComponent();
_camera.depthTextureMode = DepthTextureMode.Depth;
}
利用RayCast的原理获取鼠标点击的位置作为扫描起始位置
if (Input.GetMouseButtonDown(0))
{
Ray ray = _camera.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
_scanning = true;
ScanDistance = 0;
ScannerOrigin.position = hit.point;
}
}
获取摄像机视场四个边角位置并根据远截面进行方向变量的统一变换,方便进行位置映射,将摄像机捕捉画面作为shader的主纹理
在update函数中使得扫描距离随时间增加,将扫描距离和扫描起始位置作为参数传到shader中。