【发布时间】:2019-02-10 14:07:59
【问题描述】:
我目前正在编写一个带有三角形相交的光线追踪器。我已将网格导出为 .raw 格式,只是为了获得每个顶点的坐标。 我注意到一件事,当我旋转相机时,它会显示出被遮挡的网格。
我在我的片段着色器下面发布了我的三角形相交函数
bool hitTriangle(vec3 orig,vec3 dir,vec3 a,vec3 b,vec3 c,out vec3 uvt,out vec3 triangleNormal){
float eps=1e-8;
vec3 ab=b-a;
vec3 ac=c-a;
triangleNormal = normalize(cross(ab,ac));
vec3 n=cross(dir,ac);
float det=dot(ab,n);
// if the determinant is negative the triangle is backfacing
// if the determinant is close to 0, the ray misses the triangl
if(det<=eps){ return false;}
vec3 ao=orig-a;
float u=dot(ao,n)/det;
if(u<0.0 || u>1.0){ return false;}
vec3 e=cross(ao,ab);
float v=dot(dir,e)/det;
if(v<0.0||u+v>1.0){ return false;}
float t= dot(ac,e)/det;
uvt = vec3(u,v,t);
return true;
}
在它下面是 hitScene 函数,我在其中穿过所有网格并检查交叉点
bool hitScene(Ray R_, out vec3 hitPos, out vec3 normal, out Material material, Sphere lightSource){ // na thimithw na thesw to isShpere false stin trace synartisi
vec4 a = vec4(0.0), b = vec4(0.0), c = vec4(0.0);
float mindist = -1000.;
bool weHitSomething = false;
vec3 hitPos1 = vec3(0.),triangleNormal = vec3(0.,0.,0.), sphereNormal;
//here we chck all the mesh if we hit a triangle if the mesh and we keep the closest hitpoint
for (int i = 0; i < vertsCount; i += 3) {
a = texelFetch(uMeshData, ivec2(i, 0), 0);
b = texelFetchOffset(uMeshData, ivec2(i, 0), 0, ivec2(1, 0));
c = texelFetchOffset(uMeshData, ivec2(i, 0), 0, ivec2(2, 0));
vec3 uvt;
bool isHit = hitTriangle(R_.orig,R_.dir, a.xyz,b.xyz,c.xyz,uvt, triangleNormal);
if (isHit) {
vec3 intersect = R_.orig + R_.dir*uvt.z;
float z = intersect.z;
if (z>mindist) {
hitPos1 = intersect;
mindist = z;
weHitSomething = true;
material.type = METAL;
material.albedo = vec3(.0, .8, .8);
normal = triangleNormal;
hitPos = hitPos1;
}
}
}
return weHitSomething;
}
下面是遍历traces的Trace函数
//Trace is the main function of the max bounces
vec3 Trace(out Ray ray, Sphere lightSource){
vec3 hitPos, normal;
bool isShpere;
Material material;
vec3 color = vec3(1.);
vec3 attenuation = vec3(1.);
vec3 light = vec3(1.,1.,1.), shadow = vec3(1.,1.,1.);
//this if for every ray to bounce 4 times.(hopefully)
for(int i=0; i< MAX_BOUNCES; i++){
// we check if we hit something
if(hitScene(ray, hitPos, normal, material, lightSource)){
//we calculate the new direction
vec3 direction = normalize(reflect(ray.dir, normal));
ray = Ray(hitPos, direction);
color *= material.albedo * attenuation*hitPos;
attenuation *= material.albedo;
}
else{
color = attenuation;
}
}
return color;
}
然后我得到类似的东西: 如您所见,我正在反射,但我在球体内也看到了立方体。这是否意味着我未通过射线三角形相交测试?还是最小距离不正确??
问题的根源是什么?
【问题讨论】:
-
@rabbid76 jsfiddle.net/dominuss/qLcp0rn2/5 这是一个最小的完整示例吗?如果不是我可以试试。问题是我修改了三角形相交测试,但现在我看不到反射。一点也不。不知道我的“相机”是否指向错误。
-
更新,我的跟踪函数 100% 存在问题,因为如果我保持 for 循环与反弹,它会在 hitScene 中的 else 检查中达到 90%。
标签: javascript opengl-es glsl rendering webgl2