src/raytracer.cc
author Radek Brich <radek.brich@devl.cz>
Fri, 02 May 2008 13:27:47 +0200
branchpyrit
changeset 91 9d66d323c354
parent 90 f6a72eb99631
child 92 9af5c039b678
permissions -rw-r--r--
packetize Phong shader new scons config options: simd=(yes|no) - allow/suppress explicit SSE force_flags=(yes|no) - force use of specified flags instead of autodetected profile=(yes|no) - enable gcc's profiling (-pg option) check for pthread.h header, don't try to build without it add fourth Vector3 component for better memory aligning rename Vector3 to Vector partialy SSE-ize Vector class (only fully vertical operations) build static lib and python module in distinctive directories to avoid collision of library file names on some platforms
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     1
/*
44
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
     2
 * raytracer.cc: Raytracer class
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
     3
 *
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
     4
 * This file is part of Pyrit Ray Tracer.
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
     5
 *
47
320d5d466864 move Sampler classes to sampler.cc
Radek Brich <radek.brich@devl.cz>
parents: 46
diff changeset
     6
 * Copyright 2006, 2007, 2008  Radek Brich
0
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     7
 *
44
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
     8
 * Permission is hereby granted, free of charge, to any person obtaining a copy
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
     9
 * of this software and associated documentation files (the "Software"), to deal
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
    10
 * in the Software without restriction, including without limitation the rights
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
    11
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
    12
 * copies of the Software, and to permit persons to whom the Software is
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
    13
 * furnished to do so, subject to the following conditions:
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
    14
 *
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
    15
 * The above copyright notice and this permission notice shall be included in
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
    16
 * all copies or substantial portions of the Software.
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
    17
 *
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
    18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
    19
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
    20
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
    21
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
    22
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
    23
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
3763b26244f0 MIT license for sources
Radek Brich <radek.brich@devl.cz>
parents: 42
diff changeset
    24
 * THE SOFTWARE.
0
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    25
 */
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    26
4
c73bc405ee7a multi-threaded rendering via pthreads
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    27
#include <pthread.h>
0
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    28
#include <stdio.h>
67
249553e1d4fe new option to choose single or double precision floats
Radek Brich <radek.brich@devl.cz>
parents: 56
diff changeset
    29
#include <stdlib.h>
82
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
    30
#include <assert.h>
0
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    31
#include "raytracer.h"
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    32
53
228cb8bfdd54 slighly optimized raytrace_worker
Radek Brich <radek.brich@devl.cz>
parents: 52
diff changeset
    33
int pyrit_verbosity = 2;
30
33f95441790e pyrit_verbosity: new variable for controlling amount of output, see common.h
Radek Brich <radek.brich@devl.cz>
parents: 25
diff changeset
    34
0
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    35
// Hammersley spherical point distribution
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    36
// http://www.cse.cuhk.edu.hk/~ttwong/papers/udpoint/udpoints.html
91
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
    37
Vector Raytracer::SphereDistribute(int i, int n, Float extent, const Vector &normal)
0
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    38
{
22
76b7bd51d64a new make infrastructure
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
    39
	Float p, t, st, phi, phirad;
0
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    40
	int kk;
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    41
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    42
	t = 0;
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    43
	for (p=0.5, kk=i; kk; p*=0.5, kk>>=1)
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    44
	if (kk & 1)
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    45
		t += p;
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    46
	t = 1.0 + (t - 1.0)*extent;
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    47
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    48
	phi = (i + 0.5) / n;
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    49
	phirad =  phi * 2.0 * M_PI;
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    50
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    51
	st = sqrt(1.0 - t*t);
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    52
22
76b7bd51d64a new make infrastructure
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
    53
	Float x, y, z, xx, yy, zz, q;
0
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    54
	x = st * cos(phirad);
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    55
	y = st * sin(phirad);
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    56
	z = t;
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    57
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    58
	// rotate against Y axis
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    59
	q = acos(normal.z);
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    60
	zz = z*cos(q) - x*sin(q);
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    61
	xx = z*sin(q) + x*cos(q);
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    62
	yy = y;
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    63
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    64
	// rotate against Z axis
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    65
	q = atan2f(normal.y, normal.x);
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    66
	x = xx*cos(q) - yy*sin(q);
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    67
	y = xx*sin(q) + yy*cos(q);
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    68
	z = zz;
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    69
91
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
    70
	return Vector(x, y, z);
0
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    71
}
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    72
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    73
/*
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    74
 P is point of intersection,
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    75
 N normal in this point,
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    76
 R direction of reflected ray,
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    77
 V direction to the viewer
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    78
*/
91
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
    79
Colour Raytracer::PhongShader(const Shape *shape,
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
    80
	const Vector &P, const Vector &N, const Vector &V)
