devNotes 9-3-16 Geometry Shaders Generating Tetrahedrons

[maxvertexcount(6)]
void GS( point GS_INPUT point[1], inout TriangleStream<PS_INPUT> triStream )
{
    PS_INPUT v1,v2,v3,v4,v5,v6;
    triStream.Append(v1);
    triStream.Append(v2);
    triStream.Append(v3);
    triStream.RestartStrip();
    triStream.Append(v4);
    triStream.Append(v5);
    triStream.Append(v6);
}

DX GEOMETRY SHADER REFERENCE

 
Shader "Geom/GeometryPyramidLit"
 
{
 
    Properties
 
    {
 
        _Color ("Main Color", Color) = (1,1,1,1)
 
        _MainTex ("Particle Texture", 2D) = "white" {}
 
        _Explode ("Explode factor", Range(0.0, 4.0)) = 1.0
 
    }
 
 
 
    SubShader
 
    {
 
        Tags { "RenderType"="Opaque" }
 
        LOD 200
 
           
 
        Pass
 
        {  
 
            Name "FORWARD"
 
            Tags { "LightMode" = "ForwardBase" }
 
   
 
            CGPROGRAM
 
            #pragma target      5.0
 
           
 
            #pragma vertex      vert
 
            #pragma geometry    geom
 
            #pragma fragment    frag            
 
           
 
            #pragma fragmentoption ARB_precision_hint_fastest
 
            #pragma multi_compile_fwdbase
 
           
 
            #include "HLSLSupport.cginc"
 
            #include "UnityShaderVariables.cginc"
 
           
 
            #define UNITY_PASS_FORWARDBASE
 
           
 
            #include "UnityCG.cginc"
 
            #include "Lighting.cginc"
 
            #include "AutoLight.cginc"
 
           
 
            #define INTERNAL_DATA
 
            #define WorldReflectionVector(data,normal) data.worldRefl
 
            #define WorldNormalVector(data,normal) normal
 
 
 
            #pragma only_renderers d3d11
 
            //#pragma surface surf Lambert                                  
 
            //#pragma debug
 
                       
 
            sampler2D   _MainTex;
 
            fixed4      _Color;
 
            float       _Explode;
 
                                               
 
            struct Input
 
            {
 
                float2 uv_MainTex;
 
            };
 
                       
 
            void surf (Input IN, inout SurfaceOutput o)
 
            {
 
                fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
 
                o.Albedo = c.rgb;
 
                o.Alpha  = c.a;
 
            }      
 
           
 
            struct v2f_surf
 
            {
 
                float4 pos : SV_POSITION;
 
                float2 pack0 : TEXCOORD0;
 
                fixed3 normal : TEXCOORD1;
 
                fixed3 vlight : TEXCOORD2;
 
                LIGHTING_COORDS(3,4)
 
            //  float3 _LightCoord : TEXCOORD3;
 
            //  float3 _ShadowCoord : TEXCOORD4;                
 
            };
 
                               
 
            float4 _MainTex_ST;
 
                       
 
            v2f_surf vert (appdata_full v)
 
            {
 
                v2f_surf o;
 
                     
 
                o.pos = v.vertex; // mul (UNITY_MATRIX_MVP, v.vertex);
 
                o.pack0.xy = TRANSFORM_TEX(v.texcoord, _MainTex);
 
                                       
 
                float3 worldN = mul((float3x3)_Object2World, SCALED_NORMAL);
 
               
 
                o.normal = worldN;
 
           
 
                float3 shlight = ShadeSH9 (float4(worldN,1.0));
 
                o.vlight = shlight;
 
               
 
                #ifdef VERTEXLIGHT_ON
 
                    float3 worldPos = mul(_Object2World, v.vertex).xyz;
 
                    o.vlight += Shade4PointLights (
 
                    unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0,
 
                    unity_LightColor[0].rgb, unity_LightColor[1].rgb, unity_LightColor[2].rgb, unity_LightColor[3].rgb,
 
                    unity_4LightAtten0, worldPos, worldN );
 
                #endif // VERTEXLIGHT_ON
 
           
 
                TRANSFER_VERTEX_TO_FRAGMENT(o);
 
             
 
                return o;
 
            }
 
           
 
       
 
                // Geometry Shader
 
                [maxvertexcount(12)]
 
                void geom( triangle v2f_surf input[3], inout TriangleStream<v2f_surf> outStream )
 
                {                  
 
                    v2f_surf output;
                                   
 
                    // Calculate the face normal
 
                    float3 faceEdgeA = input[1].pos - input[0].pos;
 
                    float3 faceEdgeB = input[2].pos - input[0].pos;
 
                    float3 faceNormal = normalize( cross(faceEdgeA, faceEdgeB) );
 
                    float3 ExplodeAmt = faceNormal*_Explode;
 
                   
 
                    // Calculate the face center                
 
                    float3 centerPos = (input[0].pos.xyz + input[1].pos.xyz + input[2].pos.xyz)/3.0;
 
                    float2 centerTex = (input[0].pack0 + input[1].pack0 + input[2].pack0)/3.0;
 
                    centerPos += faceNormal*_Explode;                  
                                   
                    // Output the pyramid          
 
                    for( int looper=0; looper<3; looper++ )
 
                    {
 
                        output.pos = input[looper].pos + float4(ExplodeAmt,0);                                          
 
                        output.pos = mul(UNITY_MATRIX_MVP, output.pos);                
 
                        output.normal = input[looper].normal;
 
                        output.pack0 = input[looper].pack0;
 
                        output.vlight = input[looper].vlight;
                         TRANSFER_VERTEX_TO_FRAGMENT(output);
                       // output._ShadowCoord = input[looper]._ShadowCoord;
 
                   //     output._LightCoord  = input[looper]._LightCoord;
 
                        outStream.Append( output );
       
                        uint iNext = looper+1;
 
                        if(iNext>2)
                        {
                            iNext=0;
                        }
                        output.pos = input[iNext].pos + float4(ExplodeAmt,0);
 
                        output.pos = mul(UNITY_MATRIX_MVP, output.pos);
 
                        output.normal = input[iNext].normal;
 
                        output.pack0 = input[iNext].pack0;
 
                        output.vlight = input[iNext].vlight;
 
                  //      output._ShadowCoord = input[iNext]._ShadowCoord;
 
                  //      output._LightCoord  = input[iNext]._LightCoord;  
 
                        outStream.Append( output );
 
                                               
 
                        output.pos = float4(centerPos,1) + float4(ExplodeAmt,0);
 
                        output.pos = mul(UNITY_MATRIX_MVP, output.pos);                  
 
                        output.normal = faceNormal;
 
                        output.pack0 = centerTex;
 
                        output.vlight = input[looper].vlight;
 
                   //     output._ShadowCoord = input[looper]._ShadowCoord;
 
                   //     output._LightCoord  = input[looper]._LightCoord;
 
                        outStream.Append( output );
 
                       
 
                        outStream.RestartStrip();
 
                    }
 
                   
 
                    for(int cpt=2; cpt>=0; cpt-- )
 
                    {
 
                        output.pos = input[cpt].pos + float4(ExplodeAmt,0);
 
                        output.pos = mul(UNITY_MATRIX_MVP, output.pos);
 
                        output.normal = -input[cpt].normal;
 
                        output.pack0 = input[cpt].pack0;
 
                        output.vlight = input[cpt].vlight;
 
                   //     output._ShadowCoord = input[looper]._ShadowCoord;
 
                   //     output._LightCoord  = input[looper]._LightCoord;
 
                        outStream.Append( output );
 
                    }
 
                    outStream.RestartStrip();
 
                }                  
 
           
 
            fixed4 frag (v2f_surf IN) : COLOR
 
            {
 
                Input surfIN;
 
                surfIN.uv_MainTex = IN.pack0.xy;
 
               
 
                #ifdef UNITY_COMPILER_HLSL
 
                    SurfaceOutput o = (SurfaceOutput)0;
 
                #else
 
                    SurfaceOutput o;
 
                #endif
 
               
 
                o.Albedo    = 0.0;
 
                o.Emission  = 0.0;
 
                o.Specular  = 0.0;
 
                o.Alpha     = 0.0;
 
                o.Gloss     = 0.0;  
 
                o.Normal = IN.normal;
 
                               
 
                surf (surfIN, o);
 
                fixed atten = LIGHT_ATTENUATION(IN);
 
                fixed4 c = 0;                
 
               
 
                c = LightingLambert (o, _WorldSpaceLightPos0.xyz, atten);          
 
                c.rgb += o.Albedo * IN.vlight;  
 
               
 
                return c;
 
            }
 
           
 
            ENDCG          
 
        } // Pass ForwardBase      
 
       
 
    } // subshader
 
 
 
    Fallback Off
 
}

