坐标关键代码如下:
//将uv转换为-1到1之间的浮点数
float u = (x / (float) imageW)*2.0f-1.0f;
float v = (y / (float) imageH)*2.0f-1.0f;
// calculate eye ray in world space
Ray eyeRay;
eyeRay.o = make_float3(mul(c_invViewMatrix, make_float4(0.0f, 0.0f, 0.0f, 1.0f)));
eyeRay.d = normalize(make_float3(u, v, -2.0f));//
eyeRay.d = mul(c_invViewMatrix, eyeRay.d);//
// find intersection with box
float tnear, tfar;
int hit = intersectBox(eyeRay, boxMin, boxMax, &tnear, &tfar);
if (!hit) return;
if (tnear < 0.0f) tnear = 0.0f; // clamp to near plane
// march along ray from front to back, accumulating color
float4 sum = make_float4(0.0f);
float t = tnear;
float3 pos = eyeRay.o + eyeRay.d*tnear;
float3 step = eyeRay.d*tstep;
for(int i=0; i<maxSteps; i++) {
// read from 3D texture
// remap position to [0, 1] coordinates
float sample = tex3D(tex, pos.x*0.5f+0.5f, pos.y*0.5f+0.5f, pos.z*0.5f+0.5f);//?
1、先声明,世界坐标系为x [-1, 1]; y [-1, 1]; z[-1, 1]。(自己随便说是世界坐标系)
2、u,v可以肯定是在[-1, 1]之间变化的,因为x和y 的变化范围分别在[0,imageW]和[0,imageH]变化(x / (float) imageW)在[0,1]变化乘以2在[0,2]变化,再减1,在[-1, 1]变化。
3、说明视线的变化。首先规定眼睛的位置:make_float4(0.0f, 0.0f, 0.0f, 1.0f);然后对眼睛的位置进行仿射变换:mul(c_invViewMatrix, make_float4(0.0f, 0.0f, 0.0f, 1.0f)),这里变换矩阵是变换视点的矩阵,所以是模型变换的逆矩阵。最后,mul(c_invViewMatrix, eyeRay.d); 对视线进行变换。
4、求交,求交也是在世界坐标系下。
5、求纹理坐标。由于纹理生成时,使用了:tex.normalized = true; 所以会对坐标进行标准化范围[0, 1],所以又需要将坐标变换到[0, 1]之间,tex3D(tex, pos.x*0.5f+0.5f, pos.y*0.5f+0.5f, pos.z*0.5f+0.5f); 意思是:[-1, 1]*0.5 + 0.5 = [0, 1]
至此坐标变换完成。