Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
12 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by andyMill · Dec 01, 2017 at 11:45 AM · shader programminggeometry shader

,Implementing a Geometry shader for a pointcloud

I am working on a project for college in Unity that involves displaying a very big pointcloud. I have implemented the point cloud as a mesh with 1 vertex per point and no triangles. I want to implement a shader in Unity that creates a triangle for each vertex and colors it of the color of the vertex.

I have no experience with shaders and I have developed the code trying to follow multiple resources online.

At the current state the code simply makes the pointcloud disappear and nothing is displayed.

Thank you!

  Shader "Custom/SpherePoint" {
 Properties {
     _Color ("Color", Color) = (1,1,1,1)
     _Radius ("Sphere Radius", float) = 0.01
 }
  SubShader {
 Tags { "RenderType"="Opaque" }
 LOD 200
 Pass {
     CGPROGRAM
     #pragma vertex vert
     #pragma fragment frag
     #pragma geometry geom
     #pragma target 4.0                  // Use shader model 3.0 target, to get nicer looking lighting
     #include "UnityCG.cginc"

     struct vertexIn {
         float4 pos : POSITION;
         float4 color : COLOR;
         float3 normal : NORMAL;
     };

     struct vertexOut {
         float4 pos : POSITION;
         float4 color : COLOR0;
         float3 normal : NORMAL;
     };

     struct geomOut {
         float4 pos : POSITION;
         float4 color : COLO0R;
         float3 normal : NORMAL;
     };

     //Vertex shader: computes normal wrt camera
     vertexOut vert (vertexIn i) {
         vertexOut o;
         o.pos = UnityObjectToClipPos(i.pos);
         //o.pos = mul(unity_ObjectToWorld, i.pos);
         o.color = i.color;
         //o.normal = normalize(_WorldSpaceCameraPos - mul(unity_ObjectToWorld, o.pos).xyz); //normal is towards the camera
         o.normal = ObjSpaceViewDir(o.pos);
         return o;
     }

     float _Radius;  

     //Geometry shaders: Creates an equilateral triangle with the original vertex in the orthocenter
     [maxvertexcount(3)]
     void geom(point vertexOut i[1], inout TriangleStream<geomOut> OutputStream)
     {
         geomOut o, p;
         float3 perp = float3(i[0].normal.y - i[0].normal.x, i[0].normal.x, i[0].normal.x) * _Radius;

         o.color = i[0].color;
         o.normal = i[0].normal;
         o.pos = i[0].pos;
         o.pos = float4(i[0].pos.x * _Radius, i[0].pos.yz, 1);
         //o.pos = float4(normalize(perp + i[0].pos) * _Radius , 1); //Generic perpendicular to the normal
         OutputStream.Append(o);

         p.color = i[0].color;
         p.normal = i[0].normal;
         p.pos = float4(i[0].pos.x, i[0].pos.y * _Radius, i[0].pos.z, 1);
         //p.pos = float4(   (normalize(cross(i[0].pos.xyz, perp.xyz)) - perp.xyz / 2 + i[0].pos) * _Radius,1);
         OutputStream.Append(p);

         o.color = i[0].color;
         o.normal = i[0].normal;
         o.pos = float4(i[0].pos.x * _Radius, i[0].pos.yz, 1);
         //p.pos = float4(-1 * (normalize(cross(i[0].pos.xyz, perp.xyz)) * _Radius) /* - perp.xyz / 2 + i[0].pos*/, 1);
         OutputStream.Append(p);

         OutputStream.RestartStrip();
     }

     float4 frag(geomOut i) : COLOR
     {
         return i.color;
     }
     ENDCG
 }
 }
    FallBack "Diffuse"
    }

,I am working on a project for college in Unity that involves displaying a very big pointcloud. I have implemented the point cloud as a mesh with 1 vertex per point and no triangles. I want to implement a shader in Unity that creates a triangle for each vertex and colors it of the color of the vertex.

I have no experience with shaders and I have developed the code trying to follow multiple resources online.

At the current state the code simply makes the pointcloud disappear and nothing is displayed.

