Просмотр исходного кода

修改添加uvc纹理裁剪,区域外变成填充黑色

slambb 6 месяцев назад
Родитель
Сommit
42d161ec77

+ 10 - 6
Assets/BowArrow/InfraredCamera/InfraredDemo.cs

@@ -1101,7 +1101,11 @@ public class InfraredDemo : JCUnityLib.ViewBase
 
     [SerializeField] RawImage _cameraRenderTest5;
     [SerializeField] RawImage _cameraRenderTest6;
-
+    public RawImage MyCameraRender6
+    {
+        get { return _cameraRenderTest6; }
+        set { _cameraRenderTest6 = value; }
+    }
     void DrawTestLine()
     {
         Vector2 texSize = ScreenLocate.Main.getUVCCameraInfoSize;
@@ -1167,11 +1171,11 @@ public class InfraredDemo : JCUnityLib.ViewBase
             OnDropdownValueChanged(index, screenQuads);
         });
 
-        if (screenQuads[0] != null || screenQuads[1] != null)
-        {
-            Texture texImage6 = ScreenLocate.Main.OutputTextures[5];
-            if (texImage6 != null) _cameraRenderTest6.texture = texImage6;
-        }
+        //if (screenQuads[0] != null || screenQuads[1] != null)
+        //{
+        //    Texture texImage6 = ScreenLocate.Main.OutputTextures[5];
+        //    if (texImage6 != null) _cameraRenderTest6.texture = texImage6;
+        //}
         if (ScreenLocate.quadUnityVectorList.Count == 4)
         {
             //绘制白色线段

+ 87 - 0
Assets/InfraredProject/Resources/CameraPointsMaskShader.shader

@@ -0,0 +1,87 @@
+Shader "Custom/CameraPointsMaskShader"
+{
+    Properties
+    {
+        _MainTex("Main Texture", 2D) = "white" {}
+         // 这里用4个Vector传四个顶点点坐标(UV空间,0~1)
+        _QuadP0("Quad Point 0", Vector) = (0,0,0,0)
+        _QuadP1("Quad Point 1", Vector) = (0,0,0,0)
+        _QuadP2("Quad Point 2", Vector) = (0,0,0,0)
+        _QuadP3("Quad Point 3", Vector) = (0,0,0,0)
+    }
+        SubShader
+    {
+        Tags { "RenderType" = "Opaque" }
+        Pass
+        {
+            CGPROGRAM
+            #pragma vertex vert
+            #pragma fragment frag
+
+            sampler2D _MainTex;
+            float4 _QuadP0;
+            float4 _QuadP1;
+            float4 _QuadP2;
+            float4 _QuadP3;
+
+            struct appdata
+            {
+                float4 vertex : POSITION;
+                float2 uv : TEXCOORD0;
+            };
+
+            struct v2f
+            {
+                float2 uv : TEXCOORD0;
+                float4 vertex : SV_POSITION;
+            };
+
+            v2f vert(appdata v)
+            {
+                v2f o;
+                o.vertex = UnityObjectToClipPos(v.vertex);
+                o.uv = v.uv;
+                return o;
+            }
+
+            // 计算2D向量叉积符号
+            float sign2D(float2 p1, float2 p2, float2 p3)
+            {
+                return (p1.x - p3.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p3.y);
+            }
+
+            // 点是否在四边形内(用两个三角形判定)
+            float PointInQuad(float2 p, float2 p0, float2 p1, float2 p2, float2 p3)
+            {
+                float inTri1 = step(0.0, sign2D(p, p0, p1)) *
+                               step(0.0, sign2D(p, p1, p3)) *
+                               step(0.0, sign2D(p, p3, p0));
+
+                float inTri2 = step(0.0, sign2D(p, p0, p3)) *
+                               step(0.0, sign2D(p, p3, p2)) *
+                               step(0.0, sign2D(p, p2, p0));
+
+                return inTri1 + inTri2;
+            }
+
+            fixed4 frag(v2f i) : SV_Target
+            {
+                float2 uv = i.uv;
+
+                float2 p0 = _QuadP0.xy;
+                float2 p1 = _QuadP1.xy;
+                float2 p2 = _QuadP2.xy;
+                float2 p3 = _QuadP3.xy;
+
+                float inside = PointInQuad(uv, p0, p1, p2, p3);
+
+                fixed4 colInside = tex2D(_MainTex, uv);
+                fixed4 colOutside = fixed4(0,0,0,1);
+
+                // inside > 0 表示点在四边形内
+                return lerp(colOutside, colInside, saturate(inside));
+            }
+            ENDCG
+        }
+    }
+}

+ 10 - 0
Assets/InfraredProject/Resources/CameraPointsMaskShader.shader.meta

@@ -0,0 +1,10 @@
+fileFormatVersion: 2
+guid: 925a5a836d509e14391a336941f6c216
+ShaderImporter:
+  externalObjects: {}
+  defaultTextures: []
+  nonModifiableTextures: []
+  preprocessorOverride: 0
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 65 - 0
Assets/InfraredProject/WebCamera/Script/ZIM/ScreenLocate.cs

@@ -259,6 +259,7 @@ public partial class ScreenLocate : o0InfraredCameraHandler
 
     [NonSerialized] public RectTransform BackQuad = null;
 
+    public Material quadMaskMat;
     static public ScreenLocate Main { get; private set; }
 
     static public void AutoLightPixels(Color[] pixels, int width, int height)
@@ -359,6 +360,9 @@ public partial class ScreenLocate : o0InfraredCameraHandler
 
         //if (mUVCDrawer)
         //    mUVCDrawer.StartPreviewAction += UVCIsReady;
+
+        //获取master
+        quadMaskMat = new Material(Shader.Find("Custom/CameraPointsMaskShader"));
     }
 
     void OnDestroy()