0
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    81
{
91
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
    82
	Colour col, acc;
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
    83
	Material * const &mat = shape->material;
0
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    84
91
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
    85
	if (mat->texture)
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
    86
		col = mat->texture->evaluate(P);
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
    87
	else
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
    88
		col = mat->colour;
0
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    89
91
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
    90
	// ambient
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
    91
	acc = mat->ambient * col;
82
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
    92
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
    93
	vector<Light*>::iterator light;
91
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
    94
	for (light = lights.begin(); light != lights.end(); light++)
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
    95
	{
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
    96
		const Vector L = normalize((*light)->pos - P); // direction vector to light
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
    97
		const Float L_dot_N = dot(L, N);
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
    98
		if (L_dot_N > 0)
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
    99
		{
82
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   100
			// test if this light is occluded (sharp shadows)
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   101
			if ((*light)->cast_shadows) {
91
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   102
				const Ray shadow_ray = Ray(P, L);
82
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   103
				Float dist = FLT_MAX;
91
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   104
				if (top->nearest_intersection(shape, shadow_ray, dist))
82
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   105
					continue;
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   106
			}
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   107
91
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   108
			const Vector R = L - 2.0 * L_dot_N * N;
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   109
			const Float R_dot_V = dot(R, V);
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   110
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   111
			// diffuse
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   112
			acc += mat->diffuse * col * (*light)->colour * L_dot_N;
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   113
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   114
			// specular
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   115
			if (R_dot_V > 0)
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   116
				acc += mat->specular * (*light)->colour * powf(R_dot_V, mat->shininess);
82
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   117
		}
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   118
	}
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   119
91
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   120
	return acc;
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   121
}
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   122
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   123
#ifndef NO_SSE
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   124
VectorPacket Raytracer::PhongShader_packet(const Shape **shapes,
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   125
	const VectorPacket &P, const VectorPacket &N, const VectorPacket &V)
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   126
{
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   127
	VectorPacket acc, colour;
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   128
	union { __m128 ambient; float ambient_f[4]; };
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   129
	union { __m128 diffuse; float diffuse_f[4]; };
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   130
	union { __m128 specular; float specular_f[4]; };
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   131
	union { __m128 shininess; float shininess_f[4]; };
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   132
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   133
	for (int i = 0; i < 4; i++)
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   134
		if (shapes[i] == NULL)
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   135
		{
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   136
			ambient_f[i] = 0;
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   137
			diffuse_f[i] = 0;
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   138
			specular_f[i] = 0;
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   139
			shininess_f[i] = 0;
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   140
		}
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   141
		else
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   142
		{
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   143
			Material * const &mat = shapes[i]->material;
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   144
			if (mat->texture)
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   145
				colour.setVector(i, mat->texture->evaluate(P.getVector(i)));
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   146
			else
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   147
				colour.setVector(i, mat->colour);
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   148
			ambient_f[i] = mat->ambient;
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   149
			diffuse_f[i] = mat->diffuse;
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   150
			specular_f[i] = mat->specular;
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   151
			shininess_f[i] = mat->shininess;
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   152
		}
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   153
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   154
	// ambient
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   155
	acc = colour * ambient;
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   156
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   157
	Shape **shadow_shapes;
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   158
	vector<Light*>::iterator light;
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   159
	for (light = lights.begin(); light != lights.end(); light++)
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   160
	{
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   161
		 // direction vector to light
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   162
		VectorPacket L = VectorPacket((*light)->pos) - P;
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   163
		L.normalize();
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   164
		const __m128 L_dot_N = dot(L, N);
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   165
		__m128 valid = _mm_cmpgt_ps(L_dot_N, mZero);
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   166
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   167
		// test if this light is occluded (sharp shadows)
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   168
		if ((*light)->cast_shadows)
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   169
		{
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   170
			const RayPacket shadow_rays = RayPacket(P, L);
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   171
			union { __m128 dists; float dists_f[4]; };
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   172
			dists = mInf;
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   173
			top->packet_intersection(shapes, shadow_rays,
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   174
				dists_f, shadow_shapes);
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   175
			valid = _mm_and_ps(valid, _mm_cmpeq_ps(dists, mInf));
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   176
		}
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   177
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   178
		const VectorPacket R = L - N * _mm_mul_ps(mTwo, L_dot_N);
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   179
		const __m128 R_dot_V = dot(R, V);
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   180
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   181
		// diffuse
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   182
		acc.selectiveAdd(valid,
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   183
			colour * VectorPacket((*light)->colour) * _mm_mul_ps(diffuse, L_dot_N));
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   184
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   185
		// specular
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   186
		valid = _mm_and_ps(valid, _mm_cmpgt_ps(R_dot_V, mZero));
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   187
		__m128 spec = _mm_mul_ps(_mm_mul_ps(specular, _mm_set_ps1((*light)->colour.r)),
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   188
			_mm_fastpow(R_dot_V, shininess));
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   189
		acc.selectiveAdd(valid, spec);
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   190
	}
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   191
	return acc;
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   192
}
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   193
#endif
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   194
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   195
void Raytracer::lightScatter(const Ray &ray, const Shape *shape, int depth,
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   196
	const Vector &P, const Vector &normal, bool from_inside, Colour &col)
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   197
{
82
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   198
	if (depth < max_depth)
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   199
	{
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   200
		Colour trans_col, refl_col;
91
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   201
		Float trans = shape->material->transmissivity;
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   202
		Float refl = shape->material->reflectivity;
82
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   203
		const Float cos_i = - dot(normal, ray.dir);
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   204
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   205
		// reflection
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   206
		if (refl > 0.01)
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   207
		{
91
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   208
			Vector newdir = ray.dir + 2.0 * cos_i * normal;
82
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   209
			Ray newray = Ray(P, newdir);
91
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   210
			refl_col = raytrace(newray, depth + 1, shape);
82
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   211
		}
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   212
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   213
		// refraction
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   214
		if (trans > 0.01)
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   215
		{
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   216
			Float n, n1, n2;
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   217
			if (from_inside)
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   218
			{
91
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   219
				n1 = shape->material->refract_index;
82
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   220
				n2 = 1.0;
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   221
				n = n1;
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   222
			}
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   223
			else
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   224
			{
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   225
				n1 = 1.0;
91
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   226
				n2 = shape->material->refract_index;
82
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   227
				n = 1.0 / n2;
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   228
			}
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   229
			const Float sin2_t = n*n * (1 - cos_i*cos_i);
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   230
			if (sin2_t >= 1.0)
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   231
			{
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   232
					// totally reflected
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   233
					refl += trans;
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   234
					trans = 0;
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   235
			}
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   236
			else
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   237
			{
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   238
				const Float cos_t = sqrtf(1 - sin2_t);
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   239
				const Float Rdiv = 1.0/(n1*cos_i + n2*cos_t);
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   240
				const Float Rper = (n1*cos_i - n2*cos_t)*Rdiv;
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   241
				const Float Rpar = (n2*cos_i - n1*cos_t)*Rdiv;
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   242
				const Float R = (Rper*Rper + Rpar*Rpar)/2;
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   243
				refl += R*trans;
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   244
				trans = (1-R)*trans;
91
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   245
				Vector newdir = n * ray.dir + (n*cos_i - cos_t) * normal;
82
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   246
				Ray newray = Ray(P + 0.001*newdir, newdir);
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   247
				trans_col = raytrace(newray, depth + 1, NULL);
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   248
			}
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   249
		}
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   250
		col = (1-refl-trans)*col + refl*refl_col + trans*trans_col;
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   251
	}
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   252
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   253
	// ambient occlusion
91
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   254
	if (ao_samples && !from_inside)
82
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   255
	{
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   256
		Float miss = 0;
91
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   257
		for (int i = 0; i < ao_samples; i++)
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   258
		{
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   259
			Vector dir = SphereDistribute(i, ao_samples, ao_angle, normal);
82
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   260
			Ray ao_ray = Ray(P, dir);
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   261
			Float dist = ao_distance;
91
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   262
			Shape *shape_in_way = top->nearest_intersection(shape, ao_ray, dist);
82
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   263
			if (shape_in_way == NULL)
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   264
				miss += 1.0;
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   265
			else
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   266
				miss += dist / ao_distance;
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   267
		}
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   268
		Float ao_intensity = miss / ao_samples;
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   269
		col = col * ao_intensity;
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   270
	}
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   271
}
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   272
91
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   273
Colour Raytracer::raytrace(Ray &ray, int depth, const Shape *origin_shape)
0
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   274
{
22
76b7bd51d64a new make infrastructure
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   275
	Float nearest_distance = Inf;
11
4d192e13ee84 move nearest_intersection() to Container, add dummy KdTree.load(), plus small fixes
Radek Brich <radek.brich@devl.cz>
parents: 10
diff changeset
   276
	Shape *nearest_shape = top->nearest_intersection(origin_shape, ray, nearest_distance);
0
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   277
82
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   278
	if (nearest_shape == NULL)
0
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   279
		return bg_colour;
82
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   280
	else
91
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   281
	{
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   282
		const Vector P = ray.o + ray.dir * nearest_distance; // point of intersection
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   283
		Vector normal = nearest_shape->normal(P);
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   284
		bool from_inside = false;
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   285
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   286
		// make shapes double sided
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   287
		if (dot(normal, ray.dir) > 0.0)
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   288
		{
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   289
			normal = - normal;
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   290
			from_inside = true;
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   291
		}
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   292
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   293
		// shading function
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   294
		Colour col = PhongShader(nearest_shape, P, normal, ray.dir);
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   295
		lightScatter(ray, nearest_shape, depth, P, normal, from_inside, col);
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   296
		return col;
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   297
	}
82
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   298
}
31
b4e09433934a refraction
Radek Brich <radek.brich@devl.cz>
parents: 30
diff changeset
   299