Thank you!

    Shader "Custom/SpherePoint" {
 Properties {
     _Color ("Color", Color) = (1,1,1,1)
     _Radius ("Sphere Radius", float) = 0.01
 }
 SubShader {
     Tags { "RenderType"="Opaque" }
     LOD 200
     Pass {
         CGPROGRAM
         #pragma vertex vert
         #pragma fragment frag
         #pragma geometry geom

         #pragma target 4.0                    // Use shader model 3.0 target, to get nicer looking lighting
         #include "UnityCG.cginc"

         struct vertexIn {
             float4 pos : POSITION;
             float4 color : COLOR;
             float3 normal : NORMAL;
         };

         struct vertexOut {
             float4 pos : POSITION;
             float4 color : COLOR0;
             float3 normal : NORMAL;
         };

         struct geomOut {
             float4 pos : POSITION;
             float4 color : COLO0R;
             float3 normal : NORMAL;
         };

         //Vertex shader: computes normal wrt camera
         vertexOut vert (vertexIn i) {
             vertexOut o;
             o.pos = UnityObjectToClipPos(i.pos);
             //o.pos = mul(unity_ObjectToWorld, i.pos);
             o.color = i.color;
             //o.normal = normalize(_WorldSpaceCameraPos - mul(unity_ObjectToWorld, o.pos).xyz);    //normal is towards the camera
             o.normal = ObjSpaceViewDir(o.pos);
             return o;
         }

         float _Radius;    

         //Geometry shaders: Creates an equilateral triangle with the original vertex in the orthocenter
         [maxvertexcount(3)]
         void geom(point vertexOut i[1], inout TriangleStream<geomOut> OutputStream)
         {
             geomOut o, p;
             float3 perp = float3(i[0].normal.y - i[0].normal.x, i[0].normal.x, i[0].normal.x) * _Radius;

             o.color = i[0].color;
             o.normal = i[0].normal;
             o.pos = i[0].pos;
             o.pos = float4(i[0].pos.x * _Radius, i[0].pos.yz, 1);
             //o.pos = float4(normalize(perp + i[0].pos) * _Radius , 1);    //Generic perpendicular to the normal
             OutputStream.Append(o);

             p.color = i[0].color;
             p.normal = i[0].normal;
             p.pos = float4(i[0].pos.x, i[0].pos.y * _Radius, i[0].pos.z, 1);
             //p.pos = float4(    (normalize(cross(i[0].pos.xyz, perp.xyz)) - perp.xyz / 2 + i[0].pos) * _Radius,1);
             OutputStream.Append(p);

             o.color = i[0].color;
             o.normal = i[0].normal;
             o.pos = float4(i[0].pos.x * _Radius, i[0].pos.yz, 1);
             //p.pos = float4(-1 * (normalize(cross(i[0].pos.xyz, perp.xyz)) * _Radius) /* - perp.xyz / 2 + i[0].pos*/, 1);
             OutputStream.Append(p);

             OutputStream.RestartStrip();
         }

         float4 frag(geomOut i) : COLOR
         {
             return i.color;
         }
         ENDCG
     }
 }
 FallBack "Diffuse"
   }
Comment
Add comment · Show 7
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image pesch2 · Feb 26, 2018 at 04:32 PM 0
Share

Hi,

I'm also working on a real-time kinect point-cloud visualization for an academic project. I've tried both of the provided answers, but they don't render any point at all. Did you found a working point cloud shader? Would be very helpful! thanks!

avatar image Bunny83 pesch2 · Feb 26, 2018 at 05:56 PM 1
Share

Then you do something wrong. Are you sure that you are actually rendering points? The shader is supposed to receive a mesh that consists of points ($$anonymous$$eshTopology.Points).

I just re-assembled the shader the OP posted with my changes applied. I quickly created a script that creates a point mesh with 2000 random points (`Random.insideUnitSphere * 20;`). The radius is set to "1" in the material and this is the result:

avatar image pesch2 Bunny83 · Feb 26, 2018 at 07:22 PM 0
Share

:) Yeah might be doing something wrong. I'm completely new to shader coding. Thus I wanted to take a look on a working code. I tried your pastbin code. It also produces an invisible pointcloud rendering. Are there any other settings necessary?

I'm using the right meshtopology: _mesh.SetIndices(_indecies, $$anonymous$$eshTopology.Points, 0);

I'm using the $$anonymous$$esh component and Points co$$anonymous$$g from a $$anonymous$$inect v2. Which is working so far. Only the points rendered are very small. And I was searching for a shader that could fix this.

As mentioned, I'm new to shader languages. The Unity $$anonymous$$esh component has this vertices limit of max 65535 Is it possible that the triangle generation somehow exceeds this limit?

If I switch to the editor window an select the pointcloud. I can clearly see the outline of triangles in the selection. But they are not visible to me. pointcloud invisible but outline indicates triangles are generated

EDIT: I've found this project on github: https://github.com/keijiro/Pcx The disc shader is working fine. Still I would be happy to understand what I'm doing wrong with the shader above :)

Show more comments

2 Replies

· Add your reply
  • Sort: 
avatar image
2

Answer by Bunny83 · Dec 01, 2017 at 01:59 PM

Sorry but your geometry shader code doesn't seem to make much sense to me. Keep in mind that the incoming position is in clipspace (range -1 to 1, the center point of the screen is 0,0). You multiply some components the position by radius. Your first and thrid point is identical so the triangle you generate is a degenerated triangle as all 3 points lie on the same line.


You may want to work with worldspace coordinates instead and do the clipspace conversion inside the geometry shader. However from the question it's not clear what the desired output should be.


