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