91
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   300
#ifndef NO_SSE
84
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   301
void Raytracer::raytracePacket(RayPacket &rays, Colour *results)
82
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   302
{
91
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   303
	union {
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   304
		float nearest_distances[4];
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   305
		__m128 m_nearest_distances;
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   306
	};
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   307
	__m128 mask;
82
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   308
	Shape *nearest_shapes[4];
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   309
	static const Shape *origin_shapes[4] = {NULL, NULL, NULL, NULL};
91
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   310
	m_nearest_distances = mInf;
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   311
	mask = mAllSet;
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   312
82
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   313
	top->packet_intersection(origin_shapes, rays, nearest_distances, nearest_shapes);
0
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   314
91
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   315
	mask = _mm_cmpneq_ps(m_nearest_distances, mInf);
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   316
	if (!_mm_movemask_ps(mask))
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   317
	{
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   318
		for (int i = 0; i < 4; i++)
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   319
			results[i] = bg_colour;
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   320
		return;
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   321
	}
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   322
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   323
	const VectorPacket P = rays.o + rays.dir * m_nearest_distances; // point of intersection
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   324
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   325
	VectorPacket normal;
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   326
	for (int i = 0; i < 4; i++)
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   327
		if (nearest_shapes[i] != NULL)
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   328
			normal.setVector(i, nearest_shapes[i]->normal(P.getVector(i)));
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   329
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   330
	// make shapes double sided
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   331
	__m128 from_inside = _mm_cmpgt_ps(dot(normal, rays.dir), mZero);
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   332
	normal.mx = _mm_or_ps(_mm_and_ps(from_inside, _mm_sub_ps(mZero, normal.mx)),
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   333
		_mm_andnot_ps(from_inside, normal.mx));
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   334
	normal.my = _mm_or_ps(_mm_and_ps(from_inside, _mm_sub_ps(mZero, normal.my)),
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   335
		_mm_andnot_ps(from_inside, normal.my));
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   336
	normal.mz = _mm_or_ps(_mm_and_ps(from_inside, _mm_sub_ps(mZero, normal.mz)),
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   337
		_mm_andnot_ps(from_inside, normal.mz));
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   338
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   339
	// shading function
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   340
	VectorPacket pres =
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   341
		PhongShader_packet(const_cast<const Shape**>(nearest_shapes), P, normal, rays.dir);
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   342
	//pres.mx = _mm_or_ps(_mm_and_ps(mask, pres.mx), _mm_andnot_ps(mask, _mm_set_ps1(bg_colour.r)));
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   343
	//pres.my = _mm_or_ps(_mm_and_ps(mask, pres.my), _mm_andnot_ps(mask, _mm_set_ps1(bg_colour.g)));
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   344
	//pres.mz = _mm_or_ps(_mm_and_ps(mask, pres.mz), _mm_andnot_ps(mask, _mm_set_ps1(bg_colour.b)));
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   345
82
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   346
	for (int i = 0; i < 4; i++)
91
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   347
		if (nearest_shapes[i] != NULL)
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   348
		{
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   349
			results[i] = pres.getVector(i);
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   350
			lightScatter(rays[i], nearest_shapes[i], 0,
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   351
				P.getVector(i), normal.getVector(i), (_mm_movemask_ps(from_inside)>>i)&1,
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   352
				results[i]);
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   353
		}
82
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   354
		else
91
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   355
			results[i] = bg_colour;
0
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   356
}
91
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   357
#endif
0
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   358
50
14a727b70d07 rewritten threads with heavy debug information
Radek Brich <radek.brich@devl.cz>
parents: 49
diff changeset
   359
