Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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
3
Question by thrmotta · Jul 09, 2014 at 09:51 PM · shadermeshcubedirectx

Constructing a Cube Primitive using Shader

Ive been trying to construct a Cube Primitive using Shaders, but havent really got anything to appear on the screen. Im using Unity Pro 4.3.1f1 at Windows 7 and using a GTX 260 as graphic card. The "Use Direct 3D 11" option at Player Settings is enable.

The reason I need to construct a Cube Primitive using Shader is that I need to render a Point Cloud (10k+ points), where every point has got to be rendered using cubes.

This is my try so far:

 Shader "Custom/CubeColor" 
 {    
     Properties 
     {
         _MainTex ("TileTexture", 2D) = "white" {}
         _PointSize("PointSize", Float) = 10 
         _MyColor ("Some Color", Color) = (0,1,0,1) 
     }
     
     SubShader 
     {
         LOD 200
         
         Pass 
         {
             CGPROGRAM
 
             #pragma only_renderers d3d11
             #pragma target 4.0
             
             #include "UnityCG.cginc"
 
             #pragma vertex   myVertexShader
             #pragma geometry myGeometryShader
             #pragma fragment myFragmentShader
     
             struct vIn // Into the vertex shader
             {
                 float4 vertex : POSITION;
                 float4 color  : COLOR0;
             };
             
             struct gIn // OUT vertex shader, IN geometry shader
             {
                 float4 pos : SV_POSITION;
                 float4 col : COLOR0;                
                 float size : PSIZE;
             };
             
              struct v2f // OUT geometry shader, IN fragment shader 
             {
                 float4 pos           : SV_POSITION;
                 float2 uv_MainTex : TEXCOORD0;
                 float4 col : COLOR0;    
             };
             
             float4       _MainTex_ST;
             sampler2D _MainTex; 
             float     _PointSize;
             fixed4 _MyColor; 
             
             // ----------------------------------------------------
             gIn myVertexShader(vIn v)
             {
                 gIn o; // Out here, into geometry shader
                 UNITY_INITIALIZE_OUTPUT(gIn,o);
 
                 // Passing on color to next shader (using .r/.g there as tile coordinate)
                 o.col = _MyColor;//v.color;
                 
                 o.size = _PointSize;
                 
                 // Passing on center vertex (tile to be built by geometry shader from it later)
                 o.pos = v.vertex;
  
                 return o;
             }    
             
             [maxvertexcount(10)]    // 8 vertex
             // ----------------------------------------------------
             // Using "point" type as input, not "triangle"
             void myGeometryShader(point gIn vert[1], inout TriangleStream<v2f> triStream)
             {
                 const float f = _PointSize/2; //half size
                 
                  The 8 vertex positions of a CUBE tile
                 const float4 vc[8] = { float4( -f, -f, -f, 0.0f ),
                                        float4( -f, -f, +f, 0.0f ),
                                        float4( -f, +f, -f, 0.0f ),
                                        float4( -f, +f, +f, 0.0f ),
                                        float4( +f, -f, -f, 0.0f ),
                                        float4( +f, -f, +f, 0.0f ),
                                        float4( +f, +f, -f, 0.0f ),
                                        float4( +f, +f, +f, 0.0f ) };    
                                               
                 const int TRI_STRIP_CUBE[9]  = { 0, 2, 1, 3, 5, 7, 4, 6, 0 };
             
                 v2f v[12]; //for CUBE
                 
                 // Assign new vertices positions (12 new tile vertices, forming CUBE)
                 for (int i=0;i<12;i++) { v[i].pos = vert[0].pos + vc[i];    }
                 
                 // Position in view space
                 for (int i=0;i<6;i++) { v[i].pos = mul(UNITY_MATRIX_MVP, v[i].pos); }
                 
                 // Build the CUBE tile by submitting triangle strip vertices
                 for (int i=0;i<9;i++) triStream.Append(v[TRI_STRIP_CUBE[i]]);
                 triStream.RestartStrip();
              }
              
              // ----------------------------------------------------
             half4 myFragmentShader(v2f IN) : COLOR
             {
                 // Not considering normals/light here. Just texture
                 half4 c = tex2D (_MainTex, IN.uv_MainTex); 
                 return c;
             }
 
             ENDCG
         }
     } 
     FallBack "Diffuse"
 }
 

