280 likes | 294 Views
Visibilidade. MO603/MC930. Visibilidade. Algoritmos básicos de visibilidade Algoritmo pintor Z-buffer Estilos de Shading Ray-casting. The visibility problem. What is the nearest surface seen at any point in the image? How would YOU solve this problem?. Removendo superfícies ocultas. B.
E N D
Visibilidade MO603/MC930
Visibilidade • Algoritmos básicos de visibilidade • Algoritmo pintor • Z-buffer • Estilos de Shading • Ray-casting
The visibility problem • What is the nearest surface seen at any point in the image? • How would YOU solve this problem?
Removendo superfícies ocultas • while (1) { • get_viewing_point_from_mouse_position(); • glClear(GL_COLOR_BUFFER_BIT); • draw_3d_object_B(); • draw_3d_object_A(); • }
Removendo superfícies ocultas • while (1) { • get_viewing_point_from_mouse_position(); • glClear(GL_COLOR_BUFFER_BIT); • draw_3d_object_A(); • draw_3d_object_B(); • }
Painter’s Algorithm • Sort objects by depth (Z) • Loop over objects in back-to-front order • Project to image • scan convert: image[x,y] = shade(x,y)
Sorting Objects by Depth Sorting Objects by Depth A A A B B B Z Zmin G G R1 R B B R2
Painter´s Algorithm • Strengths • Simplicity: draw objects one-at-a-time, scan convert each • Handles transparency well • Drawbacks • Sorting can be expensive (slower than linear in the number of objects) • Clumsy when ordering is cyclic, because of need to split • Interpenetrating polygons need to be split, too • Hard to sort non-polygonal objects • Sometimes no need to sort • If objects are arranged in a grid, e.g. triangles in a height field z(x,y), such as a triangulated terrain • Who uses it? • Postscript interpreters • OpenGL, if you don’t glEnable(GL_DEPTH_TEST);
Representando objetos por malhas triangulares • Divide objeto em faces triangulares • A junção de todas as faces forma a “casca” do objeto • Triangulo = estrutura (P1, P2, P3) • T1={P1,P2,P3}, T2={P2,P4,P3} • T3={P2, P5, P6}, T4={P6, P1, P2}, … • Objeto = T1, T2, T3, T4, …
Backface culling • Each polygon is either front-facing or back-facing • A polygon is backfacing if its normal points away from the viewer, • i.e. V•N >= 0 • When it works • If object is closed, back faces are never visible so no need to render them • Easy way to eliminate half your polygons • Can be used with both z-buffer and painter’s algorithms • If object is convex, backface culling is a complete visibility algorithm! • When it doesn’t work • If objects are not closed, back faces might be visible V N1 N2
Z-Buffer Algorithm • Initialization • loop over all x,y • zbuf[x,y] = infinity • Drawing steps • loop over all objects • scan convert object (loop over x,y) • if z(x,y) < zbuf[x,y] compute z of this object • at this pixel & test • zbuf[x,y] = z(x,y) update z-buffer • image[x,y] = shade(x,y) update image (typically RGB)
Z-Buffer Algorithm • Strengths • Simple, no sorting or splitting • Easy to mix polygons, spheres, other geometric primitives • Drawbacks • Can’t handle transparency well • Need good Z-buffer resolution or you get depth ordering artifacts • In OpenGL, this resolution is controlled by choice of clipping planes and number of bits for depth • Choose ratio of clipping plane depths (zfar/znear) to be as small as possible • Who uses it? • OpenGL, if you glEnable(GL_DEPTH_TEST);
Usando o buffer de profundidade • glutInitDisplayMode (GLUT_DEPTH | .... ); • glEnable(GL_DEPTH_TEST); • ... • while (1) { • glClear(GL_COLOR_BUFFER_BIT | • GL_DEPTH_BUFFER_BIT); • get_viewing_point_from_mouse_position(); • draw_3d_object_A(); • draw_3d_object_B(); • }
Ray Casting • A very flexible visibility algorithm • loop y • loop x • shoot ray from eye through pixel (x,y) into scene • intersect with all surfaces, find first one the ray hits • shade surface point to compute pixel (x,y)’s color
Comparing visibility algorithms • Painter’s: • Implementation: moderate to hard if sorting & splitting needed • Speed: fast if objects are pre-sorted, otherwise slow • Generality: sorting & splitting make it ill-suited for general 3-D rendering • Z-buffer: • Implementation: moderate, it can be implemented in hardware • Speed: fast, unless depth complexity is high • Generality: good but won’t do transparency • Ray Casting: • Implementation: easy, but hard to make it run fast • Speed: slow if many objects: cost is O((#pixels)´(#objects)) • Generality: excellent, can even do CSG, transparency, shadows
Really Hard Visibility Problems • Extremely high scene complexity • a building walkthrough (QUAKE)? • A fly-by of the Grand Canyon (or any outdoor scene!) • Z-buffering requires drawing EVERY triangle for each image • Not feasible in real time • Usually Z-buffering is combined with spatial data structures • BSP trees are common (similar concept to octrees) • For really complex scenes, visibility isn’t always enough • Objects WAY in the distance are too small to matter • Might as well approximate far-off objects with simpler primitives • This is called geometry simplification
Programa exemplo (esfera) • #include <GL/gl.h> • #include <GL/glu.h> • #include <GL/glut.h>
Programa exemplo (esfera) • void init(void) { • GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 }; • GLfloat mat_shininess[] = { 50.0 }; • GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 }; • glClearColor (0.0, 0.0, 0.0, 0.0); • glShadeModel (GL_SMOOTH); • glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); • glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); • glLightfv(GL_LIGHT0, GL_POSITION, light_position); • glEnable(GL_LIGHTING); • glEnable(GL_LIGHT0); • glEnable(GL_DEPTH_TEST); • }
Programa exemplo (esfera) • void display(void) • { • glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); • glutSolidSphere (1.0, 20, 16); • glFlush (); • }
Programa exemplo (esfera) • void reshape (int w, int h) • { • glViewport (0, 0, (GLsizei) w, (GLsizei) h); • glMatrixMode (GL_PROJECTION); • glLoadIdentity(); • if (w <= h) • glOrtho (-1.5, 1.5, -1.5*(GLfloat)h/(GLfloat)w, • 1.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0); • else • glOrtho (-1.5*(GLfloat)w/(GLfloat)h, • 1.5*(GLfloat)w/(GLfloat)h, -1.5, 1.5, -10.0, 10.0); • glMatrixMode(GL_MODELVIEW); • glLoadIdentity(); • }
Programa exemplo (esfera) • int main(int argc, char** argv) • { • glutInit(&argc, argv); • glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); • glutInitWindowSize (500, 500); • glutInitWindowPosition (100, 100); • glutCreateWindow (argv[0]); • init (); • glutDisplayFunc(display); • glutReshapeFunc(reshape); • glutMainLoop(); • return 0; • }
Comentários • Definir vetores normais para todos vértices: glutSolidSphere() faz isso. • Criar, posicionar e habilitar uma (ou mais) fontes de luz: glLightfv(), glEnable(), glLight*() • Ex: GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 }; • glLightfv(GL_LIGHT0, GL_POSITION, light_position); • default: GL_POSITION é (0, 0, 1, 0), eixo-Z negativo • Selecionar um modelo de iluminação: glLightModel*() • Definir propriedades materiais para os objetos na cena
Lembre-se • Voce pode usar valores defaults para alguns parâmetros, de iluminação; outros devem ser modificados • Não se esqueça de habilitar todas as luzes que pretende usar e também habilitar o cálculo de iluminação • Voce pode usar “display lists” para maximizar eficiência quando é necessário mudar as condições de iluminação
Computing Z for Z-buffering • How to compute Z at each point for z-buffering? • Can we interpolate Z? • Linear interpolation along edge, along span • Not quite. World space Z does not interpolate linearly in image space • But if we linearly interpolate image space Z, it works! • Perspective transforms planes to planes • Note that image space Z is a nonlinear function of world space Z