射线追踪是一种通过模拟光线在虚拟环境中的传播路径来生成逼真图像的渲染技术。
matlab
%% 3D射线追踪渲染器
% 功能: 实现完整的3D射线追踪渲染引擎
% 特性: 支持多种几何体、Phong光照模型、阴影、反射和折射
clear; clc; close all;
%% 1. 场景参数设置
width = 800; % 图像宽度 (像素)
height = 600; % 图像高度 (像素)
fov = 60; % 视场角 (度)
maxDepth = 3; % 最大反射/折射深度
backgroundColor = [0.1, 0.1, 0.3]; % 背景色 (深蓝色)
% 相机设置
cameraPos = [0, 1.5, -5]; % 相机位置
lookAt = [0, 1, 0]; % 观察点
upVector = [0, 1, 0]; % 上方向
% 光源设置
lightSources = [
struct('pos', [3, 4, -2], 'color', [1, 1, 1], 'intensity', 1.0); % 主光源
struct('pos', [-5, 3, 1], 'color', [0.8, 0.6, 0.4], 'intensity', 0.6) % 辅助光源
];
%% 2. 场景几何体定义
% 球体
sphere1 = struct('type', 'sphere', ...
'center', [0, 1, 0], ...
'radius', 1.0, ...
'material', struct('diffuse', [0.8, 0.2, 0.2], 'specular', [1, 1, 1], 'shininess', 50, 'reflectivity', 0.3, 'transparency', 0, 'refractiveIndex', 1.5));
sphere2 = struct('type', 'sphere', ...
'center', [-2, 0.5, 2], ...
'radius', 0.8, ...
'material', struct('diffuse', [0.2, 0.8, 0.2], 'specular', [1, 1, 1], 'shininess', 80, 'reflectivity', 0.5, 'transparency', 0, 'refractiveIndex', 1.5));
sphere3 = struct('type', 'sphere', ...
'center', [1.5, 0.3, -1], ...
'radius', 0.6, ...
'material', struct('diffuse', [0.2, 0.2, 0.8], 'specular', [1, 1, 1], 'shininess', 30, 'reflectivity', 0.2, 'transparency', 0.8, 'refractiveIndex', 1.5));
% 平面 (地面)
plane1 = struct('type', 'plane', ...
'point', [0, 0, 0], ...
'normal', [0, 1, 0], ...
'material', struct('diffuse', [0.7, 0.7, 0.7], 'specular', [0.5, 0.5, 0.5], 'shininess', 20, 'reflectivity', 0.1, 'transparency', 0, 'refractiveIndex', 1.0));
% 三角形网格 (立方体)
cubeVertices = [
[-1, -1, -1]; [1, -1, -1]; [1, 1, -1]; [-1, 1, -1];
[-1, -1, 1]; [1, -1, 1]; [1, 1, 1]; [-1, 1, 1]
];
cubeFaces = [
[1, 2, 3, 4]; % 底面
[5, 6, 7, 8]; % 顶面
[1, 2, 6, 5]; % 前面
[2, 3, 7, 6]; % 右面
[3, 4, 8, 7]; % 后面
[4, 1, 5, 8] % 左面
];
cube = struct('type', 'mesh', ...
'vertices', cubeVertices, ...
'faces', cubeFaces, ...
'position', [0, 0.5, 0], ... % 立方体位置
'rotation', [0, 0, 0], ... % 旋转角度
'material', struct('diffuse', [0.8, 0.5, 0.2], 'specular', [1, 1, 1], 'shininess', 40, 'reflectivity', 0.4, 'transparency', 0, 'refractiveIndex', 1.5));
% 将所有对象放入场景
sceneObjects = [sphere1, sphere2, sphere3, plane1, cube];
%% 3. 向量运算函数
% 归一化向量
function v_norm = normalize(v)
norm_v = norm(v);
if norm_v > 0
v_norm = v / norm_v;
else
v_norm = v;
end
end
% 点乘
function dot_product = dot(v1, v2)
dot_product = sum(v1 .* v2);
end
% 叉乘
function cross_product = cross(v1, v2)
cross_product = [v1(2)*v2(3) - v1(3)*v2(2), ...
v1(3)*v2(1) - v1(1)*v2(3), ...
v1(1)*v2(2) - v1(2)*v2(1)];
end
% 反射向量
function r = reflect(i, n)
r = i - 2 * dot(i, n) * n;
end
% 折射向量 (斯涅尔定律)
function [refracted, refractedExists] = refract(i, n, eta)
cosi = max(min(dot(i, n), 1), -1);
etai = 1; % 空气折射率
etat = eta;
if cosi < 0
cosi = -cosi;
else
[n, etat, etai] = deal(-n, etai, etat);
end
eta_ratio = etai / etat;
k = 1 - eta_ratio^2 * (1 - cosi^2);
if k < 0
refracted = [0, 0, 0];
refractedExists = false;
else
refracted = eta_ratio * i + (eta_ratio * cosi - sqrt(k)) * n;
refractedExists = true;
end
end
%% 4. 光线生成
% 生成相机光线
function ray = generateCameraRay(u, v, cameraPos, lookAt, upVector, fov, width, height)
aspectRatio = width / height;
fovRad = deg2rad(fov);
scale = tan(fovRad / 2);
% 计算相机坐标系
forward = normalize(lookAt - cameraPos);
right = normalize(cross(forward, upVector));
up = cross(right, forward);
% 计算图像平面上的点
pixelX = (2 * (u + 0.5) / width - 1) * aspectRatio * scale;
pixelY = (1 - 2 * (v + 0.5) / height) * scale;
% 光线方向
direction = normalize(pixelX * right + pixelY * up + forward);
ray.origin = cameraPos;
ray.direction = direction;
end
%% 5. 光线与物体相交计算
% 光线与球体相交
function [hit, t, point, normal] = intersectSphere(ray, sphere)
oc = ray.origin - sphere.center;
a = dot(ray.direction, ray.direction);
b = 2 * dot(oc, ray.direction);
c = dot(oc, oc) - sphere.radius^2;
discriminant = b^2 - 4*a*c;
if discriminant < 0
hit = false;
t = inf;
point = [0, 0, 0];
normal = [0, 0, 0];
return;
end
t1 = (-b - sqrt(discriminant)) / (2*a);
t2 = (-b + sqrt(discriminant)) / (2*a);
if t1 > 0.001
t = t1;
elseif t2 > 0.001
t = t2;
else
hit = false;
t = inf;
point = [0, 0, 0];
normal = [0, 0, 0];
return;
end
hit = true;
point = ray.origin + t * ray.direction;
normal = normalize(point - sphere.center);
end
% 光线与平面相交
function [hit, t, point, normal] = intersectPlane(ray, plane)
denom = dot(plane.normal, ray.direction);
if abs(denom) > 1e-6
t = dot(plane.point - ray.origin, plane.normal) / denom;
if t >= 0.001
hit = true;
point = ray.origin + t * ray.direction;
normal = plane.normal;
else
hit = false;
t = inf;
point = [0, 0, 0];
normal = [0, 0, 0];
end
else
hit = false;
t = inf;
point = [0, 0, 0];
normal = [0, 0, 0];
end
end
% 光线与三角形相交 (Möller--Trumbore算法)
function [hit, t, point, normal] = intersectTriangle(ray, v0, v1, v2)
epsilon = 1e-6;
edge1 = v1 - v0;
edge2 = v2 - v0;
pvec = cross(ray.direction, edge2);
det = dot(edge1, pvec);
if abs(det) < epsilon
hit = false;
t = inf;
point = [0, 0, 0];
normal = [0, 0, 0];
return;
end
inv_det = 1.0 / det;
tvec = ray.origin - v0;
u = dot(tvec, pvec) * inv_det;
if u < 0 || u > 1
hit = false;
t = inf;
point = [0, 0, 0];
normal = [0, 0, 0];
return;
end
qvec = cross(tvec, edge1);
v = dot(ray.direction, qvec) * inv_det;
if v < 0 || u + v > 1
hit = false;
t = inf;
point = [0, 0, 0];
normal = [0, 0, 0];
return;
end
t = dot(edge2, qvec) * inv_det;
if t > 0.001
hit = true;
point = ray.origin + t * ray.direction;
normal = normalize(cross(edge1, edge2));
else
hit = false;
t = inf;
point = [0, 0, 0];
normal = [0, 0, 0];
end
end
% 光线与网格相交
function [hit, t_min, point, normal] = intersectMesh(ray, mesh)
t_min = inf;
hit_point = [0, 0, 0];
hit_normal = [0, 0, 0];
hit = false;
% 应用位置和旋转变换
vertices = mesh.vertices;
for i = 1:size(vertices, 1)
% 旋转
rot = mesh.rotation;
R = [cos(rot(3)) -sin(rot(3)) 0; sin(rot(3)) cos(rot(3)) 0; 0 0 1] * ...
[cos(rot(2)) 0 sin(rot(2)); 0 1 0; -sin(rot(2)) 0 cos(rot(2))] * ...
[1 0 0; 0 cos(rot(1)) -sin(rot(1)); 0 sin(rot(1)) cos(rot(1))];
vertices(i, :) = (R * vertices(i, :)')' + mesh.position;
end
% 检查每个面
for f = 1:size(mesh.faces, 1)
face = mesh.faces(f, :);
v0 = vertices(face(1), :);
v1 = vertices(face(2), :);
v2 = vertices(face(3), :);
[tri_hit, t, point, normal] = intersectTriangle(ray, v0, v1, v2);
if tri_hit && t < t_min
t_min = t;
hit_point = point;
hit_normal = normal;
hit = true;
end
end
if hit
t = t_min;
point = hit_point;
normal = hit_normal;
else
t = inf;
point = [0, 0, 0];
normal = [0, 0, 0];
end
end
% 光线与场景相交 (返回最近的交点)
function [hit, closestObj, t, point, normal] = intersectScene(ray, sceneObjects)
closest_t = inf;
hit = false;
closestObj = [];
point = [0, 0, 0];
normal = [0, 0, 0];
for obj_idx = 1:length(sceneObjects)
obj = sceneObjects(obj_idx);
[obj_hit, obj_t, obj_point, obj_normal] = deal(false, inf, [0,0,0], [0,0,0]);
switch obj.type
case 'sphere'
[obj_hit, obj_t, obj_point, obj_normal] = intersectSphere(ray, obj);
case 'plane'
[obj_hit, obj_t, obj_point, obj_normal] = intersectPlane(ray, obj);
case 'mesh'
[obj_hit, obj_t, obj_point, obj_normal] = intersectMesh(ray, obj);
end
if obj_hit && obj_t < closest_t
closest_t = obj_t;
hit = true;
closestObj = obj;
point = obj_point;
normal = obj_normal;
end
end
t = closest_t;
end
%% 6. 光照模型
% Phong光照模型
function color = phongShading(point, normal, material, light, cameraPos, objects)
lightDir = normalize(light.pos - point);
viewDir = normalize(cameraPos - point);
reflectDir = reflect(-lightDir, normal);
% 环境光
ambient = 0.1 * material.diffuse;
% 漫反射
diff = max(dot(normal, lightDir), 0);
diffuse = diff * material.diffuse;
% 镜面反射
spec = pow(max(dot(viewDir, reflectDir), 0), material.shininess);
specular = spec * material.specular;
% 阴影检测
shadowRayOrigin = point + normal * 1e-4; % 偏移避免自相交
shadowRayDir = normalize(light.pos - point);
[shadowHit, ~, shadow_t, ~, ~] = intersectScene(struct('origin', shadowRayOrigin, 'direction', shadowRayDir), objects);
% 如果阴影光线击中物体且在光源之前,则处于阴影中
inShadow = false;
if shadowHit && shadow_t < norm(light.pos - point)
inShadow = true;
end
if inShadow
color = ambient;
else
% 组合光照分量
lightContrib = (ambient + diffuse + specular) * light.color * light.intensity;
color = material.diffuse * lightContrib; % 简化处理
end
end
%% 7. 射线追踪核心函数
function color = traceRay(ray, sceneObjects, lightSources, cameraPos, depth)
if depth > maxDepth
color = backgroundColor;
return;
end
% 寻找最近的交点
[hit, closestObj, t, point, normal] = intersectScene(ray, sceneObjects);
if ~hit
color = backgroundColor;
return;
end
material = closestObj.material;
localColor = [0, 0, 0];
% 计算所有光源的贡献
for i = 1:length(lightSources)
light = lightSources(i);
localColor = localColor + phongShading(point, normal, material, light, cameraPos, sceneObjects);
end
% 初始化最终颜色
finalColor = localColor;
% 反射
if material.reflectivity > 0
reflectDir = reflect(normalize(ray.direction), normal);
reflectRay = struct('origin', point + normal * 1e-4, 'direction', reflectDir);
reflectedColor = traceRay(reflectRay, sceneObjects, lightSources, cameraPos, depth + 1);
finalColor = finalColor + material.reflectivity * reflectedColor;
end
% 折射
if material.transparency > 0
refractDir = refract(normalize(ray.direction), normal, material.refractiveIndex);
if ~isnan(refractDir(1))
refractRay = struct('origin', point - normal * 1e-4, 'direction', refractDir);
refractedColor = traceRay(refractRay, sceneObjects, lightSources, cameraPos, depth + 1);
finalColor = finalColor + material.transparency * refractedColor;
end
end
% 限制颜色值在合理范围内
finalColor = min(finalColor, 1.0);
color = finalColor;
end
%% 8. 渲染场景
% 创建图像缓冲区
image = zeros(height, width, 3);
% 进度条
h = waitbar(0, '渲染场景中...');
% 对每个像素进行射线追踪
for y = 1:height
for x = 1:width
% 生成相机光线
ray = generateCameraRay(x, y, cameraPos, lookAt, upVector, fov, width, height);
% 追踪光线
color = traceRay(ray, sceneObjects, lightSources, cameraPos, 0);
% 存储颜色
image(y, x, :) = color;
% 更新进度条
if mod(x, 10) == 0
waitbar((y-1)*width + x / (width*height), h);
end
end
end
close(h);
%% 9. 显示和保存结果
% 转换为uint8格式
image = uint8(image * 255);
% 显示图像
figure('Name', '射线追踪渲染结果', 'Position', [100, 100, width, height]);
imshow(image);
axis off;
% 保存图像
imwrite(image, 'raytraced_scene.png');
fprintf('渲染完成! 图像已保存为 raytraced_scene.png\n');
%% 10. 高级功能:抗锯齿
function antiAliasedImage = applyAntiAliasing(image, samplesPerPixel)
[height, width, ~] = size(image);
antiAliasedImage = zeros(height, width, 3);
for y = 1:height
for x = 1:width
colorSum = [0, 0, 0];
for sy = 1:samplesPerPixel
for sx = 1:samplesPerPixel
% 在像素内随机采样
offsetX = (sx - 0.5) / samplesPerPixel;
offsetY = (sy - 0.5) / samplesPerPixel;
sampleX = min(width, max(1, round(x + offsetX)));
sampleY = min(height, max(1, round(y + offsetY)));
colorSum = colorSum + double(image(sampleY, sampleX, :)) / 255;
end
end
antiAliasedImage(y, x, :) = colorSum / (samplesPerPixel^2);
end
end
end
% 应用抗锯齿
aaImage = applyAntiAliasing(image, 2);
aaImage = uint8(aaImage * 255);
figure('Name', '抗锯齿处理后', 'Position', [100, 100, width, height]);
imshow(aaImage);
axis off;
imwrite(aaImage, 'raytraced_scene_aa.png');
%% 11. 性能分析
% 计算渲染时间
tic;
% 渲染代码...
renderTime = toc;
fprintf('渲染时间: %.2f 秒\n', renderTime);
fprintf('每像素平均时间: %.4f 毫秒\n', (renderTime * 1000) / (width * height));
% 内存使用分析
memUsage = whos('image', 'sceneObjects', 'lightSources');
fprintf('\n内存使用情况:\n');
for i = 1:length(memUsage)
fprintf('%s: %.2f MB\n', memUsage(i).name, memUsage(i).bytes / (1024^2));
end
射线追踪技术原理与实现
1. 射线追踪基本概念
射线追踪是一种基于物理的渲染技术,通过模拟光线在虚拟环境中的传播路径来生成逼真图像。核心思想是从相机发射射线穿过每个像素,计算射线与场景中物体的交点,并根据光照模型确定像素颜色。
关键组件:
- 光线生成:从相机位置发射穿过像素的光线
- 相交检测:计算光线与几何体的交点
- 光照模型:计算交点处的光照贡献
- 阴影计算:检测光线是否被遮挡
- 反射/折射:模拟光线的反射和折射行为
2. 场景构建与几何体表示
(1) 场景对象定义
matlab
% 球体
sphere = struct('type', 'sphere', ...
'center', [0, 1, 0], ...
'radius', 1.0, ...
'material', struct('diffuse', [0.8, 0.2, 0.2], ...));
% 平面
plane = struct('type', 'plane', ...
'point', [0, 0, 0], ...
'normal', [0, 1, 0], ...
'material', struct('diffuse', [0.7, 0.7, 0.7], ...));
% 网格
mesh = struct('type', 'mesh', ...
'vertices', [...], ...
'faces', [...], ...
'position', [0, 0, 0], ...
'material', struct(...));
(2) 材质属性
matlab
material = struct(...
'diffuse', [0.8, 0.2, 0.2], % 漫反射颜色
'specular', [1, 1, 1], % 镜面反射颜色
'shininess', 50, % 光泽度 (0-100)
'reflectivity', 0.3, % 反射率 (0-1)
'transparency', 0, % 透明度 (0-1)
'refractiveIndex', 1.5 % 折射率
);
3. 光线与几何体相交计算
(1) 光线-球体相交
matlab
function [hit, t, point, normal] = intersectSphere(ray, sphere)
oc = ray.origin - sphere.center;
a = dot(ray.direction, ray.direction);
b = 2 * dot(oc, ray.direction);
c = dot(oc, oc) - sphere.radius^2;
discriminant = b^2 - 4*a*c;
if discriminant < 0
hit = false; t = inf; return;
end
t1 = (-b - sqrt(discriminant)) / (2*a);
t2 = (-b + sqrt(discriminant)) / (2*a);
t = min(t1, t2);
if t < 0.001, t = max(t1, t2); end
if t < 0.001, hit = false; return; end
hit = true;
point = ray.origin + t * ray.direction;
normal = normalize(point - sphere.center);
end
(2) 光线-平面相交
matlab
function [hit, t, point, normal] = intersectPlane(ray, plane)
denom = dot(plane.normal, ray.direction);
if abs(denom) < 1e-6, hit = false; return; end
t = dot(plane.point - ray.origin, plane.normal) / denom;
if t < 0.001, hit = false; return; end
hit = true;
point = ray.origin + t * ray.direction;
normal = plane.normal;
end
(3) 光线-三角形相交 (Möller--Trumbore算法)
matlab
function [hit, t, point, normal] = intersectTriangle(ray, v0, v1, v2)
edge1 = v1 - v0;
edge2 = v2 - v0;
pvec = cross(ray.direction, edge2);
det = dot(edge1, pvec);
if abs(det) < 1e-6, hit = false; return; end
inv_det = 1.0 / det;
tvec = ray.origin - v0;
u = dot(tvec, pvec) * inv_det;
if u < 0 || u > 1, hit = false; return; end
qvec = cross(tvec, edge1);
v = dot(ray.direction, qvec) * inv_det;
if v < 0 || u + v > 1, hit = false; return; end
t = dot(edge2, qvec) * inv_det;
if t < 0.001, hit = false; return; end
hit = true;
point = ray.origin + t * ray.direction;
normal = normalize(cross(edge1, edge2));
end
4. 光照模型与阴影
(1) Phong光照模型
matlab
function color = phongShading(point, normal, material, light, cameraPos, objects)
lightDir = normalize(light.pos - point);
viewDir = normalize(cameraPos - point);
reflectDir = reflect(-lightDir, normal);
% 环境光
ambient = 0.1 * material.diffuse;
% 漫反射
diff = max(dot(normal, lightDir), 0);
diffuse = diff * material.diffuse;
% 镜面反射
spec = pow(max(dot(viewDir, reflectDir), 0), material.shininess);
specular = spec * material.specular;
% 阴影检测
shadowRayOrigin = point + normal * 1e-4;
shadowRayDir = normalize(light.pos - point);
[shadowHit, ~, shadow_t, ~, ~] = intersectScene(...);
if shadowHit && shadow_t < norm(light.pos - point)
color = ambient; % 处于阴影中
else
lightContrib = (ambient + diffuse + specular) * light.color * light.intensity;
color = material.diffuse * lightContrib;
end
end
(2) 阴影计算
matlab
% 从交点向光源发射阴影射线
shadowRayOrigin = point + normal * 1e-4; % 微小偏移避免自相交
shadowRayDir = normalize(light.pos - point);
[shadowHit, ~, shadow_t, ~, ~] = intersectScene(struct('origin', shadowRayOrigin, 'direction', shadowRayDir), objects);
% 检查是否在阴影中
inShadow = shadowHit && (shadow_t < norm(light.pos - point));
5. 反射与折射
(1) 反射向量计算
matlab
function r = reflect(i, n)
r = i - 2 * dot(i, n) * n;
end
(2) 折射向量计算 (斯涅尔定律)
matlab
function [refracted, refractedExists] = refract(i, n, eta)
cosi = max(min(dot(i, n), 1), -1);
etai = 1; etat = eta;
if cosi < 0
cosi = -cosi;
else
[n, etat, etai] = deal(-n, etai, etat);
end
eta_ratio = etai / etat;
k = 1 - eta_ratio^2 * (1 - cosi^2);
if k < 0
refracted = [0, 0, 0];
refractedExists = false;
else
refracted = eta_ratio * i + (eta_ratio * cosi - sqrt(k)) * n;
refractedExists = true;
end
end
(3) 递归射线追踪
matlab
function color = traceRay(ray, sceneObjects, lightSources, cameraPos, depth)
if depth > maxDepth
return backgroundColor;
end
% 计算交点
[hit, closestObj, t, point, normal] = intersectScene(ray, sceneObjects);
if ~hit
return backgroundColor;
end
% 局部光照计算
localColor = computeLighting(point, normal, closestObj.material, ...);
% 反射
if material.reflectivity > 0
reflectDir = reflect(normalize(ray.direction), normal);
reflectRay = struct('origin', point + normal*1e-4, 'direction', reflectDir);
reflectedColor = traceRay(reflectRay, sceneObjects, lightSources, cameraPos, depth+1);
localColor = localColor + material.reflectivity * reflectedColor;
end
% 折射
if material.transparency > 0
refractDir = refract(normalize(ray.direction), normal, material.refractiveIndex);
if refractedDirExists
refractRay = struct('origin', point - normal*1e-4, 'direction', refractDir);
refractedColor = traceRay(refractRay, sceneObjects, lightSources, cameraPos, depth+1);
localColor = localColor + material.transparency * refractedColor;
end
end
return localColor;
end
参考代码 实现3D环境下的射线追踪 www.youwenfan.com/contentcsn/83524.html
6. 性能优化技术
(1) 空间加速结构
matlab
% 使用包围盒层次结构(BVH)
function buildBVH(objects)
% 递归构建二叉树
% 每个节点包含包围盒和指向子节点的指针
end
function [hit, obj, t] = intersectBVH(ray, bvhRoot)
% 遍历BVH树进行高效相交测试
end
(2) 重要性采样
matlab
% 对光源进行重要性采样
function sampleLightContribution(point, normal, material, light)
% 计算直接光照贡献
% 使用蒙特卡洛积分减少噪声
end
(3) 并行计算
matlab
% 使用parfor并行处理像素
parfor y = 1:height
for x = 1:width
% 渲染像素
end
end
7. 高级渲染效果
(1) 软阴影
matlab
function softShadow(point, light, objects)
shadowIntensity = 0;
numSamples = 16; % 光源采样数
for i = 1:numSamples
% 在单位圆盘上随机采样
samplePoint = light.pos + randomDiskSample() * light.radius;
shadowRay = struct('origin', point, 'direction', normalize(samplePoint - point));
[hit, t] = intersectScene(shadowRay, objects);
if ~hit || t > norm(samplePoint - point)
shadowIntensity = shadowIntensity + 1;
end
end
return shadowIntensity / numSamples;
end
(2) 环境光遮蔽(AO)
matlab
function ao = ambientOcclusion(point, normal, objects)
aoIntensity = 0;
numSamples = 32;
maxDist = 2.0;
for i = 1:numSamples
dir = randomHemisphereDirection(normal);
ray = struct('origin', point + normal*0.01, 'direction', dir);
[hit, t] = intersectScene(ray, objects);
if hit && t < maxDist
aoIntensity = aoIntensity + 1;
end
end
return 1 - (aoIntensity / numSamples);
end
(3) 景深效果
matlab
function ray = generateDOFRay(u, v, cameraPos, lookAt, upVector, fov, aperture, focalLength)
% 生成带有光圈偏移的主光线
mainRay = generateCameraRay(u, v, cameraPos, lookAt, upVector, fov, width, height);
% 随机光圈采样
lensOffset = aperture * randomDiskSample();
% 计算焦点平面交点
focalPoint = cameraPos + focalLength * mainRay.direction;
% 新光线起点和终点
ray.origin = cameraPos + [lensOffset(1), lensOffset(2), 0];
ray.direction = normalize(focalPoint - ray.origin);
end
应用场景与扩展
1. 应用领域
- 电影特效:创造逼真的视觉效果
- 建筑设计:可视化建筑方案
- 游戏开发:离线渲染高质量静态场景
- 科学可视化:模拟光学现象
- 虚拟现实:生成沉浸式环境
2. 扩展功能
matlab
% 纹理映射
function color = applyTexture(point, material)
if isfield(material, 'texture')
uv = mapToUV(point);
color = textureMap(uv, material.texture);
else
color = material.diffuse;
end
end
% 凹凸贴图
function perturbedNormal = bumpMapping(point, normal, material)
if isfield(material, 'bumpMap')
du = [0.01, 0, 0]; dv = [0, 0, 0.01];
height_u = getHeight(point + du, material.bumpMap);
height_v = getHeight(point + dv, material.bumpMap);
dhdu = (height_u - getHeight(point, material.bumpMap)) / 0.01;
dhdv = (height_v - getHeight(point, material.bumpMap)) / 0.01;
tangent = [1, 0, dhdu]; binormal = [0, 1, dhdv];
perturbedNormal = normalize(cross(tangent, binormal));
else
perturbedNormal = normal;
end
end
% 体积渲染
function transmittance = volumeRendering(ray, densityField)
stepSize = 0.1;
transmittance = 1.0;
colorAccum = [0, 0, 0];
for t = 0:stepSize:10
point = ray.origin + t * ray.direction;
density = sampleDensity(point, densityField);
if density > 0
lightAttenuation = exp(-integrateDensityAlongRay(...));
scattering = density * stepSize;
color = material.albedo * lightColor * lightAttenuation;
colorAccum = colorAccum + transmittance * scattering * color;
transmittance = transmittance * exp(-scattering);
end
if transmittance < 0.01, break; end
end
return colorAccum;
end
3. 与其他技术结合
- 光线追踪 + 光栅化:混合渲染管线
- AI降噪:使用神经网络减少渲染噪点
- GPU加速:CUDA/OpenCL实现实时射线追踪
- 云渲染:分布式渲染农场处理复杂场景
总结
- 场景构建:支持球体、平面、网格等多种几何体
- 材质系统:实现Phong光照模型,支持反射、折射和透明度
- 高级效果:阴影、环境光遮蔽、景深等
- 性能优化:递归深度控制、加速结构接口
- 扩展接口:纹理映射、凹凸贴图、体积渲染