@@ -1417,6 +1421,48 @@ public partial class ScreenLocate : o0InfraredCameraHandler
         RenderTexture.ReleaseTemporary(renderTexture);
         return _texture2D;
     }
+    /// <summary>
+    /// 制作一个填充黑边的texture,把识别点之后的外围区域填充成黑色部分,用shader处理
+    /// </summary>
+    /// <param name="inputTexture"></param>
+    /// <param name="shaderMat"></param>
+    /// <param name="quadUV"></param>
+    /// <param name="width"></param>
+    /// <param name="height"></param>
+    /// <returns></returns>
+    private Texture2D TextureToTexture2DWithShader(Texture inputTexture, Material shaderMat, List<Vector2> quadUV, int width = 0, int height = 0)
+    {
+        if (width == 0) width = inputTexture.width;
+        if (height == 0) height = inputTexture.height;
+
+        // 设置四点裁剪(传给 shader)
+        shaderMat.SetVector("_QuadP0", quadUV[0]);
+        shaderMat.SetVector("_QuadP1", quadUV[1]);
+        shaderMat.SetVector("_QuadP2", quadUV[2]);
+        shaderMat.SetVector("_QuadP3", quadUV[3]);
+
+
+        // 创建临时 RT
+        RenderTexture currentRT = RenderTexture.active;
+        RenderTexture tempRT = RenderTexture.GetTemporary(
+            width, height, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
+
+        // Blit 带 Shader 的处理
+        Graphics.Blit(inputTexture, tempRT, shaderMat);
+
+        // 从 RT 读取像素到 Texture2D
+        Texture2D resultTex = new Texture2D(width, height, TextureFormat.ARGB32, false, true);
+        RenderTexture.active = tempRT;
+        resultTex.ReadPixels(new Rect(0, 0, width, height), 0, 0);
+        resultTex.Apply();
+
+        // 清理
+        RenderTexture.active = currentRT;
+        RenderTexture.ReleaseTemporary(tempRT);
+
+        return resultTex;
+    }
+
 
     //public void CreateUVCTexture2DFocusSizeIfNeeded(int width, int height)
     //{
@@ -1443,7 +1489,26 @@ public partial class ScreenLocate : o0InfraredCameraHandler
     {
         if (mUVCTexture2D != null)
             Destroy(mUVCTexture2D);
+
+        // 获取 Quad
+        var quadInCamera = screenIdentification?.Screen?.QuadInCamera;
+        if (quadInCamera != null)
+        {
+            List<Vector2> quad = quadInCamera.GetUnityVertexNormalizedList();
+            if (quad != null && quad.Count == 4)
+            {
+                // 原顺序:左下、右下、左上、右上
+                mUVCTexture2D = TextureToTexture2DWithShader(mUVCTexture, quadMaskMat, quad);
+
+                // 纹理测试显示
+                InfraredDemo._ins.MyCameraRender6.texture = mUVCTexture2D;
+                return;
+            }
+        }
+
+        // 无效 quad 或为空时直接复制原始纹理
         mUVCTexture2D = TextureToTexture2D(mUVCTexture, width, height);
+
     }
 
     #region DoubleButton