Skip to content

Commit 8109287

Browse files
committed
Reworked color class:
- renamed to RgbColor - using operators instead of methods - replaced usages
1 parent 093d691 commit 8109287

File tree

7 files changed

+130
-112
lines changed

7 files changed

+130
-112
lines changed

Editors/EditorMaterial.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public EditorMaterial()
1212

1313
public override void ResetState()
1414
{
15-
// TBD: Color
15+
panelColor.BackColor = System.Drawing.Color.White;
1616
numGloss.Value = 0;
1717
numSpecular.Value = 0;
1818
numReflection.Value = 0;
@@ -31,9 +31,9 @@ public override void LoadState(object item)
3131
if (obj.Material == null)
3232
return;
3333

34-
int r = (int)(obj.Material.Color.r * 255);
35-
int g = (int)(obj.Material.Color.g * 255);
36-
int b = (int)(obj.Material.Color.b * 255);
34+
int r = (int)(obj.Material.Color.R * 255);
35+
int g = (int)(obj.Material.Color.G * 255);
36+
int b = (int)(obj.Material.Color.B * 255);
3737
panelColor.BackColor = System.Drawing.Color.FromArgb(r, g, b);
3838

3939
numGloss.Value = (decimal)obj.Material.Gloss;
@@ -51,9 +51,9 @@ public override void SaveState(object item)
5151

5252
// take color from panel and store back into Material.Color
5353
var c = panelColor.BackColor;
54-
obj.Material.Color.r = c.R / 255f;
55-
obj.Material.Color.g = c.G / 255f;
56-
obj.Material.Color.b = c.B / 255f;
54+
obj.Material.Color.R = c.R / 255f;
55+
obj.Material.Color.R = c.G / 255f;
56+
obj.Material.Color.R = c.B / 255f;
5757

5858
// save numeric values back into material
5959
obj.Material.Gloss = (float)numGloss.Value;

Engine/Raytracer.cs

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -49,19 +49,20 @@ private struct RayTraversalResult
4949

5050
public Raytracer() { }
5151

52-
private Color computeSpecular(float vDotR, float mGls, Color sourceSpec, float matSpec)
52+
private RgbColor computeSpecular(float vDotR, float mGls, RgbColor sourceSpec, float matSpec)
5353
{
54-
return sourceSpec.Multiply((float)Math.Pow(vDotR, mGls) * matSpec);
54+
float factor = (float)Math.Pow(vDotR, mGls) * matSpec;
55+
return sourceSpec * factor;
5556
}
5657

57-
private Color computeDiffuse(float nDotL, Color sourceDiff, Color matDiff)
58+
private RgbColor computeDiffuse(float nDotL, RgbColor sourceDiff, RgbColor matDiff)
5859
{
59-
return sourceDiff.Multiply(nDotL).Multiply(matDiff);
60+
return sourceDiff * nDotL * matDiff;
6061
}
6162

62-
private Color trace(Ray ray, int depth)
63+
private RgbColor trace(Ray ray, int depth)
6364
{
64-
if (Scene == null) return Color.black;
65+
if (Scene == null) return RgbColor.Black;
6566

6667
mIntersector.Ray = ray;
6768

@@ -86,7 +87,7 @@ private Color trace(Ray ray, int depth)
8687
}
8788
}
8889

89-
Color lit = Color.black;
90+
RgbColor lit = RgbColor.Black;
9091

