[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
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 ));
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);