And the test Mesh is created with the following method:

 void CreateMesh( int startRange, int endRange, Mesh currMesh ) {
         Vector3[] points = new Vector3[maxPointsPerMesh];
         int[] indexes = new int[maxPointsPerMesh];
         Color[] colors = new Color[maxPointsPerMesh];
         for(int i=0;i<points.Length;++i) {
             points[i] = new Vector3(Random.Range(startRange,endRange), Random.Range (startRange,endRange), Random.Range (startRange,endRange));
             indexes[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);
         }
         
         currMesh.vertices = points;
         currMesh.colors = colors;
         currMesh.SetIndices(indexes, MeshTopology.Points,0);
         
     }


My Game Object has a MeshFilter and a MeshRenderer.

What am I doing wrong?

Thank you all!

Comment
Add comment
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

2 Replies

· Add your reply
  • Sort: 
avatar image
1

Answer by thrmotta · Jul 15, 2014 at 06:31 PM

I finally made it, and it also worked on my previous hardware. Thank you @Bunny85 for your marvelous help! Here is the code that got it working:

 Shader "Custom/CubeShader" 
 {        
     Properties 
     {
         _MainTex ("TileTexture", 2D) = "white" {}
         _PointSize("Point Size", Float) = 1.0
     }
     
     SubShader 
     {
         LOD 200
         
         Pass 
         {
             CGPROGRAM
 
             #pragma only_renderers d3d11
             #pragma target 4.0
             
             #include "UnityCG.cginc"
 
             #pragma vertex   myVertexShader
             #pragma geometry myGeometryShader
             #pragma fragment myFragmentShader
             
             #define TAM 36
                         
             struct vIn // Into the vertex shader
             {
                 float4 vertex : POSITION;
                 float4 color  : COLOR0;
             };
             
             struct gIn // OUT vertex shader, IN geometry shader
             {
                 float4 pos : SV_POSITION;
                 float4 col : COLOR0;
             };
             
              struct v2f // OUT geometry shader, IN fragment shader 
             {
                 float4 pos           : SV_POSITION;
                 float2 uv_MainTex : TEXCOORD0;
                 float4 col : COLOR0;
             };
             
             float4       _MainTex_ST;
             sampler2D _MainTex; 
             float     _PointSize;            
             // ----------------------------------------------------
             gIn myVertexShader(vIn v)
             {
                 gIn o; // Out here, into geometry shader
                 // Passing on color to next shader (using .r/.g there as tile coordinate)
                 o.col = v.color;                
                 // Passing on center vertex (tile to be built by geometry shader from it later)
                 o.pos = v.vertex;
  
                 return o;
             }
             
             // ----------------------------------------------------
             
             [maxvertexcount(TAM)] 
             // ----------------------------------------------------
             // Using "point" type as input, not "triangle"
             void myGeometryShader(point gIn vert[1], inout TriangleStream<v2f> triStream)
             {                            
                 float f = _PointSize/20.0f; //half size
                 
                 const float4 vc[TAM] = { float4( -f,  f,  f, 0.0f), float4(  f,  f,  f, 0.0f), float4(  f,  f, -f, 0.0f),    //Top                                 
                                          float4(  f,  f, -f, 0.0f), float4( -f,  f, -f, 0.0f), float4( -f,  f,  f, 0.0f),    //Top
                                          
                                          float4(  f,  f, -f, 0.0f), float4(  f,  f,  f, 0.0f), float4(  f, -f,  f, 0.0f),     //Right
                                          float4(  f, -f,  f, 0.0f), float4(  f, -f, -f, 0.0f), float4(  f,  f, -f, 0.0f),     //Right
                                          
                                          float4( -f,  f, -f, 0.0f), float4(  f,  f, -f, 0.0f), float4(  f, -f, -f, 0.0f),     //Front
                                          float4(  f, -f, -f, 0.0f), float4( -f, -f, -f, 0.0f), float4( -f,  f, -f, 0.0f),     //Front
                                          
                                          float4( -f, -f, -f, 0.0f), float4(  f, -f, -f, 0.0f), float4(  f, -f,  f, 0.0f),    //Bottom                                         
                                          float4(  f, -f,  f, 0.0f), float4( -f, -f,  f, 0.0f), float4( -f, -f, -f, 0.0f),     //Bottom
                                          
                                          float4( -f,  f,  f, 0.0f), float4( -f,  f, -f, 0.0f), float4( -f, -f, -f, 0.0f),    //Left
                                          float4( -f, -f, -f, 0.0f), float4( -f, -f,  f, 0.0f), float4( -f,  f,  f, 0.0f),    //Left
                                          
                                          float4( -f,  f,  f, 0.0f), float4( -f, -f,  f, 0.0f), float4(  f, -f,  f, 0.0f),    //Back
                                          float4(  f, -f,  f, 0.0f), float4(  f,  f,  f, 0.0f), float4( -f,  f,  f, 0.0f)     //Back
                                          };
                                          
                 
                 const float2 UV1[TAM] = { float2( 0.0f,    0.0f ), float2( 1.0f,    0.0f ), float2( 1.0f,    0.0f ),         //Esta em uma ordem
                                           float2( 1.0f,    0.0f ), float2( 1.0f,    0.0f ), float2( 1.0f,    0.0f ),         //aleatoria qualquer.
                                           
                                           float2( 0.0f,    0.0f ), float2( 1.0f,    0.0f ), float2( 1.0f,    0.0f ), 
                                           float2( 1.0f,    0.0f ), float2( 1.0f,    0.0f ), float2( 1.0f,    0.0f ),
                                           
                                           float2( 0.0f,    0.0f ), float2( 1.0f,    0.0f ), float2( 1.0f,    0.0f ), 
                                           float2( 1.0f,    0.0f ), float2( 1.0f,    0.0f ), float2( 1.0f,    0.0f ),
                                           
                                           float2( 0.0f,    0.0f ), float2( 1.0f,    0.0f ), float2( 1.0f,    0.0f ), 
                                           float2( 1.0f,    0.0f ), float2( 1.0f,    0.0f ), float2( 1.0f,    0.0f ),
                                           
                                           float2( 0.0f,    0.0f ), float2( 1.0f,    0.0f ), float2( 1.0f,    0.0f ), 
                                           float2( 1.0f,    0.0f ), float2( 1.0f,    0.0f ), float2( 1.0f,    0.0f ),
                                           
                                           float2( 0.0f,    0.0f ), float2( 1.0f,    0.0f ), float2( 1.0f,    0.0f ), 
                                           float2( 1.0f,    0.0f ), float2( 1.0f,    0.0f ), float2( 1.0f,    0.0f )                                            
                                             };    
                                                             
                 const int TRI_STRIP[TAM]  = {  0, 1, 2,  3, 4, 5,
                                                6, 7, 8,  9,10,11,
                                               12,13,14, 15,16,17,
                                               18,19,20, 21,22,23,
                                               24,25,26, 27,28,29,
                                               30,31,32, 33,34,35  
                                               }; 
                                                             
                 v2f v[TAM];
                 int i;
                 
                 // Assign new vertices positions 
                 for (i=0;i<TAM;i++) { v[i].pos = vert[0].pos + vc[i]; v[i].col = vert[0].col;    }
 
                 // Assign UV values
                 for (i=0;i<TAM;i++) v[i].uv_MainTex = TRANSFORM_TEX(UV1[i],_MainTex); 
                 
                 // Position in view space
                 for (i=0;i<TAM;i++) { v[i].pos = mul(UNITY_MATRIX_MVP, v[i].pos); }
                     
                 // Build the cube tile by submitting triangle strip vertices
                 for (i=0;i<TAM/3;i++)
                 { 
                     triStream.Append(v[TRI_STRIP[i*3+0]]);
                     triStream.Append(v[TRI_STRIP[i*3+1]]);
                     triStream.Append(v[TRI_STRIP[i*3+2]]);    
                                     
                     triStream.RestartStrip();
                 }
              }
              
              // ----------------------------------------------------
             float4 myFragmentShader(v2f IN) : COLOR
             {
                 //return float4(1.0,0.0,0.0,1.0);
                 return IN.col;
             }
 
             ENDCG
         }
     } 
 }
 
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
avatar image
0