9192
if (closest != null && mIntersector.Result == Intersector.IntersectionResult.Hit)
9293
{
@@ -114,26 +115,26 @@ private Color trace(Ray ray, int depth)
114115
if (ComputeSpecular)
115116
{
116117
float vDotR = v.Dot(r);
117-
Color spec = (vDotR > 0)
118+
RgbColor spec = (vDotR > 0)
118119
? computeSpecular(vDotR, mat.Gloss, light.getColor(), mat.Specular)
119-
: Color.black;
120-
lit = lit.Add(spec);
120+
: RgbColor.Black;
121+
lit = lit + spec;
121122
}
122123

123124
if (ComputeDiffuse)
124125
{
125126
float nDotL = n.Dot(l);
126-
Color diff = (nDotL > 0)
127+
RgbColor diff = (nDotL > 0)
127128
? computeDiffuse(nDotL, light.getColor(), mat.Color)
128-
: Color.black;
129-
lit = lit.Add(diff);
129+
: RgbColor.Black;
130+
lit = lit + diff;
130131
}
131132

132133
if (GlobalReflection && refl > 0 && depth < TraceDepth)
133134
{
134135
Ray reflected = new Ray(intersectionPoint, r);
135-
Color acc = trace(reflected, depth + 1);
136-
lit = lit.Add(acc.Multiply(refl).Multiply(mat.Color));
136+
RgbColor acc = trace(reflected, depth + 1);
137+
lit += acc * refl * mat.Color;
137138
}
138139
}
139140
}
@@ -227,13 +228,13 @@ private void RenderChunk(Point start, Point end, byte[] pixels, int stride)
227228
dir.Normalize();
228229
Ray ray = new Ray(Camera.Eye, dir);
229230

230-
Color c = trace(ray, 1);
231+
RgbColor c = trace(ray, 1);
231232

232233
// Write into pixel array (thread-safe)
233234
int index = iter.Cursor.Y * stride + iter.Cursor.X * 4;
234-
pixels[index + 0] = (byte)(c.b * 255);
235-
pixels[index + 1] = (byte)(c.g * 255);
236-
pixels[index + 2] = (byte)(c.r * 255);
235+
pixels[index + 0] = (byte)(c.B * 255);
236+
pixels[index + 1] = (byte)(c.G * 255);
237+
pixels[index + 2] = (byte)(c.R * 255);
237238
pixels[index + 3] = 255; // full opacity
238239

239240
// Thread-safe progress update

MainForm.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ private void BuildScene()
5757

5858
Sphere s1 = new Sphere();
5959
s1.Origin = new Vector(-3.5f, 0, 0);
60-
s1.Material.Color = Color.blue;
60+
s1.Material.Color = RgbColor.Blue;
6161
s1.Material.Gloss = 30;
6262
s1.Material.Specular = 1.0f;
6363
s1.Material.Reflection = 1.0f;
@@ -67,7 +67,7 @@ private void BuildScene()
6767

6868
Sphere s2 = new Sphere();
6969
s2.Origin = new Vector(3, 0, 0);
70-
s2.Material.Color = Color.red;
70+
s2.Material.Color = RgbColor.Red;
7171
s2.Material.Gloss = 10;
7272
s2.Material.Specular = 0.8f;
7373
s2.Material.Reflection = 0.0f;
@@ -78,7 +78,7 @@ private void BuildScene()
7878

7979
Sphere s3 = new Sphere();
8080
s3.Origin = new Vector(0, 0, 0);
81-
s3.Material.Color = Color.green;
81+
s3.Material.Color = RgbColor.Green;
8282
s3.Material.Gloss = 10;
8383
s3.Material.Specular = 0;
8484
s3.Material.Reflection = 0;
@@ -87,12 +87,12 @@ private void BuildScene()
8787
mScene.AddObject(s3);
8888

8989
Plane pln = new();
90-
pln.Material.Color = Color.yellow;
90+
pln.Material.Color = RgbColor.Yellow;
9191
mScene.AddObject(pln);
9292

9393
PointLight p = new PointLight();
9494
p.setPosition(new Vector(0, 15, 35));
95-
p.setColor(Color.white);
95+
p.setColor(RgbColor.White);
9696
p.setName("Point Light");
9797
p.setEnabled(true);
9898

Model/Color.cs

Lines changed: 0 additions & 77 deletions
This file was deleted.

Model/Material.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ public Material()
77
{
88
}
99

10-
public Color Color { get; set; } = new(0, 0, 0);
10+
public RgbColor Color { get; set; } = new(0, 0, 0);
1111

1212
// the "Phong" exponent;
1313
// small => large hotspot, gradual fallof;

Model/PointLight.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ namespace UnilightRaytracer
33
public class PointLight
44
{
55
private Vector position = new Vector();
6-
private Color color = new Color(1, 1, 1); // same color used for diffuse and specular
6+
private RgbColor color = new RgbColor(1, 1, 1); // same color used for diffuse and specular
77
private String name = "Point light";
88
private bool enabled = true;
99

@@ -21,12 +21,12 @@ public Vector getPosition()
2121
return position;
2222
}
2323

