1+ /* Copyright (c) 2025, Sascha Willems
2+ *
3+ * SPDX-License-Identifier: MIT
4+ *
5+ */
6+
7+ struct VSInput
8+ {
9+ float3 Pos : POSITION0;
10+ float3 Normal : NORMAL0;
11+ float2 UV : TEXCOORD0;
12+ float3 Color : COLOR0;
13+ // Instanced attributes
14+ float3 instancePos : POSITION1;
15+ float3 instanceRot : TEXCOORD1;
16+ float instanceScale : TEXCOORD2;
17+ int instanceTexIndex : TEXCOORD3;
18+ };
19+
20+ struct VSOutput
21+ {
22+ float4 Pos : SV_POSITION;
23+ float3 Normal;
24+ float3 Color;
25+ float3 UV;
26+ float3 ViewVec;
27+ float3 LightVec;
28+ };
29+
30+ struct UBO
31+ {
32+ float4x4 projection;
33+ float4x4 modelview;
34+ float4 lightPos;
35+ float locSpeed;
36+ float globSpeed;
37+ };
38+ ConstantBuffer < UBO> ubo;
39+ Sampler2DArray samplerArray;
40+
41+ [shader(" vertex" )]
42+ VSOutput vertexMain(VSInput input)
43+ {
44+ VSOutput output;
45+ output .Color = input .Color ;
46+ output .UV = float3(input .UV , input .instanceTexIndex );
47+
48+ // rotate around x
49+ float s = sin(input .instanceRot .x + ubo .locSpeed );
50+ float c = cos(input .instanceRot .x + ubo .locSpeed );
51+
52+ float3x3 mx = { c, - s, 0 . 0 ,
53+ s, c, 0 . 0 ,
54+ 0 . 0 , 0 . 0 , 1 . 0 };
55+
56+ // rotate around y
57+ s = sin(input .instanceRot .y + ubo .locSpeed );
58+ c = cos(input .instanceRot .y + ubo .locSpeed );
59+
60+ float3x3 my = { c, 0 . 0 , - s,
61+ 0 . 0 , 1 . 0 , 0 . 0 ,
62+ s, 0 . 0 , c };
63+
64+ // rot around z
65+ s = sin(input .instanceRot .z + ubo .locSpeed );
66+ c = cos(input .instanceRot .z + ubo .locSpeed );
67+
68+ float3x3 mz = { 1 . 0 , 0 . 0 , 0 . 0 ,
69+ 0 . 0 , c, - s,
70+ 0 . 0 , s, c };
71+
72+ float3x3 rotMat = mul(mz, mul(my, mx));
73+
74+ float4x4 gRotMat;
75+ s = sin(input .instanceRot .y + ubo .globSpeed );
76+ c = cos(input .instanceRot .y + ubo .globSpeed );
77+ gRotMat [0 ] = float4(c, 0 . 0 , - s, 0 . 0 );
78+ gRotMat [1 ] = float4(0 . 0 , 1 . 0 , 0 . 0 , 0 . 0 );
79+ gRotMat [2 ] = float4(s, 0 . 0 , c, 0 . 0 );
80+ gRotMat [3 ] = float4(0 . 0 , 0 . 0 , 0 . 0 , 1 . 0 );
81+
82+ float4 locPos = float4(mul(rotMat, input .Pos .xyz ), 1 . 0 );
83+ float4 pos = float4((locPos .xyz * input .instanceScale ) + input .instancePos , 1 . 0 );
84+
85+ output .Pos = mul(ubo .projection , mul(ubo .modelview , mul(gRotMat, pos)));
86+ output .Normal = mul((float3x3 )mul(ubo .modelview , gRotMat), mul(rotMat, input .Normal ));
87+
88+ pos = mul(ubo .modelview , float4(input .Pos .xyz + input .instancePos , 1 . 0 ));
89+ float3 lPos = mul((float3x3 )ubo .modelview , ubo .lightPos .xyz );
90+ output .LightVec = lPos - pos .xyz ;
91+ output .ViewVec = - pos .xyz ;
92+ return output;
93+ }
94+
95+ [shader(" fragment" )]
96+ float4 fragmentMain(VSOutput input)
97+ {
98+ float4 color = samplerArray .Sample (input .UV ) * float4(input .Color , 1 . 0 );
99+ float3 N = normalize(input .Normal );
100+ float3 L = normalize(input .LightVec );
101+ float3 V = normalize(input .ViewVec );
102+ float3 R = reflect(- L, N);
103+ float3 diffuse = max(dot(N, L), 0 . 1 ) * input .Color ;
104+ float3 specular = (dot(N,L) > 0 . 0 ) ? pow(max(dot(R, V), 0 . 0 ), 16 . 0 ) * float3(0 . 75 , 0 . 75 , 0 . 75 ) * color .r : float3(0 . 0 , 0 . 0 , 0 . 0 );
105+ return float4(diffuse * color .rgb + specular, 1 . 0 );
106+ }
0 commit comments