1+ /* Copyright (c) 2025, Sascha Willems
2+ *
3+ * SPDX-License-Identifier: MIT
4+ *
5+ */
6+
7+ struct VSInput
8+ {
9+ float3 Pos;
10+ float3 Normal;
11+ float3 Color;
12+ };
13+
14+ struct VSOutput
15+ {
16+ float4 Pos : SV_POSITION;
17+ float3 Normal;
18+ float3 Color;
19+ };
20+
21+ struct GSOutput
22+ {
23+ float4 Pos : SV_POSITION;
24+ uint ViewportIndex : SV_ViewportArrayIndex;
25+ uint PrimitiveID : SV_PrimitiveID;
26+ float3 Normal;
27+ float3 Color;
28+ float3 ViewVec;
29+ float3 LightVec;
30+ }
31+
32+ struct UBO
33+ {
34+ float4x4 projection [2 ];
35+ float4x4 modelview [2 ];
36+ float4 lightPos;
37+ };
38+ ConstantBuffer < UBO> ubo;
39+
40+ [shader(" vertex" )]
41+ VSOutput vertexMain(VSInput input)
42+ {
43+ VSOutput output;
44+ output .Color = input .Color ;
45+ output .Normal = input .Normal ;
46+ output .Pos = float4(input .Pos .xyz , 1 . 0 );
47+ return output;
48+ }
49+
50+ [shader(" geometry" )]
51+ [maxvertexcount(3 )]
52+ [instance(2 )]
53+ void geometryMain(triangle VSOutput input [3 ], inout TriangleStream< GSOutput> outStream, uint InvocationID: SV_GSInstanceID, uint PrimitiveID: SV_PrimitiveID)
54+ {
55+ for (int i = 0 ; i < 3 ; i++ )
56+ {
57+ GSOutput output;
58+ output .Normal = mul((float3x3 )ubo .modelview [InvocationID], input [i].Normal );
59+ output .Color = input [i].Color ;
60+
61+ float4 pos = input [i].Pos ;
62+ float4 worldPos = mul(ubo .modelview [InvocationID], pos);
63+
64+ float3 lPos = mul(ubo .modelview [InvocationID], ubo .lightPos ).xyz ;
65+ output .LightVec = lPos - worldPos .xyz ;
66+ output .ViewVec = - worldPos .xyz ;
67+
68+ output .Pos = mul(ubo .projection [InvocationID], worldPos);
69+
70+ // Set the viewport index that the vertex will be emitted to
71+ output .ViewportIndex = InvocationID;
72+ output .PrimitiveID = PrimitiveID;
73+ outStream .Append (output);
74+ }
75+
76+ outStream .RestartStrip ();
77+ }
78+
79+ [shader(" fragment" )]
80+ float4 fragmentMain(GSOutput input)
81+ {
82+ float3 N = normalize(input .Normal );
83+ float3 L = normalize(input .LightVec );
84+ float3 V = normalize(input .ViewVec );
85+ float3 R = reflect(- L, N);
86+ float3 ambient = float3(0 . 1 , 0 . 1 , 0 . 1 );
87+ float3 diffuse = max(dot(N, L), 0 . 0 ) * float3(1 . 0 , 1 . 0 , 1 . 0 );
88+ float3 specular = pow(max(dot(R, V), 0 . 0 ), 16 . 0 ) * float3(0 . 75 , 0 . 75 , 0 . 75 );
89+ return float4((ambient + diffuse) * input .Color .rgb + specular, 1 . 0 );
90+ }
0 commit comments