File Material.cs
File List > Render > src > Material.cs
Go to the documentation of this file.
using System;
using System.Drawing;
using System.Linq;
using Qkmaxware.Geometry;
namespace Qkmaxware.Rendering {
public class Material {
public bool TwoSided = false;
public virtual Color Vert(ShaderVariables variables) { return Color.Transparent; }
public virtual Color Edge(ShaderVariables variables) { return Fragment(variables); }
public virtual Color Fragment(ShaderVariables variables) { return Color.Transparent; }
}
public class Wireframe : Material {
public Color Colour = Color.White;
public Wireframe(Color colour) {
this.Colour = colour;
this.TwoSided = true;
}
public override Color Edge(ShaderVariables variables) {
return this.Colour;
}
}
public class UnlitColour : Material {
public Color Colour = Color.White;
public UnlitColour(Color colour) {
this.Colour = colour;
}
public override Color Edge(ShaderVariables variables) {
return Colour;
}
public override Color Fragment(ShaderVariables variables) {
return Colour;
}
}
public class TexturedMaterial : Material {
public Texture2D Texture;
public TexturedMaterial(Texture2D texture) {
this.Texture = texture;
}
protected Color ColourSample(Vec2 uv) {
var uvx = (int)(uv.X * Texture.Width);
var uvy = (int)(uv.Y * Texture.Height);
return Texture[uvx, uvy];
}
}
public class UnlitTexture : TexturedMaterial {
public UnlitTexture(Texture2D texture) : base(texture) {}
public override Color Edge(ShaderVariables variables) {
return Fragment(variables);
}
public override Color Fragment(ShaderVariables variables) {
return ColourSample(variables.UVCoordinates);
}
}
public class DiffuseColour : Material {
public Color Colour = Color.White;
public double Albedo = 1;
public DiffuseColour(Color colour) {
this.Colour = colour;
}
private Color Darken(Color colour, double shade) {
double r = shade * colour.R;
double g = shade * colour.G;
double b = shade * colour.B;
return Color.FromArgb(colour.A, (int)r % 255, (int)g % 255, (int)b % 255);
}
private Color Mix(Color a, Color b) {
return Color.FromArgb(
a.A,
(a.R * b.R)/255,
(a.G * b.G)/255,
(a.B * b.B)/255
);
}
public override Color Fragment(ShaderVariables variables) {
var surfColour = Colour;
Vec3 N = variables.WorldNormal;
var tint = variables.LightSources.Select((light) => {
var lightColour = light.Tint;
Vec3 L = light.Direction(variables.WorldPosition, variables.WorldNormal);
double Lintensity = light.Intensity(variables.WorldPosition, variables.WorldNormal);
double diffuse_surface_shade = (Albedo / Math.PI) * Lintensity * Math.Max(Vec3.Dot(L, N), 0);
return Darken(lightColour, diffuse_surface_shade);
}).Aggregate((a,b) => Mix(a, b));
return Mix(surfColour, tint);
}
}
public class DiffuseTexture : TexturedMaterial {
public Color Colour = Color.White;
public double Albedo = 1;
public DiffuseTexture(Texture2D texture) : base(texture) {}
private Color Darken(Color colour, double shade) {
double r = shade * colour.R;
double g = shade * colour.G;
double b = shade * colour.B;
return Color.FromArgb(colour.A, (int)r % 255, (int)g % 255, (int)b % 255);
}
private Color Mix(Color a, Color b) {
return Color.FromArgb(
a.A,
(a.R * b.R)/255,
(a.G * b.G)/255,
(a.B * b.B)/255
);
}
public override Color Fragment(ShaderVariables variables) {
var surfColour = ColourSample(variables.UVCoordinates);
Vec3 N = variables.WorldNormal;
var tint = variables.LightSources.Select((light) => {
var lightColour = light.Tint;
Vec3 L = light.Direction(variables.WorldPosition, variables.WorldNormal);
double Lintensity = light.Intensity(variables.WorldPosition, variables.WorldNormal);
double diffuse_surface_shade = (Albedo / Math.PI) * Lintensity * Math.Max(Vec3.Dot(L, N), 0);
return Darken(lightColour, diffuse_surface_shade);
}).Aggregate((a,b) => Mix(a, b));
return Mix(surfColour, tint);
}
}
}