这是我在这里的第一个问题,所以我希望我做得对。
我正在尝试为学校项目构建光线跟踪器,并且我想在我的基本形状中添加一些纹理贴图。我已经为球体做了它并且它完美地工作,这是我使用的算法(UV映射):
d = vector3d_normalize(vector3d_sub(hit->point, object->position));
u = 0.5 + atan2(d.z, d.x) / M_PI * 0.5;
v = 0.5 - asin(d.y) / M_PI;
对于气缸,我找不到任何算法,所以我尝试不同的东西,但我不能使它工作。实际上,当它固定在(x:0,y:0,z:0)时,它适用于圆柱体,但是从我在空间中移动它的那一刻起,纹理看起来很拉伸。
对于此时的代码,它包含以下内容:
d = vector3d_sub(hit->point, vector3d_mult(object->position, ray->direction));
u = 0.5 + atan2(d.z, d.x) / M_PI * 0.5;
v = d.y / M_PI;
v = v - floor(v);
(0,0,0)中的圆柱:
使用翻译:
如果你有任何想法,我会陷入困境,这对我有很大的帮助!
答案 0 :(得分:0)
以下是Jamis's Buck的 Ray Tracer Challenge (强烈推荐)中的一些伪代码:
// Based off of pseudocode from Jamis Buck: http://raytracerchallenge.com/bonus/texture-mapping.html
// Input: point on the cylinder. The cylinder is assumed to be of radius 1, centered at the origin and parallel with the y axis.
// Output: (u,v) with u and v both between 0 and 1.
// u will vary from 0 to 1 with the azimuthal angle, counter-clockwise.
// v will vary from 0 to 1 with whole units of y; note that the cylinder will have to be scaled by PI in the y axis to prevent stretching
map_cylinder_point_to_uv(point: (x: float, y: float, z: float)) -> (float, float) {
// compute the azimuthal angle, -PI < theta <= PI
float theta = arctan2(point.x, point.z);
// convert from radians to units
// -0.5 < rawU <= 0.5
float rawU = theta / (2 * Constants.PI)
// convert to correct scale, and flip it so that u increases with theta counter-clockwise
// 0 <= u < 1
float u = 1 - (rawU + 0.5);
// v will vary from 0 to 1 between whole units of y
// Use whatever modulus method or operator your language has to gauarantee a positive value for v.
// It's different for every programming language: https://en.wikipedia.org/wiki/Modulo_operation#In_programming_languages
float v = point.y % 1
return (u, v)
}
您的问题可能与以下事实有关:您在圆柱体上放置了正方形纹理,并且应用于圆柱体侧面的纹理的长度将是2 PI(圆的周长)的倍数。您只需通过PI或2 PI在y轴上缩放圆柱即可解决您的问题。
如果您不希望局限于特定尺寸的圆柱,并且具有可以像方格图案一样重复的纹理,则可以缩放v以防止拉伸。将此行替换上面的v
计算,
// let v go from 0 to 1 between 2*pi units of y
let v = point.y % (2 * Constants.PI) * 1 / (2 * Constants.PI);
我还将注意到,最近几天,计算机图形的堆栈交换可能比SO更有用:https://computergraphics.stackexchange.com/。