GLSL to HLSL – MS

HLSL uses Column-Major and XNAMath uses ROW-Major. Transpose your matrices before supplying it to the HLSL Shader should work. I was confused too two days ago.

 

Tetrahedron – Dimensions

Regular_Tetrahedron_1

Dimensions
Length of tetrahedron edge: a.
The height of an regular tetrahedron:
h = sqrt (2/3) * a ;

The radius of circumsphere:
R = sqrt( 3/8 ) * a ;

The height of the incenter O or 
the radius of the insphere:
r = 1/3 * R or   r = 1/sqrt(24) * a ;

The radius of midsphere (tangent to edges):
rm = 1/sqrt(8) * a ;

The angle between two faces: ~ 70,53 (yellow)
Angle(C,MAB,D) = degrees(atan(2*sqrt(2)));

The angle between an edge and a face: ~ 54,74 (green)
Angle(0,A,D) = degrees( atan(sqrt(2)));

The angle vertex-center-vertex: ~ 109.471 (violet)
Angle(A,0,D) = degrees( acos( -1/3 ));

jijijij


void make_face(vec3 a, vec3 b, vec3 c)
{
    vec3 face_normal = normalize(cross(c - a, c - b));
    vec4 face_color = vec4(1.0, 0.2, 0.4, 1.0) * (mat3(mvMatrix) * face_normal
    gl_Position = mvpMatrix * vec4(a, 1.0);
    color = face_color;
    EmitVertex();
 
    gl_Position = mvpMatrix * vec4(b, 1.0);
    color = face_color;
    EmitVertex();
 
    gl_Position = mvpMatrix * vec4(c, 1.0);
    color = face_color;
    EmitVertex();
 
    EndPrimitive();
}

 

make_face(a, d, f);
make_face(d, b, e);
make_face(e, c, f);
make_face(d, e, f);

geometry

 

Regular_Tetrahedron_1

 

jh,jh,j