Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2012-09-22 08:57:55 +0400
committerCampbell Barton <ideasman42@gmail.com>2012-09-22 08:57:55 +0400
commitb1ef5703d69b2c3ce158da46185967af4adc36fa (patch)
tree39a09084cd2cc7b19ca9547295ffe15bf864049c /source/blender/render/intern/source/shadeinput.c
parent1a1e37f4a8e4d7fc74a7e2ce057b8a9782216340 (diff)
add a UV Project material option so UV's are calculated taking into account perspective matrix - previously this gave artifacts with lower poly meshes.
Diffstat (limited to 'source/blender/render/intern/source/shadeinput.c')
-rw-r--r--source/blender/render/intern/source/shadeinput.c127
1 files changed, 95 insertions, 32 deletions
diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c
index 7ef72b7bb79..35ab06cc564 100644
--- a/source/blender/render/intern/source/shadeinput.c
+++ b/source/blender/render/intern/source/shadeinput.c
@@ -1120,50 +1120,113 @@ void shade_input_set_shade_texco(ShadeInput *shi)
for (i = 0; (tface = RE_vlakren_get_tface(obr, vlr, i, &name, 0)); i++) {
ShadeInputUV *suv = &shi->uv[i];
- float *uv1, *uv2, *uv3;
+ const float *uv1 = tface->uv[j1];
+ const float *uv2 = tface->uv[j2];
+ const float *uv3 = tface->uv[j3];
shi->totuv++;
suv->name = name;
-
- uv1 = tface->uv[j1];
- uv2 = tface->uv[j2];
- uv3 = tface->uv[j3];
- suv->uv[0] = -1.0f + 2.0f * (l * uv3[0] - u * uv1[0] - v * uv2[0]);
- suv->uv[1] = -1.0f + 2.0f * (l * uv3[1] - u * uv1[1] - v * uv2[1]);
- suv->uv[2] = 0.0f; /* texture.c assumes there are 3 coords */
+ if ((shi->mat->mapflag & MA_MAPFLAG_UVPROJECT) && (shi->depth == 0)) {
+ float x = shi->xs;
+ float y = shi->ys;
+
+ float s1[2] = {-1.0f + 2.0f * uv1[0], -1.0f + 2.0f * uv1[1]};
+ float s2[2] = {-1.0f + 2.0f * uv2[0], -1.0f + 2.0f * uv2[1]};
+ float s3[2] = {-1.0f + 2.0f * uv3[0], -1.0f + 2.0f * uv3[1]};
+
+
+ float obwinmat[4][4], winmat[4][4], ho1[4], ho2[4], ho3[4];
+ float Zmulx, Zmuly;
+ float hox, hoy, l, dl, u, v;
+ float s00, s01, s10, s11, detsh;
+
+ /* old globals, localized now */
+ Zmulx = ((float)R.winx) / 2.0f;
+ Zmuly = ((float)R.winy) / 2.0f;
+
+ zbuf_make_winmat(&R, winmat);
+ if (shi->obi->flag & R_TRANSFORMED)
+ mult_m4_m4m4(obwinmat, winmat, obi->mat);
+ else
+ copy_m4_m4(obwinmat, winmat);
+
+ zbuf_render_project(obwinmat, v1->co, ho1);
+ zbuf_render_project(obwinmat, v2->co, ho2);
+ zbuf_render_project(obwinmat, v3->co, ho3);
+
+ s00 = ho3[0] / ho3[3] - ho1[0] / ho1[3];
+ s01 = ho3[1] / ho3[3] - ho1[1] / ho1[3];
+ s10 = ho3[0] / ho3[3] - ho2[0] / ho2[3];
+ s11 = ho3[1] / ho3[3] - ho2[1] / ho2[3];
+
+ detsh = s00 * s11 - s10 * s01;
+ detsh = (detsh != 0.0f) ? 1.0f / detsh : 0.0f;
+ s00 *= detsh; s01 *= detsh;
+ s10 *= detsh; s11 *= detsh;
+
+ /* recalc u and v again */
+ hox = x / Zmulx - 1.0f;
+ hoy = y / Zmuly - 1.0f;
+ u = (hox - ho3[0] / ho3[3]) * s11 - (hoy - ho3[1] / ho3[3]) * s10;
+ v = (hoy - ho3[1] / ho3[3]) * s00 - (hox - ho3[0] / ho3[3]) * s01;
+ l = 1.0f + u + v;
+
+ suv->uv[0] = l * s3[0] - u * s1[0] - v * s2[0];
+ suv->uv[1] = l * s3[1] - u * s1[1] - v * s2[1];
+ suv->uv[2] = 0.0f;
- if (shi->osatex) {
- float duv[2];
-
- dl = shi->dx_u + shi->dx_v;
- duv[0] = shi->dx_u;
- duv[1] = shi->dx_v;
+ if (shi->osatex) {
+ float dxuv[2], dyuv[2];
+ dxuv[0] = s11 / Zmulx;
+ dxuv[1] = -s01 / Zmulx;
+ dyuv[0] = -s10 / Zmuly;
+ dyuv[1] = s00 / Zmuly;
+
+ dl = dxuv[0] + dxuv[1];
+ suv->dxuv[0] = dl * s3[0] - dxuv[0] * s1[0] - dxuv[1] * s2[0];
+ suv->dxuv[1] = dl * s3[1] - dxuv[0] * s1[1] - dxuv[1] * s2[1];
+ dl = dyuv[0] + dyuv[1];
+ suv->dyuv[0] = dl * s3[0] - dyuv[0] * s1[0] - dyuv[1] * s2[0];
+ suv->dyuv[1] = dl * s3[1] - dyuv[0] * s1[1] - dyuv[1] * s2[1];
+ }
+ }
+ else {
- suv->dxuv[0] = 2.0f * (dl * uv3[0] - duv[0] * uv1[0] - duv[1] * uv2[0]);
- suv->dxuv[1] = 2.0f * (dl * uv3[1] - duv[0] * uv1[1] - duv[1] * uv2[1]);
+ suv->uv[0] = -1.0f + 2.0f * (l * uv3[0] - u * uv1[0] - v * uv2[0]);
+ suv->uv[1] = -1.0f + 2.0f * (l * uv3[1] - u * uv1[1] - v * uv2[1]);
+ suv->uv[2] = 0.0f; /* texture.c assumes there are 3 coords */
- dl = shi->dy_u + shi->dy_v;
- duv[0] = shi->dy_u;
- duv[1] = shi->dy_v;
+ if (shi->osatex) {
+ float duv[2];
- suv->dyuv[0] = 2.0f * (dl * uv3[0] - duv[0] * uv1[0] - duv[1] * uv2[0]);
- suv->dyuv[1] = 2.0f * (dl * uv3[1] - duv[0] * uv1[1] - duv[1] * uv2[1]);
- }
+ dl = shi->dx_u + shi->dx_v;
+ duv[0] = shi->dx_u;
+ duv[1] = shi->dx_v;
- if ((mode & MA_FACETEXTURE) && i == obr->actmtface) {
- if ((mode & (MA_VERTEXCOL | MA_VERTEXCOLP)) == 0) {
- shi->vcol[0] = 1.0f;
- shi->vcol[1] = 1.0f;
- shi->vcol[2] = 1.0f;
- shi->vcol[3] = 1.0f;
+ suv->dxuv[0] = 2.0f * (dl * uv3[0] - duv[0] * uv1[0] - duv[1] * uv2[0]);
+ suv->dxuv[1] = 2.0f * (dl * uv3[1] - duv[0] * uv1[1] - duv[1] * uv2[1]);
+
+ dl = shi->dy_u + shi->dy_v;
+ duv[0] = shi->dy_u;
+ duv[1] = shi->dy_v;
+
+ suv->dyuv[0] = 2.0f * (dl * uv3[0] - duv[0] * uv1[0] - duv[1] * uv2[0]);
+ suv->dyuv[1] = 2.0f * (dl * uv3[1] - duv[0] * uv1[1] - duv[1] * uv2[1]);
}
- if (tface->tpage) {
- render_realtime_texture(shi, tface->tpage);
+
+ if ((mode & MA_FACETEXTURE) && i == obr->actmtface) {
+ if ((mode & (MA_VERTEXCOL | MA_VERTEXCOLP)) == 0) {
+ shi->vcol[0] = 1.0f;
+ shi->vcol[1] = 1.0f;
+ shi->vcol[2] = 1.0f;
+ shi->vcol[3] = 1.0f;
+ }
+ if (tface->tpage) {
+ render_realtime_texture(shi, tface->tpage);
+ }
}
}
-
-
}
shi->dupliuv[0] = -1.0f + 2.0f * obi->dupliuv[0];