Answer by Bunny83 · Jul 09, 2014 at 10:35 PM

Well, haven't used a geometry shader yet, mainly because i don't have a dx11 card :D (i'm still on winxp 32bit with dx9.0c).

However your cube creation looks a bit strange:

  • First of all a cube needs 24 vertices, not 12. You have 6 sides with 4 vertices each.

  • Next thing is your "vc" array has a size of 8 but you use your for variable "i" which goes up to index 11 so you're out of bounds here.

  • Why do you only multiply the first 6 elements in your "v" array with the MVP?

  • Why do you only have 9 indices? shouldn't that be 36 indices? (`6*2*3`)

  • Finally it seems you map a texture in your fragment shader but you don't set any uvs when you create the new vertices.

Well, as i said i haven't written a geometry shaders yet, but i guess it should be something like that:

 [maxvertexcount(24)] // 24 vertices
 void myGeometryShader(point gIn vert[1], inout TriangleStream<v2f> triStream)
 {
     const float f = _PointSize/2; //half size
     const float4 vc[8] = { float4( -f, -f, -f, 0.0f ),  //0
                            float4( -f, -f, +f, 0.0f ),  //1
                            float4( -f, +f, -f, 0.0f ),  //2
                            float4( -f, +f, +f, 0.0f ),  //3
                            float4( +f, -f, -f, 0.0f ),  //4
                            float4( +f, -f, +f, 0.0f ),  //5
                            float4( +f, +f, -f, 0.0f ),  //6
                            float4( +f, +f, +f, 0.0f ) };//7
     const int VERT_ORDER[24] = {0,1,3,2, // left
                                 0,2,6,4, // front  
                                 4,6,7,5, // right
                                 7,3,1,5, // back
                                 2,3,7,6, // top
                                 0,4,5,1  // bottom
                                };
     v2f v[24]; //for CUBE
      
     // Assign new vertices positions (24 new tile vertices, forming CUBE)
     for (int i=0;i<24;i++) { v[i].pos = vert[0].pos + vc[VERT_ORDER[i]]; }
      
     // Position in view space
     for (int i=0;i<24;i++) { v[i].pos = mul(UNITY_MATRIX_MVP, v[i].pos); }
      
     // Build the CUBE tile by submitting triangle strip vertices
     for (int i=0;i<6;i++)
     {
         triStream.Append(v[i*4 + 0]);
         triStream.Append(v[i*4 + 1]);
         triStream.Append(v[i*4 + 3]);
         triStream.Append(v[i*4 + 2]);
         triStream.RestartStrip();
     }
 }

I can't test it, so if you have some time, feel free to go ahead ;) Oh, i didn't calculated uvs yet, so the cube will have the same color. Since your vertex-struct doesn't have a normal, i'm not sure if the lighting will work as it should.

Comment
Add comment · Show 9 · 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 Bunny83 · Jul 09, 2014 at 10:37 PM 0
Share

ps: I would love to play around with a gShader now, but i'll have to wait until i'm ready for some new hardware ;)

