LoginSignup
2
5

More than 5 years have passed since last update.

UnityのWebGLで点群を表示してみる

Last updated at Posted at 2019-01-24

Unity 2018.3.2f1のWebGL出力で点群を表示できたのでやったことをメモしておく。
(はやくAmazon Sumerianで点群表示をサポートしてほしい)

Unity Editorで点群を表示してみる

表示手順

UnityでPoint Cloudを表示する方法 – NegativeMind – Medium
を参考にして以下のような手順を実施した。

  • 以下のスクリプトを作成する。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class PointCloud : MonoBehaviour
{

    private Mesh mesh;
    int numPoints = 600000;

    // Use this for initialization
    void Start()
    {
        mesh = new Mesh();

        GetComponent<MeshFilter>().mesh = mesh;
        CreateMesh();
    }

    void CreateMesh()
    {
        Vector3[] points = new Vector3[numPoints];
        int[] indecies = new int[numPoints];
        Color[] colors = new Color[numPoints];
        for (int i = 0; i < points.Length; ++i)
        {
            points[i] = new Vector3(Random.Range(-10, 10), Random.Range(-10, 10), Random.Range(-10, 10));
            indecies[i] = i;
            colors[i] = new Color(Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f), 1.0f);
        }

        mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
        mesh.vertices = points;
        mesh.colors = colors;
        mesh.SetIndices(indecies, MeshTopology.Points, 0);

    }
}
  • 以下のシェーダーを作成する
Shader "Custom/VertexColor"
{
    SubShader {
    Pass {
        LOD 200

        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag

        struct VertexInput {
            float4 v : POSITION;
            float4 color: COLOR;
        };

        struct VertexOutput {
            float4 pos : SV_POSITION;
            float4 col : COLOR;
        };

        VertexOutput vert(VertexInput v) {

            VertexOutput o;
            o.pos = UnityObjectToClipPos(v.v);
            o.col = v.color;

            return o;
        }

        float4 frag(VertexOutput o) : COLOR {
            return o.col;
        }

        ENDCG
        } 
    }
}
  • マテリアルを作成して作成したシェーダーを指定する。
  • [CreateEmpty]でGameObjectを作成する。
  • 作成したGameObjectにMesh Rendererコンポーネント、Mesh Filterコンポーネント、作成したスクリプト、作成したマテリアルを割り当てる。
  • 実行する。 pointclouddisplaycapture.PNG

スクリプトについて

以下のように指定しているのでUInt32のMAXまで点群が設定可能。それを超える場合はゲームオブジェクト(メッシュ)の分割が必要。

mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;

WebGLで点群を表示してみる

上記のままでWebGLビルドしても点群が表示されない。

多分以下の問題。
MeshTopology.Point Geometry not displaying in WebGL Builds - Unity Forum
以下のようにすることでWebGLで表示できた。

  • リンク先にあった以下のシェーダーを作成する。
Shader "Custom/PointCloud_GL"
{
    Properties
    {
        _PointSize("PointSize", Float) = 5
        _HeightTex("Height Texture", 2D) = "white" {}
    }

    SubShader
    {
        Pass
        {
            LOD 200

            GLSLPROGRAM
            #pragma multi_compile __ HEIGHTMAP_ON

            #ifdef VERTEX

            out vec4 Color;
            uniform sampler2D _HeightTex;
            uniform float _PointSize;

            float ToneMap(float rawValue)
            {
                float contrast = 3.8;
                float exposure = 0.001;
                float a = exposure * pow(rawValue, contrast);
                return a / (1.0f + a);
            }

            void main()
            {
                gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
                gl_PointSize = _PointSize * (1.0 / gl_Position.w);

                #ifdef HEIGHTMAP_ON
                float index = ToneMap(gl_MultiTexCoord0.x);
                Color = texture2D(_HeightTex, vec2(index, 0));
                #else
                Color = gl_Color;
                #endif
            }

            #endif

            #ifdef FRAGMENT

            in vec4 Color;

            void main()
            {
                vec2 coord = gl_PointCoord - vec2(0.5);
                if (length(coord) > 0.5)
                {
                    discard;
                }

                gl_FragColor = Color;
            }

            #endif

            ENDGLSL
        }
    }
}
  • 上記シェーダーを[Editor] => [Project Settings]の[Always Included Shaders]に登録する。
  • スクリプトのStart()に以下を追加する。
#if !UNITY_EDITOR && UNITY_WEBGL
        gameObject.GetComponent<MeshRenderer>().material.shader = Shader.Find("Custom/PointCloud_GL");
#endif
  • ビルドする。

pointcloudwebgldisplaycapture.PNG

2
5
7

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
5