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



