
void canvasTest(const TPixels32Ref& ctx) {
if (ctx.getIsEmpty())
return;
long w = ctx.width;
long h = ctx.height;
ctx.fillColor(Color32(0, 0, 0, 0));
Color32* pixels = ctx.pdata;
for (long y = 0; y < h; ++y){
for (long x = 0; x < w; ++x){
pixels[x].r = (UInt8)(x * 255 / w);
pixels[x].g = (UInt8)(y * 255 / h);
pixels[x].b = 0;
pixels[x].a = 255;
}
(UInt8*&)pixels += ctx.byte_width;
}
}
void renderDepth(const TPixels32Ref& ctx) {
if (ctx.getIsEmpty())
return;
Union scene;
scene.push(new Sphere(Vector3(0, 10, -10), 10));
scene.push(new Plane(Vector3(0, 1, 0), 0));
PerspectiveCamera camera(Vector3(0, 10, 10), Vector3(0, 0, -1), Vector3(0, 1, 0), 90);
long maxDepth = 20;
long w = ctx.width;
long h = ctx.height;
ctx.fillColor(Color32(0, 0, 0, 0));
Color32* pixels = ctx.pdata;
scene.initialize();
camera.initialize();
float dx = 1.0f / w;
float dy = 1.0f / h;
float dD = 255.0f / maxDepth;
for (long y = 0; y < h; ++y){
float sy = 1 - dy*y;
for (long x = 0; x < w; ++x){
float sx = dx*x;
Ray3 ray(camera.generateRay(sx, sy));
IntersectResult result = scene.intersect(ray);
if (result.geometry) {
UInt8 depth = (UInt8)(255 - std::min(result.distance*dD, 255.0f));
pixels[x].r = depth;
pixels[x].g = depth;
pixels[x].b = depth;
pixels[x].a = 255;
}
}
(UInt8*&)pixels += ctx.byte_width;
}
}
void renderNormal(const TPixels32Ref& ctx) {
if (ctx.getIsEmpty())
return;
Sphere scene(Vector3(0, 10, -10), 10);
PerspectiveCamera camera(Vector3(0, 10, 10), Vector3(0, 0, -1), Vector3(0, 1, 0), 90);
long maxDepth = 20;
long w = ctx.width;
long h = ctx.height;
ctx.fillColor(Color32(0, 0, 0, 0));
Color32* pixels = ctx.pdata;
scene.initialize();
camera.initialize();
float dx = 1.0f / w;
float dy = 1.0f / h;
float dD = 255.0f / maxDepth;
for (long y = 0; y < h; ++y){
float sy = 1 - dy*y;
for (long x = 0; x < w; ++x){
float sx = dx*x;
Ray3 ray(camera.generateRay(sx, sy));
IntersectResult result = scene.intersect(ray);
if (result.geometry) {
pixels[x].r = (UInt8)((result.normal.x + 1) * 128);
pixels[x].g = (UInt8)((result.normal.y + 1) * 128);
pixels[x].b = (UInt8)((result.normal.z + 1) * 128);
pixels[x].a = 255;
}
}
(UInt8*&)pixels += ctx.byte_width;
}
}
void rayTrace(const TPixels32Ref& ctx) {
if (ctx.getIsEmpty())
return;
Plane* plane = new Plane(Vector3(0, 1, 0), 0);
Sphere* sphere1 = new Sphere(Vector3(-10, 10, -10), 10);
Sphere* sphere2 = new Sphere(Vector3(10, 10, -10), 10);
plane->material = new CheckerMaterial(0.1f);
sphere1->material = new PhongMaterial(Color::red(), Color::white(), 16);
sphere2->material = new PhongMaterial(Color::blue(), Color::white(), 16);
Union scene;
scene.push(plane);
scene.push(sphere1);
scene.push(sphere2);
PerspectiveCamera camera(Vector3(0, 5, 15), Vector3(0, 0, -1), Vector3(0, 1, 0), 90);
long w = ctx.width;
long h = ctx.height;
ctx.fillColor(Color32(0, 0, 0, 0));
Color32* pixels = ctx.pdata;
scene.initialize();
camera.initialize();
float dx = 1.0f / w;
float dy = 1.0f / h;
for (long y = 0; y < h; ++y){
float sy = 1 - dy*y;
for (long x = 0; x < w; ++x){
float sx = dx*x;
Ray3 ray(camera.generateRay(sx, sy));
IntersectResult result = scene.intersect(ray);
if (result.geometry) {
Color color = result.geometry->material->sample(ray, result.position, result.normal);
color.saturate();
pixels[x].r = (UInt8)(color.r * 255);
pixels[x].g = (UInt8)(color.g * 255);
pixels[x].b = (UInt8)(color.b * 255);
pixels[x].a = 255;
}
}
(UInt8*&)pixels += ctx.byte_width;
}
}
Color rayTraceRecursive(IGeometry* scene, const Ray3& ray, long maxReflect) {
IntersectResult result = scene->intersect(ray);
if (result.geometry){
float reflectiveness = result.geometry->material->reflectiveness;
Color color = result.geometry->material->sample(ray, result.position, result.normal);
color = color.multiply(1 - reflectiveness);
if ((reflectiveness > 0) && (maxReflect > 0)) {
Vector3 r = result.normal.multiply(-2 * result.normal.dot(ray.direction)).add(ray.direction);
Ray3 ray = Ray3(result.position, r);
Color reflectedColor = rayTraceRecursive(scene, ray, maxReflect - 1);
color = color.add(reflectedColor.multiply(reflectiveness));
}
return color;
}
else
return Color::black();
}
void rayTraceRecursive(const TPixels32Ref& ctx) {
if (ctx.getIsEmpty())
return;
Plane* plane = new Plane(Vector3(0, 1, 0), 0);
Sphere* sphere1 = new Sphere(Vector3(-10, 10, -10), 10);
Sphere* sphere2 = new Sphere(Vector3(10, 10, -10), 10);
plane->material = new CheckerMaterial(0.1f, 0.5);
sphere1->material = new PhongMaterial(Color::red(), Color::white(), 16, 0.25);
sphere2->material = new PhongMaterial(Color::blue(), Color::white(), 16, 0.25);
Union scene;
scene.push(plane);
scene.push(sphere1);
scene.push(sphere2);
PerspectiveCamera camera(Vector3(0, 5, 15), Vector3(0, 0, -1), Vector3(0, 1, 0), 90);
long maxReflect = 3;
long w = ctx.width;
long h = ctx.height;
ctx.fillColor(Color32(0, 0, 0, 0));
Color32* pixels = ctx.pdata;
scene.initialize();
camera.initialize();
float dx = 1.0f / w;
float dy = 1.0f / h;
for (long y = 0; y < h; ++y){
float sy = 1 - dy*y;
for (long x = 0; x < w; ++x){
float sx = dx*x;
Ray3 ray(camera.generateRay(sx, sy));
Color color = rayTraceRecursive(&scene, ray, maxReflect);
color.saturate();
pixels[x].r = (UInt8)(color.r * 255);
pixels[x].g = (UInt8)(color.g * 255);
pixels[x].b = (UInt8)(color.b * 255);
pixels[x].a = 255;
}
(UInt8*&)pixels += ctx.byte_width;
}
}
主函数实现测试:
int main(){
std::cout << " 请输入回车键开始测试(可以把进程优先级设置为“实时”)> ";
waitInputChar();
std::cout << std::endl;
test("canvasTest", canvasTest, 2000);
test("renderDepth", renderDepth, 100);
test("renderNormal", renderNormal, 200);
test("rayTrace", rayTrace, 50);
test("rayTraceRecursive", rayTraceRecursive, 50);
std::cout << std::endl << " 测试完成. ";
waitInputChar();
return 0;
}
原文:http://www.cnblogs.com/yinglinx/p/5157166.html