void *Raytracer::raytrace_worker(void *d)
14a727b70d07 rewritten threads with heavy debug information
Radek Brich <radek.brich@devl.cz>
parents: 49
diff changeset
   360
{
55
f6d75ae82c88 fix bugs
Radek Brich <radek.brich@devl.cz>
parents: 54
diff changeset
   361
	static const int my_queue_size = 256;
50
14a727b70d07 rewritten threads with heavy debug information
Radek Brich <radek.brich@devl.cz>
parents: 49
diff changeset
   362
	Raytracer *rt = (Raytracer*)d;
54
dbe3c7a4e0f0 more raytrace_worker optimization and cleaning
Radek Brich <radek.brich@devl.cz>
parents: 53
diff changeset
   363
	Sample my_queue[my_queue_size];
dbe3c7a4e0f0 more raytrace_worker optimization and cleaning
Radek Brich <radek.brich@devl.cz>
parents: 53
diff changeset
   364
	Colour my_colours[my_queue_size];
53
228cb8bfdd54 slighly optimized raytrace_worker
Radek Brich <radek.brich@devl.cz>
parents: 52
diff changeset
   365
	int my_count;
84
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   366
	Ray ray;
91
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   367
#ifndef NO_SSE
84
6f7fe14782c2 prepare kd-tree traversal for packet tracing (4 rays at once)
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   368
	RayPacket rays;
82
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   369
	const bool can_use_packets = (rt->use_packets && rt->sampler->packetableSamples());
91
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   370
#endif
50
14a727b70d07 rewritten threads with heavy debug information
Radek Brich <radek.brich@devl.cz>
parents: 49
diff changeset
   371
	for (;;)
14a727b70d07 rewritten threads with heavy debug information
Radek Brich <radek.brich@devl.cz>
parents: 49
diff changeset
   372
	{
14a727b70d07 rewritten threads with heavy debug information
Radek Brich <radek.brich@devl.cz>
parents: 49
diff changeset
   373
		pthread_mutex_lock(&rt->sample_queue_mutex);
52
a6413a3d741d new implementation of sample_queue
Radek Brich <radek.brich@devl.cz>
parents: 51
diff changeset
   374
		while (rt->sample_queue_count == 0)
a6413a3d741d new implementation of sample_queue
Radek Brich <radek.brich@devl.cz>
parents: 51
diff changeset
   375
		{
54
dbe3c7a4e0f0 more raytrace_worker optimization and cleaning
Radek Brich <radek.brich@devl.cz>
parents: 53
diff changeset
   376
			if (rt->end_of_samples)
50
14a727b70d07 rewritten threads with heavy debug information
Radek Brich <radek.brich@devl.cz>
parents: 49
diff changeset
   377
			{
52
a6413a3d741d new implementation of sample_queue
Radek Brich <radek.brich@devl.cz>
parents: 51
diff changeset
   378
				dbgmsg(4, "T thread [%d] exiting\n", pthread_self());
50
14a727b70d07 rewritten threads with heavy debug information
Radek Brich <radek.brich@devl.cz>
parents: 49
diff changeset
   379
				pthread_mutex_unlock(&rt->sample_queue_mutex);
14a727b70d07 rewritten threads with heavy debug information
Radek Brich <radek.brich@devl.cz>
parents: 49
diff changeset
   380
				pthread_exit(NULL);
14a727b70d07 rewritten threads with heavy debug information
Radek Brich <radek.brich@devl.cz>
parents: 49
diff changeset
   381
			}
14a727b70d07 rewritten threads with heavy debug information
Radek Brich <radek.brich@devl.cz>
parents: 49
diff changeset
   382
			pthread_cond_wait(&rt->sample_queue_cond, &rt->sample_queue_mutex);
14a727b70d07 rewritten threads with heavy debug information
Radek Brich <radek.brich@devl.cz>
parents: 49
diff changeset
   383
		}
14a727b70d07 rewritten threads with heavy debug information
Radek Brich <radek.brich@devl.cz>
parents: 49
diff changeset
   384
54
dbe3c7a4e0f0 more raytrace_worker optimization and cleaning
Radek Brich <radek.brich@devl.cz>
parents: 53
diff changeset
   385
		if (rt->sample_queue_count >= my_queue_size)
dbe3c7a4e0f0 more raytrace_worker optimization and cleaning
Radek Brich <radek.brich@devl.cz>
parents: 53
diff changeset
   386
			my_count = my_queue_size;
53
228cb8bfdd54 slighly optimized raytrace_worker
Radek Brich <radek.brich@devl.cz>
parents: 52
diff changeset
   387
		else
228cb8bfdd54 slighly optimized raytrace_worker
Radek Brich <radek.brich@devl.cz>
parents: 52
diff changeset
   388
			my_count = rt->sample_queue_count;
228cb8bfdd54 slighly optimized raytrace_worker
Radek Brich <radek.brich@devl.cz>
parents: 52
diff changeset
   389
		rt->sample_queue_count -= my_count;
228cb8bfdd54 slighly optimized raytrace_worker
Radek Brich <radek.brich@devl.cz>
parents: 52
diff changeset
   390
54
dbe3c7a4e0f0 more raytrace_worker optimization and cleaning
Radek Brich <radek.brich@devl.cz>
parents: 53
diff changeset
   391
		// copy samples to local queue
55
f6d75ae82c88 fix bugs
Radek Brich <radek.brich@devl.cz>
parents: 54
diff changeset
   392
		if (rt->sample_queue_pos + my_count >= rt->sample_queue_size)
53
228cb8bfdd54 slighly optimized raytrace_worker
Radek Brich <radek.brich@devl.cz>
parents: 52
diff changeset
   393
		{
55
f6d75ae82c88 fix bugs
Radek Brich <radek.brich@devl.cz>
parents: 54
diff changeset
   394
			register int c = rt->sample_queue_size - rt->sample_queue_pos;
f6d75ae82c88 fix bugs
Radek Brich <radek.brich@devl.cz>
parents: 54
diff changeset
   395
			memcpy(my_queue, rt->sample_queue + rt->sample_queue_pos, c*sizeof(Sample));
f6d75ae82c88 fix bugs
Radek Brich <radek.brich@devl.cz>
parents: 54
diff changeset
   396
			memcpy(my_queue + c, rt->sample_queue, (my_count - c)*sizeof(Sample));
f6d75ae82c88 fix bugs
Radek Brich <radek.brich@devl.cz>
parents: 54
diff changeset
   397
			rt->sample_queue_pos = my_count - c;
53
228cb8bfdd54 slighly optimized raytrace_worker
Radek Brich <radek.brich@devl.cz>
parents: 52
diff changeset
   398
		}
55
f6d75ae82c88 fix bugs
Radek Brich <radek.brich@devl.cz>
parents: 54
diff changeset
   399
		else
f6d75ae82c88 fix bugs
Radek Brich <radek.brich@devl.cz>
parents: 54
diff changeset
   400
		{
f6d75ae82c88 fix bugs
Radek Brich <radek.brich@devl.cz>
parents: 54
diff changeset
   401
			memcpy(my_queue, rt->sample_queue + rt->sample_queue_pos,
f6d75ae82c88 fix bugs
Radek Brich <radek.brich@devl.cz>
parents: 54
diff changeset
   402
				my_count*sizeof(Sample));
f6d75ae82c88 fix bugs
Radek Brich <radek.brich@devl.cz>
parents: 54
diff changeset
   403
			rt->sample_queue_pos += my_count;
f6d75ae82c88 fix bugs
Radek Brich <radek.brich@devl.cz>
parents: 54
diff changeset
   404
		}
f6d75ae82c88 fix bugs
Radek Brich <radek.brich@devl.cz>
parents: 54
diff changeset
   405
		if (rt->sample_queue_count <= my_queue_size*2)
f6d75ae82c88 fix bugs
Radek Brich <radek.brich@devl.cz>
parents: 54
diff changeset
   406
			pthread_cond_signal(&rt->worker_ready_cond);
50
14a727b70d07 rewritten threads with heavy debug information
Radek Brich <radek.brich@devl.cz>
parents: 49
diff changeset
   407
		pthread_mutex_unlock(&rt->sample_queue_mutex);
14a727b70d07 rewritten threads with heavy debug information
Radek Brich <radek.brich@devl.cz>
parents: 49
diff changeset
   408
14a727b70d07 rewritten threads with heavy debug information
Radek Brich <radek.brich@devl.cz>
parents: 49
diff changeset
   409
		// do the work
91
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   410
#ifndef NO_SSE
82
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   411
		if (can_use_packets)
53
228cb8bfdd54 slighly optimized raytrace_worker
Radek Brich <radek.brich@devl.cz>
parents: 52
diff changeset
   412
		{
82
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   413
			// packet ray tracing
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   414
			assert((my_count % 4) == 0);
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   415
			for (int i = 0; i < my_count; i+=4)
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   416
			{
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   417
				rt->camera->makeRayPacket(my_queue + i, rays);
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   418
				rt->raytracePacket(rays, my_colours + i);
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   419
			}
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   420
		}
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   421
		else
91
9d66d323c354 packetize Phong shader
Radek Brich <radek.brich@devl.cz>
parents: 90
diff changeset
   422
#endif
82
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   423
		{
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   424
			// single ray tracing
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   425
			for (int i = 0; i < my_count; i++)
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   426
			{
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   427
				ray = rt->camera->makeRay(my_queue[i]);
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   428
				my_colours[i] = rt->raytrace(ray, 0, NULL);
930a2d3ecaed prepare structures for packet tracing
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   429
			}
53
228cb8bfdd54 slighly optimized raytrace_worker
Radek Brich <radek.brich@devl.cz>
parents: 52
diff changeset
   430
		}
51
89fec8668768 remove debug messages - algorithm seems stable, but it's slow
Radek Brich <radek.brich@devl.cz>
parents: 50
diff changeset
   431
53
228cb8bfdd54 slighly optimized raytrace_worker
Radek Brich <radek.brich@devl.cz>
parents: 52
diff changeset
   432
		// save the results
50
14a727b70d07 rewritten threads with heavy debug information
Radek Brich <radek.brich@devl.cz>
parents: 49
diff changeset
   433
		pthread_mutex_lock(&rt->sampler_mutex);
53
228cb8bfdd54 slighly optimized raytrace_worker
Radek Brich <radek.brich@devl.cz>
parents: 52
diff changeset
   434
		for (int i = 0; i < my_count; i++)
228cb8bfdd54 slighly optimized raytrace_worker
Radek Brich <radek.brich@devl.cz>
parents: 52
diff changeset
   435
			rt->sampler->saveSample(my_queue[i], my_colours[i]);
50
14a727b70d07 rewritten threads with heavy debug information
Radek Brich <radek.brich@devl.cz>
parents: 49
diff changeset
   436
		pthread_mutex_unlock(&rt->sampler_mutex);
14a727b70d07 rewritten threads with heavy debug information
Radek Brich <radek.brich@devl.cz>
parents: 49
diff changeset
   437
	}
14a727b70d07 rewritten threads with heavy debug information
Radek Brich <radek.brich@devl.cz>
parents: 49
diff changeset
   438
}
14a727b70d07 rewritten threads with heavy debug information
Radek Brich <radek.brich@devl.cz>
parents: 49
diff changeset
   439
