Example 5 : Texturing

来源:互联网 发布:淘宝 客服 代码 编辑:程序博客网 时间:2024/06/10 09:18

主要实现的功能就是UV贴图,与光照计算。


思路:


1. 一个图片的每一个pixel, 都随机采样n次,然后每一次采样就是相当于发出一条ray,来检测是否碰到物体。

for (s = 0; s < NUM_SAMPLES; s++){xl_samples[s] -= 0.5f;yl_samples[s] -= 0.5f;VectorCopy(cam.eye, start);VectorMA(start, cam.aperature*xl_samples[s], cam_r, start);VectorMA(start, cam.aperature*yl_samples[s], cam_u, start);x_samples[s] = cam.d*((((x_samples[s] + 0.5f + c) / ((float)IMAGE_WIDTH)))*(cam.right - cam.left) + cam.left);y_samples[s] = cam.d*((((y_samples[s] + 0.5f + r) / ((float)IMAGE_HEIGHT)))*(cam.top - cam.bottom) + cam.bottom);VectorCopy(cam.eye, end);VectorMA(end, cam.d, cam_f, end);VectorMA(end, x_samples[s], cam_r, end);VectorMA(end, y_samples[s], cam_u, end);VectorSub(end, start, dir);VectorNormalize(dir);if (shape_intersect_all(start, dir, t_samples[s], &hit)){VectorNegate(dir, eyedir);VectorMA(start, hit.t, dir, hitpos);shape_shade(hit.shape, hitpos, eyedir, t_samples[s], color);VectorAdd(total, color, total);}// backgroundelse{total[0] += 0.2f;total[1] += 0.2f;total[2] += 0.2f;}}


2. 如果碰到了物体,就进行计算hitpos上对应的uv值


// v = hitposvoid shape_shade(shape_t *s, vec3 v, vec3 eyedir, float time, vec3 color){typedef void (shadefunc)(shape_t*, vec3, vec3, float, vec3);static shadefunc *shadefuncs[] = { shape_shade_tri , shape_shade_sphere };shadefuncs[s->type](s, v, eyedir, time, color);}

// vert = hitposvoid shape_shade_tri(shape_t *s, vec3 vert, vec3 eyedir, float time, vec3 color){float u, v, w;float det,inv_det;vec3 edge1, edge2, tvec, pvec, qvec;vec3 v0, v1, v2, normal;vec2 tex;VectorMA(s->tri.verts[0], time, s->move_velocity, v0);VectorMA(s->tri.verts[1], time, s->move_velocity, v1);VectorMA(s->tri.verts[2], time, s->move_velocity, v2);/* find vectors for two edges sharing vert0 */VectorSub(v1, v0, edge1);VectorSub(v2, v0, edge2);CrossProduct(edge2, edge1, normal);VectorNormalize(normal);/* begin calculating determinant - also used to calculate U parameter */CrossProduct(normal, edge2, pvec);/* if determinant is near zero, ray lies in plane of triangle */det = DotProduct(edge1, pvec);inv_det = 1.0f / det;/* calculate distance from vert0 to ray origin */VectorSub(vert, v0, tvec);/* calculate U parameter and test bounds */u = DotProduct(tvec, pvec) * inv_det;/* prepare to test V parameter */CrossProduct(tvec, edge1, qvec);/* calculate V parameter and test bounds */v = DotProduct(normal, qvec) * inv_det;w = 1-u-v;// 上面的,都是公式,主要就是为了求出三角形重心坐标的那3个alfa, beta, gema,求出这3个东西之后,就可以// 求对应点的uv值。tex[0],tex[1], 保存的就是uvtex[0] = w*s->tri.uv[0][0] + u*s->tri.uv[1][0] + v*s->tri.uv[2][0];tex[1] = w*s->tri.uv[0][1] + u*s->tri.uv[1][1] + v*s->tri.uv[2][1];VectorMA(vert, 0.001f, normal, v0);// 光照shade(&s->shader, v0, v0, tex, normal, eyedir, time, color);}


3. 计算hitpos上的uv值,主要目的就是为了去png图片中计算对应的rgb值,作为物体的颜色。


void shade(shader_t *s, vec3 gp, vec3 p, vec2 t, vec3 norm, vec3 eyedir, float time, vec3 color){typedef int (shadefunc)(vec3, vec3, vec2, vec3, vec3, float, void*, vec3);static shadefunc *shadefuncs[]  = { (shadefunc*)shade_constant,(shadefunc*)shade_constant_lit,(shadefunc*)shade_marble,(shadefunc*)shade_texture };shadefuncs[s->shader_id](gp, p, t, norm, eyedir, time, &s->params, color);}


// t => uvvoid shade_texture(vec3 gp, vec3 p, vec2 t, vec3 norm, vec3 eyedir, float time, shader_texture_t *param, vec3 color){int r1,r2, c1,c2;vec2 u, s;vec3 int1[2];shader_constant_lit_t light_params;texture_t *tex = &textures[param->texture];// 计算tex->w * uu[0] = t[0] - (float)floor(t[0]);u[0] *= tex->w;u[0] -= 0.5f;// 下面的都是公式: P98, use to make pixel smoother if (u[0] < 0)c1 = c2 = 0;else{c1 = (int)u[0];c2 = c1+1;if (c2 == tex->w)c2 = c1;}// s[0] 就是u[0] - (int)u[0] = u's[0] = u[0] - c1;// 3 * s[0]^2 - 2 * s[0]^3s[0] = s[0]*s[0]*(3-2*s[0]);u[1] = t[1] - ((float)floor(t[1]));u[1] = 1-u[1];u[1] *= tex->h;u[1] -= 0.5f;if (u[1] < 0)r1 = r2 = 0;else{r1 = (int)u[1];r2 = r1+1;if (r2 == tex->h)r2 = r1;}s[1] = u[1] - r1;s[1] = s[1]*s[1]*(3-2*s[1]);// 双线性插值,P98, 求出texutre的colorint1[0][0] = (1-s[0])*tex->data[(tex->w*r1 + c1)*3 + 0] + (s[0])*tex->data[(tex->w*r1 + c2)*3 + 0];int1[0][1] = (1-s[0])*tex->data[(tex->w*r1 + c1)*3 + 1] + (s[0])*tex->data[(tex->w*r1 + c2)*3 + 1];int1[0][2] = (1-s[0])*tex->data[(tex->w*r1 + c1)*3 + 2] + (s[0])*tex->data[(tex->w*r1 + c2)*3 + 2];int1[1][0] = (1-s[0])*tex->data[(tex->w*r2 + c1)*3 + 0] + (s[0])*tex->data[(tex->w*r2 + c2)*3 + 0];int1[1][1] = (1-s[0])*tex->data[(tex->w*r2 + c1)*3 + 1] + (s[0])*tex->data[(tex->w*r2 + c2)*3 + 1];int1[1][2] = (1-s[0])*tex->data[(tex->w*r2 + c1)*3 + 2] + (s[0])*tex->data[(tex->w*r2 + c2)*3 + 2];VectorScale(int1[0], 1.0f/255.0f, int1[0]);VectorScale(int1[1], 1.0f/255.0f, int1[1]);light_params.diffuse[0] = (1-s[1])*int1[0][0] + (s[1])*int1[1][0];light_params.diffuse[1] = (1-s[1])*int1[0][1] + (s[1])*int1[1][1];light_params.diffuse[2] = (1-s[1])*int1[0][2] + (s[1])*int1[1][2];light_params.specexp = param->specexp;VectorCopy(param->ambient, light_params.ambient);VectorCopy(param->specular, light_params.specular);// 计算光照shade_constant_lit(gp, p, t, norm, eyedir, time,  &light_params, color);}

4. 如果确定了物体身上的diffuse color的话,下一步就是进行光照的计算,主要几是看光源对物体的颜色的影响


void shade_constant_lit(vec3 gp, vec3 p, vec2 t, vec3 norm, vec3 eyedir, float time, shader_constant_lit_t *param, vec3 color){int i;float dist, intensity;vec3 dir, half;hit_t hit;vec3 diffuse, specular, ambient;VectorSet(diffuse,  0,0,0);VectorSet(specular, 0,0,0);VectorSet(ambient,  0,0,0);for (i=0; i<NUM_LIGHTS; i++){VectorSub(lights[i].pos, gp, dir);dist = VectorNormalize(dir);// 如果这个hitPoint 与light之间是没有其他shape的话,就可以计算光照// diffuse, specular, ambient,主要是计算光源对物体的颜色影响if (!shape_intersect_all(gp, dir, time, &hit) || (hit.t > dist)){// diffuseintensity = DotProduct(norm, dir) / (float)sqrt(dist);if (intensity > 0)VectorMA(diffuse, intensity, lights[i].diffuse, diffuse);// specularVectorAdd(dir, eyedir, half);VectorNormalize(half);intensity = DotProduct(norm, half);if (intensity > 0)VectorMA(specular, (float)pow(intensity, param->specexp), lights[i].specular, specular);}// ambientVectorAdd(ambient, lights[i].ambient, ambient);}color[0] = param->ambient[0] * ambient[0];color[1] = param->ambient[1] * ambient[1];color[2] = param->ambient[2] * ambient[2];color[0] += param->diffuse[0] * diffuse[0];color[1] += param->diffuse[1] * diffuse[1];color[2] += param->diffuse[2] * diffuse[2];color[0] += param->specular[0] * specular[0];color[1] += param->specular[1] * specular[1];color[2] += param->specular[2] * specular[2];}


 最终,得到的color, 就是物体本身的颜色与光照的颜色。






0 0
原创粉丝点击