avatar image thrmotta · Jul 09, 2014 at 10:47 PM 0
Share

Its mainly because this is the first shader Im building =D

After searching GitHub I found a marching cubes sample and modified it to the following

avatar image Bunny83 · Jul 09, 2014 at 11:38 PM 0
Share

@thrmotta: Edited my answer and added the cube code i've just written from scratch ;) $$anonymous$$aybe i made a mistake when setting up the vert order array (solving rubic's cube in your $$anonymous$$d might helps here...) but in general it should work like that.

The vert order array actually duplicates each vertex 3 times and forms quads. Finally we add two triangles for each quad, so 4 vertices become 6 (or 24 become 36)

avatar image Bunny83 · Jul 09, 2014 at 11:39 PM 0
Share

Just changed the "maxvertexcount" to 36 since each "point" will emit 36 vertices

avatar image Bunny83 · Jul 10, 2014 at 12:03 AM 0
Share

Just read somewhere that the topology in a geometry shader is always "strip", so we can actually create quads with a triangle strip. I changed the order to match the usual "strip rules" and also moved RestartStrip inside the for loop, so after each quad we start a new one.

Show more comments

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

3 People are following this question.

avatar image avatar image avatar image

Related Questions

Cube botttom transparent with shader? 1 Answer

How to determine shader center? 0 Answers

How do I get mesh data into post-processing shader (or render a mesh shader to a texture)? 0 Answers

Need help with using world position in shader 1 Answer

Standard shader not working on procedural mesh 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