46
6493fb65f0b1 Doxygen
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   440
void Raytracer::render()
0
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   441
{
46
6493fb65f0b1 Doxygen
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   442
	if (!sampler || !camera || !top)
20
f22952603f29 new C++ demo: realtime.cc (real-time scene viewer using SDL)
Radek Brich <radek.brich@devl.cz>
parents: 19
diff changeset
   443
		return;
0
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   444
55
f6d75ae82c88 fix bugs
Radek Brich <radek.brich@devl.cz>
parents: 54
diff changeset
   445
	static const int my_count_max = 256;
f6d75ae82c88 fix bugs
Radek Brich <radek.brich@devl.cz>
parents: 54
diff changeset
   446
	sample_queue_size = my_count_max*2*num_threads;
f6d75ae82c88 fix bugs
Radek Brich <radek.brich@devl.cz>
parents: 54
diff changeset
   447
	sample_queue = new Sample [sample_queue_size];
52
a6413a3d741d new implementation of sample_queue
Radek Brich <radek.brich@devl.cz>
parents: 51
diff changeset
   448
	sample_queue_count = 0;
77
dbe8438d5dca rewrite subsampling from old code to DefaultSampler
Radek Brich <radek.brich@devl.cz>
parents: 75
diff changeset
   449
	int my_count, my_pos;
54
dbe3c7a4e0f0 more raytrace_worker optimization and cleaning
Radek Brich <radek.brich@devl.cz>
parents: 53
diff changeset
   450
	int sampnum = 0, sampdone;
77
dbe8438d5dca rewrite subsampling from old code to DefaultSampler
Radek Brich <radek.brich@devl.cz>
parents: 75
diff changeset
   451
	int phase = 1;
54
dbe3c7a4e0f0 more raytrace_worker optimization and cleaning
Radek Brich <radek.brich@devl.cz>
parents: 53
diff changeset
   452
	bool more_samples;
50
14a727b70d07 rewritten threads with heavy debug information
Radek Brich <radek.brich@devl.cz>
parents: 49
diff changeset
   453
55
f6d75ae82c88 fix bugs
Radek Brich <radek.brich@devl.cz>
parents: 54
diff changeset
   454
	sampler->init();
f6d75ae82c88 fix bugs
Radek Brich <radek.brich@devl.cz>
parents: 54
diff changeset
   455
46
6493fb65f0b1 Doxygen
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   456
	// create workers
77
dbe8438d5dca rewrite subsampling from old code to DefaultSampler
Radek Brich <radek.brich@devl.cz>
parents: 75
diff changeset
   457
	dbgmsg(1, "* using %d threads\n", num_threads);
50
14a727b70d07 rewritten threads with heavy debug information
Radek Brich <radek.brich@devl.cz>
parents: 49
diff changeset
   458
	pthread_t threads[num_threads];
46
6493fb65f0b1 Doxygen
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   459
51
89fec8668768 remove debug messages - algorithm seems stable, but it's slow
Radek Brich <radek.brich@devl.cz>
parents: 50
diff changeset
   460
	dbgmsg(1, "* raytracing...\n");
89fec8668768 remove debug messages - algorithm seems stable, but it's slow
Radek Brich <radek.brich@devl.cz>
parents: 50
diff changeset
   461
46
6493fb65f0b1 Doxygen
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   462
	while ( (sampnum = sampler->initSampleSet()) > 0 )
6493fb65f0b1 Doxygen
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   463
	{
77
dbe8438d5dca rewrite subsampling from old code to DefaultSampler
Radek Brich <radek.brich@devl.cz>
parents: 75
diff changeset
   464
		my_pos = 0;
dbe8438d5dca rewrite subsampling from old code to DefaultSampler
Radek Brich <radek.brich@devl.cz>
parents: 75
diff changeset
   465
		sample_queue_pos = 0;
51
89fec8668768 remove debug messages - algorithm seems stable, but it's slow
Radek Brich <radek.brich@devl.cz>
parents: 50
diff changeset
   466
		sampdone = 0;
77
dbe8438d5dca rewrite subsampling from old code to DefaultSampler
Radek Brich <radek.brich@devl.cz>
parents: 75
diff changeset
   467
		end_of_samples = false;
dbe8438d5dca rewrite subsampling from old code to DefaultSampler
Radek Brich <radek.brich@devl.cz>
parents: 75
diff changeset
   468
dbe8438d5dca rewrite subsampling from old code to DefaultSampler
Radek Brich <radek.brich@devl.cz>
parents: 75
diff changeset
   469
		for (int t = 0; t < num_threads; t++)
dbe8438d5dca rewrite subsampling from old code to DefaultSampler
Radek Brich <radek.brich@devl.cz>
parents: 75
diff changeset
   470
		{
dbe8438d5dca rewrite subsampling from old code to DefaultSampler
Radek Brich <radek.brich@devl.cz>
parents: 75
diff changeset
   471
			int rc = pthread_create(&threads[t], NULL, raytrace_worker, (void*)this);
dbe8438d5dca rewrite subsampling from old code to DefaultSampler
Radek Brich <radek.brich@devl.cz>
parents: 75
diff changeset
   472
			if (rc) {
dbe8438d5dca rewrite subsampling from old code to DefaultSampler
Radek Brich <radek.brich@devl.cz>
parents: 75
diff changeset
   473
				dbgmsg(0, "\nE pthread_create unsuccessful, return code was %d\n", rc);
dbe8438d5dca rewrite subsampling from old code to DefaultSampler
Radek Brich <radek.brich@devl.cz>
parents: 75
diff changeset
   474
				exit(1);
dbe8438d5dca rewrite subsampling from old code to DefaultSampler
Radek Brich <radek.brich@devl.cz>
parents: 75
diff changeset
   475
			}
dbe8438d5dca rewrite subsampling from old code to DefaultSampler
Radek Brich <radek.brich@devl.cz>
parents: 75
diff changeset
   476
		}
dbe8438d5dca rewrite subsampling from old code to DefaultSampler
Radek Brich <radek.brich@devl.cz>
parents: 75
diff changeset
   477
90
f6a72eb99631 rename Python module from 'raytracer' to 'pyrit'
Radek Brich <radek.brich@devl.cz>
parents: 86
diff changeset
   478
		dbgmsg(2, "- phase %d:  0%% done", phase);
77
dbe8438d5dca rewrite subsampling from old code to DefaultSampler
Radek Brich <radek.brich@devl.cz>
parents: 75
diff changeset
   479
dbe8438d5dca rewrite subsampling from old code to DefaultSampler
Radek Brich <radek.brich@devl.cz>
parents: 75
diff changeset
   480
		pthread_mutex_lock(&sampler_mutex);
dbe8438d5dca rewrite subsampling from old code to DefaultSampler
Radek Brich <radek.brich@devl.cz>
parents: 75
diff changeset
   481
52
a6413a3d741d new implementation of sample_queue
Radek Brich <radek.brich@devl.cz>
parents: 51
diff changeset
   482
		for (;;)
46
6493fb65f0b1 Doxygen
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   483
		{
52
a6413a3d741d new implementation of sample_queue
Radek Brich <radek.brich@devl.cz>
parents: 51
diff changeset
   484
			my_count = 0;
53
228cb8bfdd54 slighly optimized raytrace_worker
Radek Brich <radek.brich@devl.cz>
parents: 52
diff changeset
   485
			while ( more_samples = sampler->nextSample(&sample_queue[my_pos++]) )
52
a6413a3d741d new implementation of sample_queue
Radek Brich <radek.brich@devl.cz>
parents: 51
diff changeset
   486
			{
a6413a3d741d new implementation of sample_queue
Radek Brich <radek.brich@devl.cz>
parents: 51
diff changeset
   487
				my_count++;
55
f6d75ae82c88 fix bugs
Radek Brich <radek.brich@devl.cz>
parents: 54
diff changeset
   488
				if (my_pos >= sample_queue_size)
f6d75ae82c88 fix bugs
Radek Brich <radek.brich@devl.cz>
parents: 54
diff changeset
   489
					my_pos = 0;
54
dbe3c7a4e0f0 more raytrace_worker optimization and cleaning
Radek Brich <radek.brich@devl.cz>
parents: 53
diff changeset
   490
				if (my_count >= my_count_max)
52
a6413a3d741d new implementation of sample_queue
Radek Brich <radek.brich@devl.cz>
parents: 51
diff changeset
   491
					break;
a6413a3d741d new implementation of sample_queue
Radek Brich <radek.brich@devl.cz>
parents: 51
diff changeset
   492
			}
55
f6d75ae82c88 fix bugs
Radek Brich <radek.brich@devl.cz>
parents: 54
diff changeset
   493
			if (!more_samples && !my_count)
52
a6413a3d741d new implementation of sample_queue
Radek Brich <radek.brich@devl.cz>
parents: 51
diff changeset
   494
				break;
a6413a3d741d new implementation of sample_queue
Radek Brich <radek.brich@devl.cz>
parents: 51
diff changeset
   495
50
14a727b70d07 rewritten threads with heavy debug information
Radek Brich <radek.brich@devl.cz>
parents: 49
diff changeset
   496
			pthread_mutex_unlock(&sampler_mutex);
14a727b70d07 rewritten threads with heavy debug information
Radek Brich <radek.brich@devl.cz>
parents: 49
diff changeset
   497
			pthread_mutex_lock(&sample_queue_mutex);
52
a6413a3d741d new implementation of sample_queue
Radek Brich <radek.brich@devl.cz>
parents: 51
diff changeset
   498
			sample_queue_count += my_count;
46
6493fb65f0b1 Doxygen
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   499
51
89fec8668768 remove debug messages - algorithm seems stable, but it's slow
Radek Brich <radek.brich@devl.cz>
parents: 50
diff changeset
   500
			// wait for workers if there is enough samples ready on queue
55
f6d75ae82c88 fix bugs
Radek Brich <radek.brich@devl.cz>
parents: 54
diff changeset
   501
			while (sample_queue_count > (2*num_threads-1)*my_count_max)
52
a6413a3d741d new implementation of sample_queue
Radek Brich <radek.brich@devl.cz>
parents: 51
diff changeset
   502
				pthread_cond_wait(&worker_ready_cond, &sample_queue_mutex);
55
f6d75ae82c88 fix bugs
Radek Brich <radek.brich@devl.cz>
parents: 54
diff changeset
   503
f6d75ae82c88 fix bugs
Radek Brich <radek.brich@devl.cz>
parents: 54
diff changeset
   504
			pthread_cond_signal(&sample_queue_cond);
f6d75ae82c88 fix bugs
Radek Brich <radek.brich@devl.cz>
parents: 54
diff changeset
   505
			pthread_mutex_unlock(&sample_queue_mutex);
46
6493fb65f0b1 Doxygen
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   506
52
a6413a3d741d new implementation of sample_queue
Radek Brich <radek.brich@devl.cz>
parents: 51
diff changeset
   507
			sampdone += my_count;
83
e3a2a5b26abb vectorize makeRayPacket() using SSE intrinsics
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   508
			dbgmsg(2, "\b\b\b\b\b\b\b\b%2d%% done", ((long)sampdone - sample_queue_count)*100/sampnum);
51
89fec8668768 remove debug messages - algorithm seems stable, but it's slow
Radek Brich <radek.brich@devl.cz>
parents: 50
diff changeset
   509
50
14a727b70d07 rewritten threads with heavy debug information
Radek Brich <radek.brich@devl.cz>
parents: 49
diff changeset
   510
			pthread_mutex_lock(&sampler_mutex);
77
dbe8438d5dca rewrite subsampling from old code to DefaultSampler
Radek Brich <radek.brich@devl.cz>
parents: 75
diff changeset
   511
dbe8438d5dca rewrite subsampling from old code to DefaultSampler
Radek Brich <radek.brich@devl.cz>
parents: 75
diff changeset
   512
			if (!more_samples)
dbe8438d5dca rewrite subsampling from old code to DefaultSampler
Radek Brich <radek.brich@devl.cz>
parents: 75
diff changeset
   513
				break;
46
6493fb65f0b1 Doxygen
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   514
		}
51
89fec8668768 remove debug messages - algorithm seems stable, but it's slow
Radek Brich <radek.brich@devl.cz>
parents: 50
diff changeset
   515
		dbgmsg(2, "\b\b\b\b\b\b\b\b100%% done\n");
77
dbe8438d5dca rewrite subsampling from old code to DefaultSampler
Radek Brich <radek.brich@devl.cz>
parents: 75
diff changeset
   516
dbe8438d5dca rewrite subsampling from old code to DefaultSampler
Radek Brich <radek.brich@devl.cz>
parents: 75
diff changeset
   517
		pthread_mutex_unlock(&sampler_mutex);
dbe8438d5dca rewrite subsampling from old code to DefaultSampler
Radek Brich <radek.brich@devl.cz>
parents: 75
diff changeset
   518
dbe8438d5dca rewrite subsampling from old code to DefaultSampler
Radek Brich <radek.brich@devl.cz>
parents: 75
diff changeset
   519
		// wait for workers
dbe8438d5dca rewrite subsampling from old code to DefaultSampler
Radek Brich <radek.brich@devl.cz>
parents: 75
diff changeset
   520
		dbgmsg(2, "- waiting for threads to finish\n");
46
6493fb65f0b1 Doxygen
Radek Brich <radek.brich@devl.cz>
parents: 44
diff changeset
   521
77
dbe8438d5dca rewrite subsampling from old code to DefaultSampler
Radek Brich <radek.brich@devl.cz>
parents: 75
diff changeset
   522
		pthread_mutex_lock(&sample_queue_mutex);
dbe8438d5dca rewrite subsampling from old code to DefaultSampler
Radek Brich <radek.brich@devl.cz>
parents: 75
diff changeset
   523
		end_of_samples = true;
dbe8438d5dca rewrite subsampling from old code to DefaultSampler
Radek Brich <radek.brich@devl.cz>
parents: 75
diff changeset
   524
		while (sample_queue_count)
dbe8438d5dca rewrite subsampling from old code to DefaultSampler
Radek Brich <radek.brich@devl.cz>
parents: 75
diff changeset
   525
		{
dbe8438d5dca rewrite subsampling from old code to DefaultSampler
Radek Brich <radek.brich@devl.cz>
parents: 75
diff changeset
   526
			pthread_cond_broadcast(&sample_queue_cond);
dbe8438d5dca rewrite subsampling from old code to DefaultSampler
Radek Brich <radek.brich@devl.cz>
parents: 75
diff changeset
   527
			pthread_mutex_unlock(&sample_queue_mutex);
dbe8438d5dca rewrite subsampling from old code to DefaultSampler
Radek Brich <radek.brich@devl.cz>
parents: 75
diff changeset
   528
			pthread_mutex_lock(&sample_queue_mutex);
dbe8438d5dca rewrite subsampling from old code to DefaultSampler
Radek Brich <radek.brich@devl.cz>
parents: 75
diff changeset
   529
		}
50
14a727b70d07 rewritten threads with heavy debug information
Radek Brich <radek.brich@devl.cz>
parents: 49
diff changeset
   530
		pthread_cond_broadcast(&sample_queue_cond);
14a727b70d07 rewritten threads with heavy debug information
Radek Brich <radek.brich@devl.cz>
parents: 49
diff changeset
   531
		pthread_mutex_unlock(&sample_queue_mutex);
77
dbe8438d5dca rewrite subsampling from old code to DefaultSampler
Radek Brich <radek.brich@devl.cz>
parents: 75
diff changeset
   532
dbe8438d5dca rewrite subsampling from old code to DefaultSampler
Radek Brich <radek.brich@devl.cz>
parents: 75
diff changeset
   533
		for (int t = 0; t < num_threads; t++)
dbe8438d5dca rewrite subsampling from old code to DefaultSampler
Radek Brich <radek.brich@devl.cz>
parents: 75
diff changeset
   534
			pthread_join(threads[t], NULL);
dbe8438d5dca rewrite subsampling from old code to DefaultSampler
Radek Brich <radek.brich@devl.cz>
parents: 75
diff changeset
   535
dbe8438d5dca rewrite subsampling from old code to DefaultSampler
Radek Brich <radek.brich@devl.cz>
parents: 75
diff changeset
   536
		phase ++;
50
14a727b70d07 rewritten threads with heavy debug information
Radek Brich <radek.brich@devl.cz>
parents: 49
diff changeset
   537
	}
14a727b70d07 rewritten threads with heavy debug information
Radek Brich <radek.brich@devl.cz>
parents: 49
diff changeset
   538
52
a6413a3d741d new implementation of sample_queue
Radek Brich <radek.brich@devl.cz>
parents: 51
diff changeset
   539
	delete[] sample_queue;
0
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   540
}
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   541
75
20dee9819b17 unify capitalization of method names in C++ and Python
Radek Brich <radek.brich@devl.cz>
parents: 72
diff changeset
   542
void Raytracer::ambientOcclusion(int samples, Float distance, Float angle)
0
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   543
{
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   544
	ao_samples = samples;
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   545
	ao_distance = distance;
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   546
	ao_angle = angle;
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   547
	if (ao_distance == 0)
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   548
		/* 0 ==> Inf */
53
228cb8bfdd54 slighly optimized raytrace_worker
Radek Brich <radek.brich@devl.cz>
parents: 52
diff changeset
   549
		ao_distance = Inf;
0
3547b885df7e initial commit, raytracer source as written year ago and unchanged since 2007-03-25
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   550
}