Post by inventordave on Oct 24, 2019 16:08:16 GMT
With material color (1,0,0) and light_color (1,1,1), (with ray normalized), I am getting the following image: "with-normalize-ray.png":
If I DON'T normalize the ray, I get: which I think is more in the spirit of the intended result. For reference, if I do: With light_color (0.1,0.5,0.9), material_color (1,0.2,1), I get:
I'm sure you can imagine what I get if I don't normalize the ray. Please find below the relevant code:
var c = 1;
var c2 = 1; // For debugging after code has completed: c = accumulates for every detected intersection, c2 = accumulates for every instance
// of positive-value hit
function render() {
var shape = new sphere();
sphere.material = new material();
sphere.material.color.x = 1;
sphere.material.color.y = 0.2;
sphere.material.color.z = 1;
//shape.transform = m_multiply(rotation_z(Math.PI / 4, true), scaling(0.5, 1, 1));
var light_position = point(-10,10,-10);
var light_color = colour();
light_color.x = 1;
light_color.y = 1;
light_color.z = 1; // colour() pseudo-constructor only generates default 0,0,0 colour.
var light = new point_light(light_position, light_color /* INTENSITY */);
var world_y;
var world_x;
var pos;
for (var y = 0; y < canvas_pixels; y++) {
world_y = half - (pixel_size * y);
for (var x = 0; x < canvas_pixels; x++) {
world_x = (-half) + (pixel_size * x);
pos = point(world_x, world_y, wall_z);
var r = new ray(ray_origin, normalize(subtract(pos, ray_origin)));
var xs = intersect(shape, r);
if (xs.length>0) {
c++;
var hit_res = hit(xs);
//console.log("intersected ray with sphere!\n");
if (hit_res) {
c2++;
r.origin = normalize(r.origin);
r.direction = normalize(r.direction);
var _point = position(r, hit_res.t);
var _normal = normal_at(hit_res.object, _point);
//var eye = invert(r.direction);
var eye = r.direction;
var _color = lighting(hit_res.object.material, light, _point, eye, _normal);
var col = convert(_color);
//console.log(col + "\n");
write_pixel(x, y, col);
//console.log("writing pixel at " + x + ", " + y + "\n");
}
}
}
}
//debugger;
}
function lighting(_material, _light, _point, eyev, normalv) {
// combine the surface color with the light's color/intensity
var effective_color = multiply(_material.color, _light.intensity);
// find the direction to the light source
var lightv = normalize(subtract(_light.position, _point));
// compute the ambient contribution
var ambient = multiplyInt(effective_color, _material.ambient);
//if (flag1++ < 2)
//debugger;
// ADDED
//ambient = new tuple(0, 0, 0, 0)
/* light_dot_normal represents the cosine of the angle between the
light vector and the normal vector. A negative number means the
light is on the other side of the surface.
*/
var diffuse = colour();
var specular = colour();
var light_dot_normal = dot(lightv, normalv);
if (light_dot_normal < 0) {
diffuse.x = 0;
diffuse.y = 0;
diffuse.z = 0; // black, same as diffuse = colour()
specular.x = 0;
specular.y = 0;
specular.z = 0; // black, same as specular = colour()
}
else {
// compute the diffuse contribution
var res = _material.diffuse * light_dot_normal;
res = multiplyInt(effective_color, res);
diffuse = res;
/* reflect_dot_eye represents the cosine of the angle between the
reflection vector and the eye vector. A negative number means the
light reflects away from the eye.
*/
var neg_lightv = new tuple(-lightv.x, -lightv.y, -lightv.z, VECTOR);
var reflectv = reflect(neg_lightv, normalv);
var reflect_dot_eye = dot(reflectv, eyev);
if (reflect_dot_eye <= 0) {
specular.x = 0;
specular.y = 0;
specular.z = 0; // black
}
else {
// compute the specular contribution
var factor = reflect_dot_eye ** _material.shininess;
var res = _material.specular * factor;
specular = multiplyInt(_light.intensity, res);
//console.log("\tspecular:: r: " + specular.x + ", g: " + specular.y + ", b: " + specular.z + "\n");
// When the above line is uncommented, the component values for specular printed are very low, negligble (<EPSILON)
}
}
var res = colour();
res = add(diffuse, specular);
res = add(ambient, res);
return res;
//return ambient + diffuse + specular;
}
with some global values:
var ray_origin = point(0,0,5);
var wall_z = -10.0;
var wall_size = 7.0;
var canvas_pixels = 550;
var pixel_size = wall_size / canvas_pixels;
var half = wall_size / 2;
Also note, if the colour() pseudo-consructor initialises to (1,1,1), I get the above images: If it initialises to (0,0,0), I get black images....
Please note, in render(), if I swap "var eye = invert(r.direction);
" for "var eye = r.direction;", it makes no difference!!
I have MCI and I am yet to fully internalize the "science" that I've been taught so far in the book, so so far I have been unable to debug the issue...
Thanks!
Lee David O'Dea
If I DON'T normalize the ray, I get: which I think is more in the spirit of the intended result. For reference, if I do: With light_color (0.1,0.5,0.9), material_color (1,0.2,1), I get:
I'm sure you can imagine what I get if I don't normalize the ray. Please find below the relevant code:
var c = 1;
var c2 = 1; // For debugging after code has completed: c = accumulates for every detected intersection, c2 = accumulates for every instance
// of positive-value hit
function render() {
var shape = new sphere();
sphere.material = new material();
sphere.material.color.x = 1;
sphere.material.color.y = 0.2;
sphere.material.color.z = 1;
//shape.transform = m_multiply(rotation_z(Math.PI / 4, true), scaling(0.5, 1, 1));
var light_position = point(-10,10,-10);
var light_color = colour();
light_color.x = 1;
light_color.y = 1;
light_color.z = 1; // colour() pseudo-constructor only generates default 0,0,0 colour.
var light = new point_light(light_position, light_color /* INTENSITY */);
var world_y;
var world_x;
var pos;
for (var y = 0; y < canvas_pixels; y++) {
world_y = half - (pixel_size * y);
for (var x = 0; x < canvas_pixels; x++) {
world_x = (-half) + (pixel_size * x);
pos = point(world_x, world_y, wall_z);
var r = new ray(ray_origin, normalize(subtract(pos, ray_origin)));
var xs = intersect(shape, r);
if (xs.length>0) {
c++;
var hit_res = hit(xs);
//console.log("intersected ray with sphere!\n");
if (hit_res) {
c2++;
r.origin = normalize(r.origin);
r.direction = normalize(r.direction);
var _point = position(r, hit_res.t);
var _normal = normal_at(hit_res.object, _point);
//var eye = invert(r.direction);
var eye = r.direction;
var _color = lighting(hit_res.object.material, light, _point, eye, _normal);
var col = convert(_color);
//console.log(col + "\n");
write_pixel(x, y, col);
//console.log("writing pixel at " + x + ", " + y + "\n");
}
}
}
}
//debugger;
}
function lighting(_material, _light, _point, eyev, normalv) {
// combine the surface color with the light's color/intensity
var effective_color = multiply(_material.color, _light.intensity);
// find the direction to the light source
var lightv = normalize(subtract(_light.position, _point));
// compute the ambient contribution
var ambient = multiplyInt(effective_color, _material.ambient);
//if (flag1++ < 2)
//debugger;
// ADDED
//ambient = new tuple(0, 0, 0, 0)
/* light_dot_normal represents the cosine of the angle between the
light vector and the normal vector. A negative number means the
light is on the other side of the surface.
*/
var diffuse = colour();
var specular = colour();
var light_dot_normal = dot(lightv, normalv);
if (light_dot_normal < 0) {
diffuse.x = 0;
diffuse.y = 0;
diffuse.z = 0; // black, same as diffuse = colour()
specular.x = 0;
specular.y = 0;
specular.z = 0; // black, same as specular = colour()
}
else {
// compute the diffuse contribution
var res = _material.diffuse * light_dot_normal;
res = multiplyInt(effective_color, res);
diffuse = res;
/* reflect_dot_eye represents the cosine of the angle between the
reflection vector and the eye vector. A negative number means the
light reflects away from the eye.
*/
var neg_lightv = new tuple(-lightv.x, -lightv.y, -lightv.z, VECTOR);
var reflectv = reflect(neg_lightv, normalv);
var reflect_dot_eye = dot(reflectv, eyev);
if (reflect_dot_eye <= 0) {
specular.x = 0;
specular.y = 0;
specular.z = 0; // black
}
else {
// compute the specular contribution
var factor = reflect_dot_eye ** _material.shininess;
var res = _material.specular * factor;
specular = multiplyInt(_light.intensity, res);
//console.log("\tspecular:: r: " + specular.x + ", g: " + specular.y + ", b: " + specular.z + "\n");
// When the above line is uncommented, the component values for specular printed are very low, negligble (<EPSILON)
}
}
var res = colour();
res = add(diffuse, specular);
res = add(ambient, res);
return res;
//return ambient + diffuse + specular;
}
with some global values:
var ray_origin = point(0,0,5);
var wall_z = -10.0;
var wall_size = 7.0;
var canvas_pixels = 550;
var pixel_size = wall_size / canvas_pixels;
var half = wall_size / 2;
Also note, if the colour() pseudo-consructor initialises to (1,1,1), I get the above images: If it initialises to (0,0,0), I get black images....
Please note, in render(), if I swap "var eye = invert(r.direction);
" for "var eye = r.direction;", it makes no difference!!
I have MCI and I am yet to fully internalize the "science" that I've been taught so far in the book, so so far I have been unable to debug the issue...
Thanks!
Lee David O'Dea