151 {
152 mxvk::Mat4D object_rotation;
153 object_rotation.
BuildXYZ(instance.rotation.x, instance.rotation.y, instance.rotation.z);
154
155 std::vector<mxvk::vec4D> camera_vertices(instance.mesh.vertices.size());
156 std::vector<mxvk::vec4D> projected_vertices(instance.mesh.vertices.size());
157 for (std::size_t index = 0; index < instance.mesh.vertices.size(); ++index) {
158 const mxvk::vec4D &vertex = instance.mesh.vertices[index];
159 mxvk::vec4D transformed(vertex.
x * instance.scale.x, vertex.
y * instance.scale.y, vertex.
z * instance.scale.z, 1.0f);
160 transformed = object_rotation.
MulVec(transformed);
161 transformed += instance.position;
162 transformed = camera_rotation.MulVec(transformed);
164 camera_vertices[index] = transformed;
165 projected_vertices[index] = project(transformed);
166 }
167
168 const mxvk::vec4D light_direction = normalized({-0.35f, -0.65f, -1.0f, 0.0f});
169 for (const Triangle &triangle : instance.mesh.triangles) {
170 const mxvk::vec4D &a = camera_vertices[triangle.indices[0]];
171 const mxvk::vec4D &b = camera_vertices[triangle.indices[1]];
172 const mxvk::vec4D &c = camera_vertices[triangle.indices[2]];
173 mxvk::vec4D normal = mxvk::vec4D().Build(a, b).CrossProduct(mxvk::vec4D().Build(a, c));
175
176 const mxvk::vec4D center = (a + b + c) * (1.0f / 3.0f);
177 const mxvk::vec4D view_direction(-center.
x, -center.
y, -center.
z, 0.0f);
178 if (normal.
DotProduct(view_direction) <= 0.0f) {
179 if (!instance.mesh.two_sided) {
180 continue;
181 }
182 normal = normal * -1.0f;
183 }
184
185 const float diffuse = std::max(0.0f, normal.
DotProduct(light_direction));
186 const float intensity = std::clamp(0.32f + diffuse * 0.68f, 0.0f, 1.0f);
187 rasterize_triangle(projected_vertices[triangle.indices[0]], projected_vertices[triangle.indices[1]], projected_vertices[triangle.indices[2]],
mxvk::shade_color(instance.color, intensity));
188 }
189 }
void BuildXYZ(float theta_x, float theta_y, float theta_z)
Build an XYZ Euler rotation matrix from angles in degrees.
vec4D MulVec(const vec4D &in) const
Transform a homogeneous 4D vector by this matrix.
void Normalize()
Normalize the 3D components in place and reset W to 1.
constexpr float DotProduct(const vec4D &v) const
Compute the 3D dot product, ignoring the W component.
constexpr float CAMERA_DISTANCE
MXCOLOR shade_color(MXCOLOR color, float intensity)
Scale the RGB channels of a color while preserving alpha.