第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定

通過一個(gè)小Trick實(shí)現(xiàn)shader的圖像識(shí)別/圖像統(tǒng)計(jì)操作

標(biāo)簽:
深度學(xué)習(xí)

1.简介

在日常开发中会遇到诸如判断某张图的红色百分比占多少的问题,由于gpu运算并行的原因并不能对其进行累加操作。网上一些针对此类问题

的做法是将一张大图分成多个小块逐步处理并逐步合并:

 

但我在思考一种更简便的方法,于是想到在顶点shader里做判断检测,在像素shader里获取结果这样一个形式:

用一组顶点去读单个像素,判断失败的顶点坐标提交到屏幕外,而判断成功的顶点坐标放在屏幕内。

最后在CPU中获取是否有屏幕内顶点这样一个结果,来进行简单的识别操作。

而在开启透明之后,还可以用透明度叠加来获取更复杂的结果。

 

 

2.实践

首先实践结果并没有想象的那么好,因为如果纯用三角面来做顶点部分的判断未免太费效率了。

所以我改成了传入顶点判断并生成面的方式,并且缩小了传入图片的像素大小。

毕竟更多的运用场合是用来做刮刮卡或者擦除的识别。只需要检测mask图片。

 

上代码:

Shader "Hidden/FooShader"{
    Properties
    {
    }
    SubShader
    {
        Blend One One

        tags
        {            "Queue" = "Transparent"
            "RenderType" = "Transparent"
        }

        Pass
        {
            CGPROGRAM            #pragma target 4.0            #pragma vertex vert            #pragma geometry geom            #pragma fragment frag

            #include "UnityCG.cginc"

            struct v2f
            {
                float4 color : COLOR;
                float4 vertex : SV_POSITION;
            };

            v2f vert(uint vid : SV_VertexID)
            {
                v2f o = (v2f)0;

                o.vertex = 0;                int roll = vid % 4;                if(roll == 0)
                    o.color = float4(0.05, 0, 0, 0);                if (roll == 1)
                    o.color = float4(0, 0.05, 0, 0);                if (roll == 2)
                    o.color = float4(0, 0, 0.05, 0);                if (roll == 3)
                    o.color = float4(0, 0, 0, 0.05);                return o;
            }

            [maxvertexcount(4)]            void geom(point v2f vertElement[1], inout TriangleStream<v2f> triStream)
            {                float size = 10;

                float4 v1 = vertElement[0].vertex + float4(-size, -size, 0, 0);
                float4 v2 = vertElement[0].vertex + float4(-size, size, 0, 0);
                float4 v3 = vertElement[0].vertex + float4(size, -size, 0, 0);
                float4 v4 = vertElement[0].vertex + float4(size, size, 0, 0);

                v2f r = (v2f)0;

                r.vertex = mul(UNITY_MATRIX_VP, v1);
                r.color = vertElement[0].color;
                triStream.Append(r);

                r.vertex = mul(UNITY_MATRIX_VP, v2);
                r.color = vertElement[0].color;
                triStream.Append(r);

                r.vertex = mul(UNITY_MATRIX_VP, v3);
                r.color = vertElement[0].color;
                triStream.Append(r);

                r.vertex = mul(UNITY_MATRIX_VP, v4);
                r.color = vertElement[0].color;
                triStream.Append(r);
            }

            fixed4 frag(v2f i) : SV_Target
            {                return i.color;
            }
            ENDCG
        }
    }
}

FooShader.shader

 

using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.Rendering;namespace Hont
{    public class Foo : MonoBehaviour
    {        void Start()
        {            var mat = new Material(Shader.Find("Hidden/FooShader"));
            mat.SetPass(0);            var tempRT = RenderTexture.GetTemporary(16, 16, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.sRGB, 1);
            tempRT.filterMode = FilterMode.Point;
            tempRT.autoGenerateMips = false;
            tempRT.anisoLevel = 0;
            tempRT.wrapMode = TextureWrapMode.Clamp;            var cacheRT = RenderTexture.active;
            RenderTexture.active = tempRT;
            Graphics.DrawProcedural(MeshTopology.Points, 10, 1);            var tex2D = new Texture2D(16, 16, TextureFormat.ARGB32, false, false);
            tex2D.wrapMode = TextureWrapMode.Clamp;
            tex2D.anisoLevel = 0;
            tex2D.filterMode = FilterMode.Point;
            tex2D.ReadPixels(new Rect(0, 0, 16, 16), 0, 0);            var firstPixel = tex2D.GetPixel(0, 0);
            Debug.Log("firstPixel: " + firstPixel);
            RenderTexture.active = cacheRT;
            RenderTexture.ReleaseTemporary(tempRT);
        }
    }
}

Foo.cs

 

跑了一下代码之后我发现了两个问题,也是没解决的问题,一个是计算结果有误差

o.color = float4(0.05, 0, 0, 0);

输出是0.05结果却有一些出入。

特别是当返回颜色小于0.1之后,我尝试改变图像格式或者RT等参数依旧没能解决

第二个问题是开启透明后,透明图片的叠加是有上限的,毕竟深度有限。

 

对于第一个问题,目前还不需要太精确所以没解决但也能用。第二个问题可以用一些方法来缓解

比如在顶点shader中增加运算量,把返回值分散到rgba四个通道上去。

复制代码

int roll = vid % 4;if(roll == 0)
    o.color = float4(0.05, 0, 0, 0);if (roll == 1)
    o.color = float4(0, 0.05, 0, 0);if (roll == 2)
    o.color = float4(0, 0, 0.05, 0);if (roll == 3)
    o.color = float4(0, 0, 0, 0.05);return o;

复制代码

 

把更多的像素遍历放入顶点中,这样顶点shader处理的图片大小是n/1:

复制代码

v2f vert(uint vid : SV_VertexID)
{
    v2f o = (v2f)0;

    o.vertex = 0;

    half2 image_size = half2(_SampleFilter.x * _LoopImageSize.x, _SampleFilter.y * _LoopImageSize.y);

    half y = floor(vid / _LoopImageSize.x);
    half x = (vid - y * _LoopImageSize.x) / _LoopImageSize.x;
    y = y / _LoopImageSize.y;    for (half rx = 0; rx < _SampleFilter.x; rx++)
    {        for (half ry = 0; ry < _SampleFilter.y; ry++)
        {
            half xx = x + rx;
            half yy = y + ry;

            float4 r = statistics_sample(_Image, _Rec_Color, half4(xx, yy, 0, 0), image_size);

            o.color += r;
        }
    }    return o;
}

复制代码

 

3.优化再测试

最终达到了一个比较不错的结果,我把相关函数封装成了一个类。

 

我写了一个涂抹效果demo来测试一下,它通过识别白色像素的数量来判断是否为全部涂完:

 

 

工程文件我丢在了github上:https://github.com/hont127/Image-Rec-Base-unity-shader-

通过这个小Trick其实可以在像素里返回更多的信息,简单的场合这么还是比较方便的,当然一些复杂的情况分块+computer shader来做其实更合适。

原文出处:https://www.cnblogs.com/hont/p/9977401.html  

點(diǎn)擊查看更多內(nèi)容
TA 點(diǎn)贊

若覺得本文不錯(cuò),就分享一下吧!

評(píng)論

作者其他優(yōu)質(zhì)文章

正在加載中
  • 推薦
  • 評(píng)論
  • 收藏
  • 共同學(xué)習(xí),寫下你的評(píng)論
感謝您的支持,我會(huì)繼續(xù)努力的~
掃碼打賞,你說多少就多少
贊賞金額會(huì)直接到老師賬戶
支付方式
打開微信掃一掃,即可進(jìn)行掃碼打賞哦
今天注冊(cè)有機(jī)會(huì)得

100積分直接送

付費(fèi)專欄免費(fèi)學(xué)

大額優(yōu)惠券免費(fèi)領(lǐng)

立即參與 放棄機(jī)會(huì)
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)

舉報(bào)

0/150
提交
取消