【问题标题】:Mapping a texture to a Pointcloud in Unity在 Unity 中将纹理映射到点云
【发布时间】:2021-04-29 04:37:03
【问题描述】:

我有一个专有的点云文件,然后将其转换为在 Unity 中显示的网格。网格由点云的每个点所在的顶点组成。我正在尝试以纹理与点 100% 对齐的方式将纹理映射到点云。我正在尝试使用着色器来完成此操作,但似乎我没有足够的知识来做到这一点。我以前从未使用过点云和着色器,所以我真的很难做到这一点。

纹理和点云的x和y大小相同,比例为16:10(1920x1200)

我的灵感来自我在assetStore 上找到的着色器资源。据我所知,着色器在网格中的每个顶点上创建一个小四边形,然后获取 UV 贴图信息并将纹理映射到点。我从网上下载了UV贴图,贴图时应该是中性的,没有修改:

UV Map that I use

我目前的成绩不好。默认情况下,纹理在 x 和 y 轴上都放大大约 2 倍。当手动调整两个轴的比例和偏移量时,我可以获得一些正确的结果,但只能在图像的一部分上。然后其他部分需要不同的偏移/比例组合。我尝试了很多东西都没有成功,但我很确定解决方案在于着色器代码,因为其他修改对纹理映射过程没有影响。

由于是保密的,所以我无法向您展示该项目的所有细节,这个问题可能很难回答。幸运的是,我可以向您展示着色器代码:

    Properties {
        [NoScaleOffset]_MainTex ("Texture", 2D) = "white" {}
        [NoScaleOffset]_UVMap ("UV", 2D) = "white" {}
        _TexScaleH("Uv texture scaler H", Float) = 1.0
        _TexScaleV("Uv texture scaler V", Float) = 1.0
        _PointSize("Point Size", Float) = 4.0
        _Color("PointCloud Color", Color) = (1, 1, 1, 1)
        _OffsetH("Horizontal offset", Float) = 0.0
        _OffsetV("Vertical offset", Float) = 0.0
    }

    SubShader
    {
        Cull Off
        Pass 
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma geometry geom
            #pragma fragment frag
            #pragma shader_feature USE_DISTANCE
            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
                float2 uv : TEXCOORD0;
            };

            float _PointSize;
            fixed4 _Color;

            sampler2D _MainTex;
            float4 _MainTex_TexelSize;
            float _OffsetH;
            float _OffsetV;

            sampler2D _UVMap;
            float4 _UVMap_TexelSize;
            float _TexScaleH;
            float _TexScaleV;

            struct g2f
            {
                float4 vertex : SV_POSITION;
                float2 uv : TEXCOORD0;
            };

            [maxvertexcount(4)]
            void geom(point v2f i[1], inout TriangleStream<g2f> triStream)
            {
                g2f o;
                float4 v = i[0].vertex;
                float2 uv = v.xy;
                uv.x = -uv.x;
                uv.y = -uv.y;
                float2 p = _PointSize * 0.001;
                p.y *= _ScreenParams.x / _ScreenParams.y;
                
                o.vertex = UnityObjectToClipPos(v);
                o.vertex += float4(-p.x, p.y, 0, 0) * o.vertex.w;
                o.uv = uv * float3(_TexScaleH,_TexScaleV,0) + float3(_OffsetH,_OffsetV,0);
                triStream.Append(o);

                o.vertex = UnityObjectToClipPos(v);
                o.vertex += float4(-p.x, -p.y, 0, 0) * o.vertex.w;
                o.uv = uv * float3(_TexScaleH, _TexScaleV, 0) + float3(_OffsetH, _OffsetV, 0);
                triStream.Append(o);

                o.vertex = UnityObjectToClipPos(v);
                o.vertex += float4(p.x, p.y, 0, 0) * o.vertex.w;
                o.uv = uv * float3(_TexScaleH, _TexScaleV, 0) + float3(_OffsetH, _OffsetV, 0);
                triStream.Append(o);

                o.vertex = UnityObjectToClipPos(v);
                o.vertex += float4(p.x, -p.y, 0, 0) * o.vertex.w;
                o.uv = uv * float3(_TexScaleH, _TexScaleV, 0) + float3(_OffsetH, _OffsetV, 0);
                triStream.Append(o);

            }

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = v.vertex;
                o.uv = v.uv;
                return o;
            }

            fixed4 frag (g2f i) : SV_Target
            {
                float2 uv = tex2D(_UVMap, i.uv);
                if(any(uv <= 0 || uv >= 1))
                    discard;
                return tex2D(_MainTex, uv) * _Color;
            }
            ENDCG
        }
    }
}

网络上没有很多关于 Unity 中着色器编码的信息,也没有关于点云的信息,所以我现在有点迷茫。

请在下方告诉我您对我可以更改哪些内容来解决问题的想法。

【问题讨论】:

  • 仅供参考,这里有点云库。该领域还有 meshlab 和其他一些。

标签: c# unity3d mesh point-clouds texture-mapping


【解决方案1】:

好吧,我找到了一种方法,但结果并不是我需要的 100%。

Shader "shaderexample"
{
    Properties
    {
        _MainTex("Texture", 2D) = "white" {}
        _PointSize("Point size", Float) = 1.0
    }
        SubShader
    {    
        Pass
        {
        CGPROGRAM
        #pragma vertex vert
        #pragma geometry geom
        #pragma fragment frag

        #include "UnityCG.cginc"

        sampler2D _MainTex;
        float4 _MainTex_ST;
        float _PointSize;

        struct v2f
        {
            float4 vertex : SV_POSITION;
            float2 texcoord : TEXCOORD0;

        };

        struct g2f
        {
            float4 vertex : SV_POSITION;
            float2 texcoord : TEXCOORD0;
        };

        v2f vert(appdata_full v)
        {
            v2f o;
            float4 vertex = mul(unity_ObjectToWorld, v.vertex);
            o.vertex = mul(UNITY_MATRIX_VP, vertex);
            o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
            return o;
        }

        fixed4 frag(g2f i) : SV_Target
        {
            fixed4 color = tex2D(_MainTex, i.texcoord);
            return color;
        }
        ENDCG
    }
}

}

现在每个点都与纹理正确对齐。现在我需要将此功能与我的另一个功能结合起来,即放大网格的每个顶点。变量 _PointSize 应该确定每个顶点应该有多大。我尝试使用前面显示的代码在顶点位置创建小四边形。有谁知道如何结合这两个功能?

maxvertexcount(4)]
void geom(point v2f i[1], inout TriangleStream<g2f> triStream)
{
    g2f o;

    float4 v = i[0].vertex;
    float2 p = _PointSize * 0.001;
    p.y *= _ScreenParams.x / _ScreenParams.y;

    o.vertex = UnityObjectToClipPos(v);
    o.vertex += float4(p.x, p.y, 0, 0) * o.vertex.w;
    triStream.Append(o);

    o.vertex = UnityObjectToClipPos(v);
    o.vertex += float4(p.x, -p.y, 0, 0) * o.vertex.w;
    triStream.Append(o);

    o.vertex = UnityObjectToClipPos(v);
    o.vertex += float4(-p.x, p.y, 0, 0) * o.vertex.w;
    triStream.Append(o);

    o.vertex = UnityObjectToClipPos(v);
    o.vertex += float4(-p.x, -p.y, 0, 0) * o.vertex.w;
    triStream.Append(o);
}

这是着色器的几何部分,应该为每个顶点创建小四边形。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-21
    • 2013-07-15
    • 2018-01-18
    • 2013-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多