24-
public void setColor(Color c)
24+
public void setColor(RgbColor c)
2525
{
2626
color = c;
2727
}
2828

29-
public Color getColor()
29+
public RgbColor getColor()
3030
{
3131
return color;
3232
}

Model/RgbColor.cs

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
* RgbColor.cs
3+
*
4+
* Represents an RGB color with float components in the range [0, 1].
5+
*
6+
* Features:
7+
* - Predefined static colors: Black, Red, Green, Blue, White, Yellow, Cyan, Magenta
8+
* - Safe mutable properties (R, G, B) with automatic clamping
9+
* - Arithmetic operators: +, -, * (with both scalars and other colors)
10+
* - Linear interpolation (Lerp) with clamped interpolation factor
11+
* - ToString() override for debugging output
12+
*
13+
* Usage:
14+
* var c1 = new RgbColor(0.5f, 0.2f, 0.7f); // create a custom color
15+
* c1.R = 2.0f; // clamped to 1.0
16+
* var mix = RgbColor.Lerp(RgbColor.Red, RgbColor.Blue, 0.5f); // purple
17+
*
18+
* Author: Dan Munteanu
19+
* Date: 28-Sep-2025
20+
*/
21+
22+
namespace UnilightRaytracer
23+
{
24+
public class RgbColor
25+
{
26+
private float r, g, b;
27+
28+
public float R
29+
{
30+
get => r;
31+
set => r = Clamp(value);
32+
}
33+
34+
public float G
35+
{
36+
get => g;
37+
set => g = Clamp(value);
38+
}
39+
40+
public float B
41+
{
42+
get => b;
43+
set => b = Clamp(value);
44+
}
45+
46+
// Predefined colors
47+
public static readonly RgbColor Black = new(0, 0, 0);
48+
public static readonly RgbColor Red = new(1, 0, 0);
49+
public static readonly RgbColor Green = new(0, 1, 0);
50+
public static readonly RgbColor Blue = new(0, 0, 1);
51+
public static readonly RgbColor White = new(1, 1, 1);
52+
public static readonly RgbColor Yellow = new(1, 1, 0);
53+
public static readonly RgbColor Cyan = new(0, 1, 1);
54+
public static readonly RgbColor Magenta = new(1, 0, 1);
55+
56+
public RgbColor(float r, float g, float b)
57+
{
58+
R = r;
59+
G = g;
60+
B = b;
61+
}
62+
63+
private static float Clamp(float value, float min = 0f, float max = 1f) =>
64+
value < min ? min : (value > max ? max : value);
65+
66+
// Operators
67+
public static RgbColor operator +(RgbColor a, RgbColor b) =>
68+
new(Clamp(a.R + b.R), Clamp(a.G + b.G), Clamp(a.B + b.B));
69+
70+
public static RgbColor operator -(RgbColor a, RgbColor b) =>
71+
new(Clamp(a.R - b.R), Clamp(a.G - b.G), Clamp(a.B - b.B));
72+
73+
public static RgbColor operator *(RgbColor a, RgbColor b) =>
74+
new(Clamp(a.R * b.R), Clamp(a.G * b.G), Clamp(a.B * b.B));
75+
76+
public static RgbColor operator *(RgbColor a, float k) =>
77+
new(Clamp(a.R * k), Clamp(a.G * k), Clamp(a.B * k));
78+
79+
// Linear interpolation with clamped t
80+
public static RgbColor Lerp(RgbColor a, RgbColor b, float t)
81+
{
82+
if (t < 0f) t = 0f;
83+
if (t > 1f) t = 1f;
84+
85+
return new RgbColor(
86+
a.R + (b.R - a.R) * t,
87+
a.G + (b.G - a.G) * t,
88+
a.B + (b.B - a.B) * t
89+
);
90+
}
91+
92+
public override string ToString() => $"RgbColor({R:0.##}, {G:0.##}, {B:0.##})";
93+
}
94+
}

0 commit comments

Comments
 (0)