edit Well, try something like this instead:

 static const fixed SQRT3_6 = sqrt(3)/6;
 float _Radius;  
 float4 _Color;
 [maxvertexcount(3)]
 void geom(point vertexOut i[1], inout TriangleStream<geomOut> OutputStream)
 {
     geomOut p;
     float a = _ScreenParams.x / _ScreenParams.y; // aspect ratio
     float s = _Radius;
     float s2 = s*SQRT3_6 *a;
     
     p.color = i[0].color * _Color;
     p.normal = float3(0,0,1);
     p.pos = i[0].pos + float4(0,s2*2,0,0);
     OutputStream.Append(p);
     p.pos = i[0].pos + float4(-s*0.5f,-s2,0,0);
     OutputStream.Append(p);
     p.pos = i[0].pos + float4(s*0.5f,-s2,0,0);
     OutputStream.Append(p);
     OutputStream.RestartStrip();
 }

The rest should stay the same.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image andyMill · Dec 01, 2017 at 08:27 PM 0
Share

Thank you

I am trying to create a triangle facing the camera for every input vertex, possibly centered on the vertex itself.

avatar image
0

Answer by Buckslice · Dec 01, 2017 at 11:28 PM

Ya you dont need to use the normal to calculate the positions in the geometry shader because they are already in clipspace as Bunny83 pointed out. You could use the normal to do some more complex lighting in the fragment shader if youre interested in that though.

I made a similar geometry shader a while ago so I changed up your shader a bit and added in some comments based on how i did it. Mainly changed your geom function, also added in random rotations of each particle and code for transparency if you want that. Hope this helps!

 Shader "Custom/SpherePoint" {
  Properties {
      _Radius ("Sphere Radius", float) = 1.0
  }
   SubShader {
  LOD 200
  Tags { "RenderType"="Opaque" }
  //if you want transparency
  //Tags { "Queue" = "Transparent" "RenderType" = "Transparent" }
  //Blend SrcAlpha OneMinusSrcAlpha
  Pass {
      CGPROGRAM
      #pragma vertex vert
      #pragma fragment frag
      #pragma geometry geom
      #pragma target 4.0                  // Use shader model 3.0 target, to get nicer looking lighting
      #include "UnityCG.cginc"
      struct vertexIn {
          float4 pos : POSITION;
          float4 color : COLOR;
      };
      struct vertexOut {
          float4 pos : SV_POSITION;
          float4 color : COLOR0;
          float3 normal : NORMAL;
          float r : TEXCOORD0; // not sure if this is good to do lol
      };
      struct geomOut {
          float4 pos : POSITION;
          float4 color : COLO0R;
          float3 normal : NORMAL;
      };
 
      float rand(float3 p){
          return frac(sin(dot(p.xyz, float3(12.9898, 78.233, 45.5432))) * 43758.5453);
      }
      float2x2 rotate2d(float a){
         float s = sin(a);
         float c = cos(a);
         return float2x2(c,-s,s,c);
      }
      //Vertex shader: computes normal wrt camera
      vertexOut vert (vertexIn i) {
          vertexOut o;
          o.pos = UnityObjectToClipPos(i.pos);
          o.color = i.color;
          o.normal = ObjSpaceViewDir(o.pos);
          o.r = rand(i.pos);// calc random value based on object space pos
          // from world space instead (particles will spin when mesh moves, kinda funny lol)
          //o.r = rand(mul(unity_ObjectToWorld,i.pos));
          return o;
      }
 
      float _Radius;  
      //Geometry shaders: Creates an equilateral triangle with the original vertex in the orthocenter
      [maxvertexcount(3)]
      void geom(point vertexOut IN[1], inout TriangleStream<geomOut> OutputStream)
      {
         float2 dim = float2(_Radius,_Radius);
 
         float2 p[3];    // equilateral tri
         p[0] = float2(-dim.x, dim.y * .57735026919);
         p[1] = float2(0., -dim.y * 1.15470053838);
         p[2] = float2(dim.x, dim.y * .57735026919);
 
         float2x2 r = rotate2d(IN[0].r * 3.14159);
 
         geomOut OUT;
         OUT.color = IN[0].color;
         OUT.normal = IN[0].normal;
 
         for (int i = 0; i < 3; i++) {
             p[i] = mul(r,p[i]);    // apply rotation
             p[i].x *= _ScreenParams.y / _ScreenParams.x; // make square
             OUT.pos = IN[0].pos + float4(p[i],0,0) / 2.;
             OutputStream.Append(OUT);
         }
      }
      float4 frag(geomOut i) : COLOR
      {
          return i.color;
          // could do some additional lighting calculation here based on normal
      }
      ENDCG
  }
  }
 FallBack "Diffuse"
 }
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

75 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

What is more efficent? Multiple passes or a single pass with iterative loop? 0 Answers

shell fur in HDRP - possible? 0 Answers

vertex and geometry shader change with distance 0 Answers

Does Unity support GL_NV_geometry_shader_passthrough geometry shaders? 0 Answers

Geometry Shader not writing to depth texture 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges