3template<size_t materialCount>
4CombineMaterial<materialCount>::CombineMaterial() {}
6template<size_t materialCount>
7void CombineMaterial<materialCount>::AddMaterial(Method method, Material* material, float opacity) {
8 if (materialsAdded < materialCount) {
9 this->method[materialsAdded] = method;
10 this->materials[materialsAdded] = material;
11 this->opacity[materialsAdded] = opacity;
17template<size_t materialCount>
18void CombineMaterial<materialCount>::SetMethod(uint8_t index, Method method) {
19 if (index < materialsAdded) {
20 this->method[index] = method;
24template<size_t materialCount>
25void CombineMaterial<materialCount>::SetOpacity(uint8_t index, float opacity) {
26 if (index < materialsAdded) {
27 this->opacity[index] = opacity;
31template<size_t materialCount>
32void CombineMaterial<materialCount>::SetMaterial(uint8_t index, Material* material) {
33 if (index < materialsAdded) {
34 materials[index] = material;
38template<size_t materialCount>
39RGBColor CombineMaterial<materialCount>::GetRGB(const Vector3D& position, const Vector3D& normal, const Vector3D& uvw) {
44 for (int i = 0; i < materialsAdded; i++) {
45 if (opacity[i] > 0.025f) {
48 temp = materials[i]->GetRGB(position, normal, uvw);
54 rgb = rgb * opacity[i];
58 // Add all colors to base color
59 temp = materials[i]->GetRGB(position, normal, uvw);
61 rgb.X = (rgb.X + temp.R) * opacity[i] + rgb.X * (1.0f - opacity[i]);
62 rgb.Y = (rgb.Y + temp.G) * opacity[i] + rgb.Y * (1.0f - opacity[i]);
63 rgb.Z = (rgb.Z + temp.B) * opacity[i] + rgb.Z * (1.0f - opacity[i]);
67 // Subtract from base color
68 temp = materials[i]->GetRGB(position, normal, uvw);
70 rgb.X = (rgb.X - temp.R) * opacity[i] + rgb.X * (1.0f - opacity[i]);
71 rgb.Y = (rgb.Y - temp.G) * opacity[i] + rgb.Y * (1.0f - opacity[i]);
72 rgb.Z = (rgb.Z - temp.B) * opacity[i] + rgb.Z * (1.0f - opacity[i]);
76 // Multiply with base color
77 temp = materials[i]->GetRGB(position, normal, uvw);
79 rgb.X = (rgb.X * temp.R) * opacity[i] + rgb.X * (1.0f - opacity[i]);
80 rgb.Y = (rgb.Y * temp.G) * opacity[i] + rgb.Y * (1.0f - opacity[i]);
81 rgb.Z = (rgb.Z * temp.B) * opacity[i] + rgb.Z * (1.0f - opacity[i]);
85 // Divide from base color
86 temp = materials[i]->GetRGB(position, normal, uvw);
88 rgb.X = (rgb.X / temp.R) * opacity[i] + rgb.X * (1.0f - opacity[i]);
89 rgb.Y = (rgb.Y / temp.G) * opacity[i] + rgb.Y * (1.0f - opacity[i]);
90 rgb.Z = (rgb.Z / temp.B) * opacity[i] + rgb.Z * (1.0f - opacity[i]);
94 // Find minimum color in all cases
95 temp = materials[i]->GetRGB(position, normal, uvw);
96 tempV = Vector3D::Min(Vector3D(temp.R, temp.G, temp.B), rgb);
98 rgb = Vector3D::LERP(rgb, tempV, opacity[i]);
102 // Find maximum color in all cases
103 temp = materials[i]->GetRGB(position, normal, uvw);
104 tempV = Vector3D::Max(Vector3D(temp.R, temp.G, temp.B), rgb);
106 rgb = Vector3D::LERP(rgb, tempV, opacity[i]);
110 // 1 - (1 - a)(1 - b)
111 temp = materials[i]->GetRGB(position, normal, uvw);
113 tempV.X = 255.0f - (255.0f - rgb.X) * (255.0f - temp.R);
114 tempV.Y = 255.0f - (255.0f - rgb.Y) * (255.0f - temp.G);
115 tempV.Z = 255.0f - (255.0f - rgb.Z) * (255.0f - temp.B);
117 rgb = Vector3D::LERP(rgb, tempV, opacity[i]);
122 // else 1 - 2(1 - a)(1 - b)
123 temp = materials[i]->GetRGB(position, normal, uvw);
125 if (rgb.X < 128) tempV.X = 2.0f * rgb.X * temp.R;
126 else tempV.X = 255.0f - 2.0f * (255.0f - rgb.X) * (255.0f - temp.R);
128 if (rgb.Y < 128) tempV.Y = 2.0f * rgb.Y * temp.G;
129 else tempV.Y = 255.0f - 2.0f * (255.0f - rgb.Y) * (255.0f - temp.G);
131 if (rgb.Z < 128) tempV.Z = 2.0f * rgb.Z * temp.B;
132 else tempV.Z = 255.0f - 2.0f * (255.0f - rgb.Z) * (255.0f - temp.B);
134 rgb = Vector3D::LERP(rgb, tempV, opacity[i]);
139 temp = materials[i]->GetRGB(position, normal, uvw);
141 tempV.X = (255.0f - 2.0f * temp.R) * (rgb.X * rgb.X) + 2.0f * (temp.R * rgb.X);
142 tempV.Y = (255.0f - 2.0f * temp.G) * (rgb.Y * rgb.Y) + 2.0f * (temp.G * rgb.Y);
143 tempV.Z = (255.0f - 2.0f * temp.B) * (rgb.Z * rgb.Z) + 2.0f * (temp.B * rgb.Z);
145 rgb = Vector3D::LERP(rgb, tempV, opacity[i]);
149 temp = materials[i]->GetRGB(position, normal, uvw);
155 rgb = Vector3D::LERP(rgb, tempV, opacity[i]);
159 temp = materials[i]->GetRGB(position, normal, uvw);
161 if (temp.R > 128 && temp.G > 128 && temp.B > 128) {
166 rgb = rgb * opacity[i];
175 materials[i]->GetRGB(position, normal, uvw);
184 return RGBColor(rgb.Constrain(0, 255));