diff options
author | Ton Roosendaal <ton@blender.org> | 2006-08-12 15:27:00 +0400 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2006-08-12 15:27:00 +0400 |
commit | e47137ff42ac241fe6c68d4df3466b030315edee (patch) | |
tree | c19568b96be11e36d0e548e5bcae92fa9f37be83 /source | |
parent | 3be0a5ad708312552ad3abd65184670df8f2f22d (diff) |
Bugreport #4787 mentioned subpixel render issues, especially for small
images (like used for rendering icons).
When working during Orange on new render pipeline, I've left this topic
alone for a while... subpixel precision testing is very time consuming and
needs concentration for a while. :)
This commit brings back precision as it was for 2.41. Below a short
explanation of the solved issues.
- the window matrix for rendering is kept constant during all OSA passes,
this to ensure clipping happens for each pass identically.
- a subpixel offset is only applied on filling in the z-buffer
- this offset is inverse corrected for shadepixel code, only on 2 places
Another nasty issue is that for filtered rendering (gauss etc), the tiles
(or entire image) is temporally increased 2 pixel in size. This caused a
'dark' (or sky color) edge on the rendering. During Orange that was solved
with a hardcoded clipping offset value, which only corrected for larger
pictures (like > 500 pixels in size).
Now this clipping offset is correctly calculated, based on render size.
Last issue: the view border in 3d window was calculated using integers,
giving small errors in display too. Now it uses float, so visually the
view border is more close to what a render shows.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/include/BSE_drawview.h | 4 | ||||
-rw-r--r-- | source/blender/render/intern/include/render_types.h | 2 | ||||
-rw-r--r-- | source/blender/render/intern/source/initrender.c | 23 | ||||
-rw-r--r-- | source/blender/render/intern/source/rendercore.c | 12 | ||||
-rw-r--r-- | source/blender/render/intern/source/zbuf.c | 30 | ||||
-rw-r--r-- | source/blender/src/drawview.c | 6 | ||||
-rw-r--r-- | source/blender/src/edit.c | 2 | ||||
-rw-r--r-- | source/blender/src/editview.c | 10 |
8 files changed, 49 insertions, 40 deletions
diff --git a/source/blender/include/BSE_drawview.h b/source/blender/include/BSE_drawview.h index 70793f88ce2..041381bbb1a 100644 --- a/source/blender/include/BSE_drawview.h +++ b/source/blender/include/BSE_drawview.h @@ -35,7 +35,7 @@ struct Object; struct BGpic; -struct rcti; +struct rctf; struct ScrArea; struct ImBuf; @@ -61,7 +61,7 @@ void drawview3dspace(struct ScrArea *sa, void *spacedata); void drawview3d_render(struct View3D *v3d, int winx, int winy); int update_time(void); -void calc_viewborder(struct View3D *v3d, struct rcti *viewborder_r); +void calc_viewborder(struct View3D *v3d, struct rctf *viewborder_r); void view3d_set_1_to_1_viewborder(struct View3D *v3d); int view3d_test_clipping(struct View3D *v3d, float *vec); diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index 8f0a85bd177..25ecf42b636 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -108,6 +108,7 @@ struct Render rcti disprect; /* part within winx winy */ rctf viewplane; /* mapped on winx winy */ float viewdx, viewdy; /* size of 1 pixel */ + float clipcrop; /* 2 pixel boundary to prevent clip when filter used */ /* final picture width and height (within disprect) */ int rectx, recty; @@ -120,7 +121,6 @@ struct Render /* values for viewing */ float lens, ycor, viewfac; - float bluroffsx, bluroffsy; float panophi, panosi, panoco, panodxp, panodxv; /* Matrices */ diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c index 8b8a413762f..30beae1c467 100644 --- a/source/blender/render/intern/source/initrender.c +++ b/source/blender/render/intern/source/initrender.c @@ -456,8 +456,6 @@ void RE_SetCamera(Render *re, Object *camera) rctf viewplane; float pixsize, clipsta, clipend; float lens; - float xd, yd; - int blursample= 0; /* make new call for that */ /* question mark */ re->ycor= ( (float)re->r.yasp)/( (float)re->r.xasp); @@ -541,18 +539,12 @@ void RE_SetCamera(Render *re, Object *camera) viewplane.ymax+= .5*re->ycor; } } - - xd= yd= 0.0; - if(blursample != -1 && re->osa != 0 ) { - re->bluroffsx= xd= re->jit[blursample % re->osa][0]; - re->bluroffsy= yd= re->ycor*re->jit[blursample % re->osa][1]; - } - else re->bluroffsx=re->bluroffsy= 0.0f; - - viewplane.xmin= pixsize*(viewplane.xmin+xd); - viewplane.xmax= pixsize*(viewplane.xmax+xd); - viewplane.ymin= pixsize*(viewplane.ymin+yd); - viewplane.ymax= pixsize*(viewplane.ymax+yd); + /* the window matrix is used for clipping, and not changed during OSA steps */ + /* using an offset of +0.5 here would give clip errors on edges */ + viewplane.xmin= pixsize*(viewplane.xmin); + viewplane.xmax= pixsize*(viewplane.xmax); + viewplane.ymin= pixsize*(viewplane.ymin); + viewplane.ymax= pixsize*(viewplane.ymax); re->viewdx= pixsize; re->viewdy= re->ycor*pixsize; @@ -562,7 +554,8 @@ void RE_SetCamera(Render *re, Object *camera) else RE_SetWindow(re, &viewplane, clipsta, clipend); - //printmatrix4("win", re->winmat); + /* we clip faces with a minimum of 2 pixel boundary outside of image border. see zbuf.c */ + re->clipcrop= 1.0f + 2.0f/(float)(re->winx>re->winy?re->winy:re->winx); } diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index c78ca424d91..2ae9ccc8527 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -2453,8 +2453,8 @@ void *shadepixel(ShadePixelInfo *shpi, float x, float y, int z, volatile int fac float fx= 2.0/(R.winx*R.winmat[0][0]); float fy= 2.0/(R.winy*R.winmat[1][1]); - shi.co[0]= (0.5 + x - 0.5*R.winx)*fx - R.winmat[3][0]/R.winmat[0][0]; - shi.co[1]= (0.5 + y - 0.5*R.winy)*fy - R.winmat[3][1]/R.winmat[1][1]; + shi.co[0]= (x - 0.5*R.winx)*fx - R.winmat[3][0]/R.winmat[0][0]; + shi.co[1]= (y - 0.5*R.winy)*fy - R.winmat[3][1]/R.winmat[1][1]; /* using a*x + b*y + c*z = d equation, (a b c) is normal */ if(shi.facenor[2]!=0.0f) @@ -2675,8 +2675,8 @@ void *shadepixel(ShadePixelInfo *shpi, float x, float y, int z, volatile int fac float fx= 2.0/(R.rectx*R.winmat[0][0]); float fy= 2.0/(R.recty*R.winmat[1][1]); - shi.co[0]= (0.5 + x - 0.5*R.rectx)*fx - R.winmat[3][0]/R.winmat[0][0]; - shi.co[1]= (0.5 + y - 0.5*R.recty)*fy - R.winmat[3][1]/R.winmat[1][1]; + shi.co[0]= (x - 0.5*R.rectx)*fx - R.winmat[3][0]/R.winmat[0][0]; + shi.co[1]= (y - 0.5*R.recty)*fy - R.winmat[3][1]/R.winmat[1][1]; } calc_view_vector(shi.view, x, y); @@ -2697,6 +2697,10 @@ static void shadepixel_sky(ShadePixelInfo *shpi, float x, float y, int z, int fa VlakRen *vlr; float collector[4], rco[3]; + /* correction back for zbuffer filling in */ + x+= 0.5f; + y+= 0.5f; + vlr= shadepixel(shpi, x, y, z, facenr, mask, rco); if(shpi->shr.combined[3] != 1.0) { diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c index 7cd21836469..3d685464574 100644 --- a/source/blender/render/intern/source/zbuf.c +++ b/source/blender/render/intern/source/zbuf.c @@ -1307,8 +1307,8 @@ static void clippyra(float *labda, float *v1, float *v2, int *b2, int *b3, int a v13= v1[3]; } else { - dw= 1.005f*(v2[3]-v1[3]); - v13= 1.005f*v1[3]; + dw= R.clipcrop*(v2[3]-v1[3]); + v13= R.clipcrop*v1[3]; } /* according the original article by Liang&Barsky, for clipping of * homogenous coordinates with viewplane, the value of "0" is used instead of "-w" . @@ -1527,7 +1527,6 @@ void zbufclip(ZSpan *zspan, int zvlnr, float *f1, float *f2, float *f3, int c1, hoco_to_zco(zspan, vez, f1); hoco_to_zco(zspan, vez+4, f2); hoco_to_zco(zspan, vez+8, f3); - zspan->zbuffunc(zspan, zvlnr, vez,vez+4,vez+8, NULL); } @@ -1628,6 +1627,7 @@ void zbuffer_solid(RenderPart *pa, unsigned int lay, short layflag) /* needed for transform from hoco to zbuffer co */ zspan.zmulx= ((float)R.winx)/2.0; zspan.zmuly= ((float)R.winy)/2.0; + if(R.osa) { zspan.zofsx= -pa->disprect.xmin - R.jit[pa->sample][0]; zspan.zofsy= -pa->disprect.ymin - R.jit[pa->sample][1]; @@ -1640,6 +1640,9 @@ void zbuffer_solid(RenderPart *pa, unsigned int lay, short layflag) zspan.zofsx= -pa->disprect.xmin; zspan.zofsy= -pa->disprect.ymin; } + /* to centre the sample position */ + zspan.zofsx -= 0.5f; + zspan.zofsy -= 0.5f; /* the buffers */ zspan.rectz= pa->rectz; @@ -1752,8 +1755,8 @@ void RE_zbufferall_radio(struct RadView *vw, RNode **rg_elem, int rg_totelem, Re zbuf_alloc_span(&zspan, vw->rectx, vw->recty); zspan.zmulx= ((float)vw->rectx)/2.0; zspan.zmuly= ((float)vw->recty)/2.0; - zspan.zofsx= 0; - zspan.zofsy= 0; + zspan.zofsx= -0.5f; + zspan.zofsy= -0.5f; /* the buffers */ zspan.rectz= vw->rectz; @@ -2409,8 +2412,6 @@ static void zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, u /* needed for transform from hoco to zbuffer co */ zspan.zmulx= ((float)R.winx)/2.0; zspan.zmuly= ((float)R.winy)/2.0; - zspan.zofsx= -pa->disprect.xmin; - zspan.zofsy= -pa->disprect.ymin; /* the buffers */ zspan.arectz= MEM_mallocT(sizeof(int)*pa->rectx*pa->recty, "Arectz"); @@ -2430,13 +2431,20 @@ static void zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, u zspan.mask= 1<<zsample; if(R.osa) { - zspan.zofsx= -pa->disprect.xmin-R.jit[zsample][0]; - zspan.zofsy= -pa->disprect.ymin-R.jit[zsample][1]; + zspan.zofsx= -pa->disprect.xmin - R.jit[zsample][0]; + zspan.zofsy= -pa->disprect.ymin - R.jit[zsample][1]; } else if(R.i.curblur) { zspan.zofsx= -pa->disprect.xmin - R.jit[R.i.curblur-1][0]; zspan.zofsy= -pa->disprect.ymin - R.jit[R.i.curblur-1][1]; } + else { + zspan.zofsx= -pa->disprect.xmin; + zspan.zofsy= -pa->disprect.ymin; + } + /* to centre the sample position */ + zspan.zofsx -= 0.5f; + zspan.zofsy -= 0.5f; for(v=0; v<R.totvlak; v++) { if((v & 255)==0) @@ -2605,6 +2613,10 @@ static void shadetrapixel(ShadePixelInfo *shpi, float x, float y, int z, int fac printf("error in shadetrapixel nr: %d\n", (facenr & RE_QUAD_MASK)); return; } + /* correction back for zbuffer filling in */ + x+= 0.5f; + y+= 0.5f; + if(R.osa) { VlakRen *vlr= RE_findOrAddVlak(&R, (facenr-1) & RE_QUAD_MASK); float accumcol[4]={0,0,0,0}, tot=0.0; diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c index e7d9bfdbbd1..dc7b0d0f2d0 100644 --- a/source/blender/src/drawview.c +++ b/source/blender/src/drawview.c @@ -393,7 +393,7 @@ static void draw_bgpic(void) } if(G.vd->persp==2) { - rcti vb; + rctf vb; calc_viewborder(G.vd, &vb); @@ -864,7 +864,7 @@ static void view3d_get_viewborder_size(View3D *v3d, float size_r[2]) } } -void calc_viewborder(struct View3D *v3d, rcti *viewborder_r) +void calc_viewborder(struct View3D *v3d, rctf *viewborder_r) { float zoomfac, size[2]; float dx= 0.0f, dy= 0.0f; @@ -964,7 +964,7 @@ static void drawviewborder(void) float fac, a; float x1, x2, y1, y2; float x3, y3, x4, y4; - rcti viewborder; + rctf viewborder; Camera *ca= NULL; if(G.vd->camera==NULL) diff --git a/source/blender/src/edit.c b/source/blender/src/edit.c index c48539ba736..bad89da633f 100644 --- a/source/blender/src/edit.c +++ b/source/blender/src/edit.c @@ -247,7 +247,7 @@ int get_border(rcti *rect, short flag) BMF_DrawString(G.fonts, str); } else if(G.vd->persp==2) { - rcti vb; + rctf vb; calc_viewborder(G.vd, &vb); diff --git a/source/blender/src/editview.c b/source/blender/src/editview.c index 76d857826b6..001105c43a9 100644 --- a/source/blender/src/editview.c +++ b/source/blender/src/editview.c @@ -1980,14 +1980,14 @@ void set_render_border(void) val= get_border(&rect, 3); if(val) { - rcti vb; + rctf vb; calc_viewborder(G.vd, &vb); - G.scene->r.border.xmin= (float) (rect.xmin-vb.xmin)/(vb.xmax-vb.xmin); - G.scene->r.border.ymin= (float) (rect.ymin-vb.ymin)/(vb.ymax-vb.ymin); - G.scene->r.border.xmax= (float) (rect.xmax-vb.xmin)/(vb.xmax-vb.xmin); - G.scene->r.border.ymax= (float) (rect.ymax-vb.ymin)/(vb.ymax-vb.ymin); + G.scene->r.border.xmin= ((float)rect.xmin-vb.xmin)/(vb.xmax-vb.xmin); + G.scene->r.border.ymin= ((float)rect.ymin-vb.ymin)/(vb.ymax-vb.ymin); + G.scene->r.border.xmax= ((float)rect.xmax-vb.xmin)/(vb.xmax-vb.xmin); + G.scene->r.border.ymax= ((float)rect.ymax-vb.ymin)/(vb.ymax-vb.ymin); CLAMP(G.scene->r.border.xmin, 0.0, 1.0); CLAMP(G.scene->r.border.ymin, 0.0, 1.0); |