Skip to content
This repository was archived by the owner on Apr 28, 2021. It is now read-only.

Add lights attributes #242

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
103 changes: 87 additions & 16 deletions assets/shader/standard.frag
Original file line number Diff line number Diff line change
@@ -1,5 +1,58 @@
{{GLSL_VERSION}}

///////////////////////////////////////////////////////////////////////////////
const int numberoflights = 5;
uniform vec3 ambientcolor;// = vec3(0.3, 0.3, 0.3);
uniform vec4 material; // = vec4(1., 0.4, 0.5, 1.);
/*
(ambient, diffuse, specular, specularcolorcoeff) ∈ [0, 1]
default vec4(1., 0.4, 0.5, 1.);
*/
uniform float shininess;
struct lightSource
{
vec3 color;
vec3 direction;
int onoff; // == 0 or 1
};
uniform vec3 lightdirection1;
uniform vec3 lightdirection2;
uniform vec3 lightdirection3;
uniform vec3 lightdirection4;
uniform vec3 lightdirection5;
uniform vec3 lightcolor1;
uniform vec3 lightcolor2;
uniform vec3 lightcolor3;
uniform vec3 lightcolor4;
uniform vec3 lightcolor5;
uniform int onoff1; uniform int onoff2;
uniform int onoff3; uniform int onoff4; uniform int onoff5;
lightSource light0 = lightSource(
lightcolor1, // color
lightdirection1, // direction
onoff1
);
lightSource light1 = lightSource(
lightcolor2, // color
lightdirection2, // direction
onoff2
);
lightSource light2 = lightSource(
lightcolor3, // color
lightdirection3, // direction
onoff3
);
lightSource light3 = lightSource(
lightcolor4, // color
lightdirection4, // direction
onoff4
);
lightSource light4 = lightSource(
lightcolor5, // color
lightdirection5, // direction
onoff5
);
lightSource lights[numberoflights];
///////////////////////////////////////////////////////////////////////////////
struct Nothing{ //Nothing type, to encode if some variable doesn't contain any data
bool _; //empty structs are not allowed
};
Expand Down Expand Up @@ -31,25 +84,43 @@ vec4 get_color(samplerBuffer color, vec2 uv){
vec4 get_color(sampler2D color, vec2 uv){
return texture(color, uv);
}
// http://www.opengl-tutorial.org/fr/beginners-tutorials/tutorial-8-basic-shading/
// https://github.com/JuliaGL/GLVisualize.jl/blob/master/assets/shader/standard.frag
// https://en.wikibooks.org/wiki/GLSL_Programming/GLUT/Multiple_Lights
// https://fr.mathworks.com/matlabcentral/answers/91652-how-do-the-ambientstrength-diffusestrength-and-specularstrength-properties-of-the-material-command
vec3 blinnphong(vec3 N, vec3 V, vec3 color){
// define lights
lights[0] = light0;
lights[1] = light1;
lights[2] = light2;
lights[3] = light3;
lights[4] = light4;
// initialize total lighting with ambient lighting
vec3 totalLighting = material[0] * vec3(ambientcolor);

vec3 blinnphong(vec3 N, vec3 V, vec3 L, vec3 color){
float diff_coeff = max(dot(L, N), 0.0);

// specular coefficient
vec3 H = normalize(L+V);
for (int index = 0; index < numberoflights; index++) // for all light sources
{
if (lights[index].onoff == 1)
{
vec3 Ldir = normalize(vec3(lights[index].direction));
float cosTheta = clamp(dot(Ldir, N), 0, 1);
vec3 R = reflect(- Ldir, N);
// should the normalize(vec3(1)) be replaced by E = normalize(EyeDirection_cameraspace)
float cosAlpha = clamp(dot(R, normalize(vec3(1))), 0, 1);

float spec_coeff = pow(max(dot(H, N), 0.0), 8.0);
if (diff_coeff <= 0.0)
spec_coeff = 0.0;

// final lighting model
return vec3(
vec3(0.1) * vec3(0.3) +
vec3(0.9) * color * diff_coeff +
vec3(0.3) * spec_coeff
);
vec3 diffuseReflection = material[1] * vec3(lights[index].color) *
cosTheta * color;
vec3 specularcolor = (1 - material[3]) * vec3(lights[index].color) +
material[3] * vec3(1);
vec3 specularReflection = material[2] * vec3(specularcolor) *
pow(cosAlpha, shininess);
totalLighting = totalLighting + diffuseReflection + specularReflection;
}
}
return totalLighting;
}


void write2framebuffer(vec4 color, uvec2 id);

void main(){
Expand Down
116 changes: 91 additions & 25 deletions assets/shader/uv_normal.frag
Original file line number Diff line number Diff line change
@@ -1,5 +1,58 @@
{{GLSL_VERSION}}

///////////////////////////////////////////////////////////////////////////////
const int numberoflights = 5;
uniform vec3 ambientcolor;// = vec3(0.3, 0.3, 0.3);
uniform vec4 material; // = vec4(1., 0.4, 0.5, 1.);
/*
(ambient, diffuse, specular, specularcolorcoeff) ∈ [0, 1]
default vec4(1., 0.4, 0.5, 1.);
*/
uniform float shininess;
struct lightSource
{
vec3 color;
vec3 direction;
int onoff; // == 0 or 1
};
uniform vec3 lightdirection1;
uniform vec3 lightdirection2;
uniform vec3 lightdirection3;
uniform vec3 lightdirection4;
uniform vec3 lightdirection5;
uniform vec3 lightcolor1;
uniform vec3 lightcolor2;
uniform vec3 lightcolor3;
uniform vec3 lightcolor4;
uniform vec3 lightcolor5;
uniform int onoff1; uniform int onoff2;
uniform int onoff3; uniform int onoff4; uniform int onoff5;
lightSource light0 = lightSource(
lightcolor1, // color
lightdirection1, // direction
onoff1
);
lightSource light1 = lightSource(
lightcolor2, // color
lightdirection2, // direction
onoff2
);
lightSource light2 = lightSource(
lightcolor3, // color
lightdirection3, // direction
onoff3
);
lightSource light3 = lightSource(
lightcolor4, // color
lightdirection4, // direction
onoff4
);
lightSource light4 = lightSource(
lightcolor5, // color
lightdirection5, // direction
onoff5
);
lightSource lights[numberoflights];
///////////////////////////////////////////////////////////////////////////////
in vec3 o_normal;
in vec3 o_lightdir;
in vec3 o_vertex;
Expand All @@ -10,27 +63,6 @@ flat in uvec2 o_id;
out vec4 fragment_color;
out uvec2 fragment_groupid;


vec3 blinnphong(vec3 N, vec3 V, vec3 L, vec3 color)
{
float diff_coeff = max(dot(L,N), 0.0);

// specular coefficient
vec3 H = normalize(L+V);

float spec_coeff = pow(max(dot(H,N), 0.0), 8.0);
if (diff_coeff <= 0.0)
spec_coeff = 0.0;

// final lighting model
return vec3(
vec3(0.1) * vec3(0.3) +
vec3(0.9) * color * diff_coeff +
vec3(0.3) * spec_coeff);
}



const float ALIASING_CONST = 0.70710678118654757;

float aastep(float threshold1, float threshold2, float value) {
Expand All @@ -51,13 +83,47 @@ float square(vec2 uv)
((1-xmin)*(1-xmax))*ymax;
}

vec3 blinnphong(vec3 N, vec3 V, vec3 color){
// define lights
lights[0] = light0;
lights[1] = light1;
lights[2] = light2;
lights[3] = light3;
lights[4] = light4;
// initialize total lighting with ambient lighting
vec3 totalLighting = material[0] * vec3(ambientcolor);

for (int index = 0; index < numberoflights; index++) // for all light sources
{
if (lights[index].onoff == 1)
{
vec3 Ldir = normalize(vec3(lights[index].direction));
float cosTheta = clamp(dot(Ldir, N), 0, 1);
vec3 R = reflect(- Ldir, N);
// should the normalize(vec3(1)) be replaced by E = normalize(EyeDirection_cameraspace)
float cosAlpha = clamp(dot(R, normalize(vec3(1))), 0, 1);

vec3 diffuseReflection = material[1] * vec3(lights[index].color) *
cosTheta * color;
vec3 specularcolor = (1 - material[3]) * vec3(lights[index].color) +
material[3] * vec3(1);
vec3 specularReflection = material[2] * vec3(specularcolor) *
pow(cosAlpha, shininess);
totalLighting = totalLighting + diffuseReflection + specularReflection;
}
}
return totalLighting;
}

void main(){
vec3 L = normalize(o_lightdir);
vec3 N = normalize(o_normal);
vec3 f_color = mix(vec3(0,0,1), vec3(1), square(o_uv));
vec3 light1 = blinnphong(N, o_vertex, L, f_color);
vec3 light2 = blinnphong(N, o_vertex, -L,f_color);
fragment_color = vec4(light1+light2*0.4, 1.0);
//vec3 light1 = blinnphong(N, o_vertex, L, f_color);
//vec3 light2 = blinnphong(N, o_vertex, -L,f_color);
//fragment_color = vec4(light1+light2*0.4, 1.0);
vec3 light1 = blinnphong(N, o_vertex, f_color);
fragment_color = vec4(light1, 1.0);
if(fragment_color.a > 0.0)
fragment_groupid = o_id;
}
51 changes: 51 additions & 0 deletions examples/lights/lighting.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using GLVisualize, GeometryTypes, GLAbstraction, Colors, FileIO

window = GLVisualize.glscreen(); δ = 0.45
ambientcolordefault = Vec3f0(0.1)
materialdefault = Vec4f0(0.9, 0.7, 0.3, 0.9) # (ambient, diffuse, specular, specularcolorcoeff) ∈ [0, 1]
shininessdefault = Float32(5.)
lightd = Vec3f0[Vec3f0(1.0, 1.0, 1.0), Vec3f0(0.1, 0.1, 0.1),
Vec3f0(0.9, 0.9, 0.9), Vec3f0(20, 0, 20)]
markerm = :o
for x = 0:2
for y = 0:2
dc = linspace(0, 1, 3)[x + 1] * materialdefault[2]
sc = linspace(0, 1, 3)[3 - y] * materialdefault[3]
lmesh = if markerm == :o
GLNormalMesh(Sphere{Float32}(Point3f0(x, y, 0), Float32(δ)), 50)
elseif markerm == :□
GLNormalMesh(GeometryTypes.HyperRectangle(Vec3f0(x - δ, y - δ , - δ),
Vec3f0(3 * δ / 2, 3 * δ / 2 , 3 * δ / 2)))
end
material = Vec4f0(1, dc, sc, 1.)
GLVisualize._view(GLVisualize.visualize(lmesh, color = RGBA{Float32}(1, 0, 0, 1.),
light = lightd, shininess = shininessdefault,
material = material,
ambientcolor = Vec3f0(0.01)), window)
end
end
lighting = GLVisualize.Lighting([lightd[end],])
for x = 0:2
for y = 0:2
ac = if x == 0
[0, 1, 0]
elseif x == 1
[0.5, 0, 1]
elseif x == 2
ones(3)
end
as = linspace(0, 1, 3)[y + 1] * materialdefault[1]
lmesh = if markerm == :o
GLNormalMesh(Sphere{Float32}(Point3f0(x , 2 - y - 4, 0), Float32(δ)), 50)
elseif markerm == :□
GLNormalMesh(GeometryTypes.HyperRectangle(Vec3f0(x - δ, 2 - y - δ - 4 , - δ),
Vec3f0(3 * δ / 2, 3 * δ / 2 , 3 * δ / 2)))
end
material = Vec4f0(as, materialdefault[2:end]...)
GLVisualize._view(GLVisualize.visualize(lmesh, color = RGBA{Float32}(1, 0, 0, 1.),
ambientcolor = Vec3f0(ac...),
lighting = lighting, shininess = shininessdefault,
material = material), window)
end
end
GLVisualize.renderloop(window)
32 changes: 32 additions & 0 deletions src/types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -269,3 +269,35 @@ struct GLVisualizeShader <: AbstractLazyShader
new(map(x-> assetpath("shader", x), paths), args)
end
end

# lighting related type
"""
Lighting(directions::Array{Vec3f0, 1}, colors::Array{Vec3f0, 1},
ambientcolor::Vec3f0, material::Vec4f0, shininess::Float32)

# Arguments
* the single attribute light is still take into account if :light[end] != default_light
using the backlight intensity 0.4
* material descibes the fields (ambient, diffuse, specular, specularcolorcoeff) ∈ [0, 1]
"""
struct Lighting
directions::Array{Vec3f0, 1}
colors::Array{Vec3f0, 1}
ambientcolor::Vec3f0
material::Vec4f0
shininess::Float32
end
ambientcolordefault = Vec3f0(0.1)
materialdefault = Vec4f0(.9, 0.7, 0.3, .9)
shininessdefault = Float32(5.)
function Lighting(lights::Array{Vec3f0, 1})
Lighting(lights, [Vec3f0(1.) for k = 1:length(lights)],
ambientcolordefault, materialdefault, shininessdefault)
end
function Lighting(lights::Array{Vec3f0, 1}, lightscolors::Array{Vec3f0, 1})
Lighting(lights, lightscolors,
ambientcolordefault, materialdefault, shininessdefault)
end
function GLAbstraction.gl_convert(x::GLVisualize.Lighting)
return x
end
36 changes: 36 additions & 0 deletions src/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,46 @@ function assemble_robj(data, program, bb, primitive, pre_fun, post_fun)
robj
end

function lightingoptions!(data)
numberoflights = 5
_default_light = Vec3f0(20, 20, 20)
if value(data[:light])[end] != _default_light
# default direct and back lighting using the signgle attribute light
# using the initial light of intensity 0.4
data[:lighting] = Lighting([value(data[:light])[end], Vec3f0(-[value(data[:light])[end]...])],
[Vec3f0(1), Vec3f0(0.4)])
end
# export values in hard coded variables
for k = 1:numberoflights
data[Symbol("onoff", string(k))] = 0
data[Symbol("lightdirection", string(k))] = Vec3f0(0)
data[Symbol("lightcolor", string(k))] = Vec3f0(1)
end
for k = 1:min(numberoflights, length(value(data[:lighting]).directions))
data[Symbol("onoff", string(k))] = 1
data[Symbol("lightdirection", string(k))] = value(data[:lighting]).directions[k]
data[Symbol("lightcolor", string(k))] = value(data[:lighting]).colors[k]
end
# add ambientcolor / material / shininess if not defined by argument
if :ambientcolor ∉ keys(data)
data[:ambientcolor] = value(data[:lighting]).ambientcolor
end
if :material ∉ keys(data)
data[:material] = value(data[:lighting]).material
end
if :shininess ∉ keys(data)
data[:shininess] = value(data[:lighting]).shininess
end
for symbl in [:ambientcolor, :material, :shininess]
data[symbl] = value(data[symbl])
end
data
end

function assemble_shader(data)
shader = data[:shader]
delete!(data, :shader)
lightingoptions!(data)
default_bb = Signal(centered(AABB))
bb = get(data, :boundingbox, default_bb)
if bb == nothing || isa(bb, Signal{Void})
Expand Down
Loading