[comp.sys.sgi] Z-buffering Problems...

zyda@NPS-CS.ARPA (michael zyda) (04/22/88)

IRIS 4D/70G Z-Buffering Problems...

  One of my students is having some problems with the z-buffering
on the IRIS-4D. He gave me the following letter to post on info-iris.
Any similar experience or solutions would be greatly appreciated...

  "I had some unexpected and unwanted results from using Z-buffering
on the IRIS 4-D. I am modeling terrain from a digital database of 
elevation data. To cut down the number of polygons drawn, I start 
with a big blue polygon at 0 elevation, "ocean", and only draw 
polygons that have elevations > 0. 

  Problem: At the intersection of the sea and land you cannot 
rely on the Z-buffer to always draw the land over the water 
or even to consistently draw it the same. This is with near and 
far clipping planes set to 100yds and 120000yds respectively.

  I believe this problem is due to the resolution of the Z-buffer.
I can get an acceptable picture if I draw sea level at -10, close, to 
-100, far, and set the far clipping plane to 1200000, 10 times the area 
I'm drawing. This effectively decreases the resolution and wastes 90% 
of the Z-buffer resolution. With this solution, the coastline, drawn 
at a distance, is still erratic. By lowering the sea and increasing the 
area that will be mapped to a certain z value, I insure that land 
will be drawn over water in a consistent manner. 
  
  This solution is not very acceptable. Does anyone out there
have similar experiences?"

   Frank Harris
   fharris@nps-cs.arpa


Responses can be sent through zyda@nps-cs.arpa

glennrp@BRL.ARPA (Glenn Randers-Pehrson, WMB) (04/22/88)

 > From: zyda@NPS-CS.ARPA (michael zyda)
 > Subject: Z-buffering Problems...
 > IRIS 4D/70G Z-Buffering Problems...
 > 
 >   Problem: At the intersection of the sea and land you cannot 
 > rely on the Z-buffer to always draw the land over the water 
 > or even to consistently draw it the same.
 >   
 >   This solution is not very acceptable. Does anyone out there
 > have similar experiences?"
 > 

	Yes.  On a 2500T, 3130, and 3030, I attempted to do a
hidden-line wireframe by drawing the filled polygons in a background color
and then drawing unfilled polygons.  It did not work very well.  I
complained to SGI and was told it was due to the resolution of the
geometry engine calculations.  I think the exact quote was that "It
works as designed". [i.e. not necessarily as specified in the manual].

Here's a copy of my e-mail to SGI:

Glenn Randers-Pehrson <glennrp@brl.arpa>
Date:     Thu, 3 Dec 87 12:21:54 EST
From:     Glenn Randers-Pehrson (WMB)  <glennrp@BRL.ARPA>
To:       dave@sgi.com
Subject:  polly()

	Re: HOTLINE log 1824, 3 Dec 87

        program pollytest
c       demonstrates that poly() does not outline polygons properly
c       in conjuntion with polf() in z-buffer mode.  Tests polly()
c       by Glenn Randers-Pehrson, which attempts to do this properly.
        dimension square(3,4)
        integer near,far
        character*1 key
        data near,far/x'c000',x'3fff'/
      call ginit
      call greset
      call cursof
        call setdep(near,far)
        call ortho (0., 1.0, 0.0, 1.0, 1.0,-1.0)
        call zbuffe(.true.)
        call color(0)
        call clear
        do 200 mode=0,1
        call zclear
        kol=1
        do 100 k=1,2
        x=.025*k + .5*mode
        y=.025*k +  .1
        z=k-1.5 + x*.01
        square(1,1)=x
        square(2,1)=y
        square(3,1)=z+.01
        square(1,2)=x+.3
        square(2,2)=y
        square(3,2)=z+.01
        square(1,3)=x+.3
        square(2,3)=y+.3
        square(3,3)=z+.02
        square(1,4)=x
        square(2,4)=y+.3
        square(3,4)=z
        call color(kol)
        call polf(4,square)
        call color(3)
        call cmov2(x,.5)
        if(mode.eq.1)then
          if(k.eq.1)call charst('polly()',7)
          call color(2)
          call polly(4,square)
        else
          if(k.eq.1)call charst('poly()',6)
          call color(2)
          call poly(4,square)
        endif
        kol=4
 100    continue
 200    continue
 300    continue
        read(*,'(a1)')key
        call fhalt(1)
        end
      subroutine polly(n,xyz)
c     FORTRAN version of poly() that uses zbuffer consistently
c     with polf(), for use in making outlined polygons
c      by Glenn Randers-Pehrson <glennrp@brl.arpa>
c         U.S. Army Ballistic Research Laboratory
c         Aberdeen Proving Ground, MD 21005-5066
      dimension xyz(3,n)
      dimension temp(3,2)
      do 10 j=1,3
        temp(j,1)=xyz(j,n)
   10 continue
      do 40 i=1,n
        do 20 j=1,3
          temp(j,2)=xyz(j,i)
   20   continue
        call polf(2,temp)
        do 30 j=1,3
          temp(j,1)=temp(j,2)
   30   continue
   40 continue
      return
      end

glennrp@BRL.ARPA (Glenn Randers-Pehrson, WMB) (04/22/88)

I meant to include this in my previous message:

Date:     Fri, 4 Dec 87 10:35:57 EST
From:     Glenn Randers-Pehrson (WMB)  <glennrp@BRL.ARPA>
To:       dave@sgi.com
Subject:  zbuffer and polygons

  Re: log 1824, 3 Dec 87.
Dave,
 I have done some more testing with the program I sent you
yesterday and find that in general it does not do much better than
the regular poly() routine (It gives the "lumpy, gloppy" edge that
you described on the phone), no doubt due to the floating point
differences you mentioned.  Case closed, I guess.
...Glenn Randers-Pehrson

rgs@siesta.megatek.uucp (Rusty Sanders) (04/23/88)

From article <8804211723.AA25090@nps-cs.arpa>, by zyda@NPS-CS.ARPA (michael zyda):
> IRIS 4D/70G Z-Buffering Problems...
> 
>   One of my students is having some problems with the z-buffering
> on the IRIS-4D.
[...]
> 
>   Problem: At the intersection of the sea and land you cannot 
> rely on the Z-buffer to always draw the land over the water 
> or even to consistently draw it the same. This is with near and 
> far clipping planes set to 100yds and 120000yds respectively.

The Z-buffer on the 4D is 24 bits deep, which would imply that the resolution
would be 1 part in 2^24 (1 part in 16777216). Your model (if accurate to the
.1 yard level) requires only one part in 1200000, which is about 2^20.195. One
would think that this would be easy to represent.

Unfortunately, it just ain't so. While there may be 24 bits to store the data,
nowhere near that many bits are accurate. The first bit of accuracy is obvious,
IEEE only has 23 bits of mantissa. Feeding the pipe in double precision may
help a little bit there, but I doubt it. SGI does it's math in the pipe in
some single precision form (not IEEE). Chances are it's only 23 bits of
mantissa in any case. Additionally, each math operation adds in a bit more
inaccuracy. By the time you've done a few rotations and translates you've
done several math operations. After all those you have to finally pass the
vector through the 4x4 to generate a screen space vector. After all that
math you probably only have 19 bits of precision, maybe 20 if you're really
being careful. That means somewhere between 2^19 (1 part in 524288) and 2^20
(1 part in 1048578) precision in the z buffer.

This is clearly not enough for your model (even if you're only modeling on
one tenth yards, smaller levels would be harder still). Something you can
try is to clean up your transformations (as an experiment). Do all the matrix
calculations in the CPU using double precision. Then just do a loadmatrix at
the end to set up the final viewing matrix. This would mean you can't use
any of those nice ortho, lookat, polarview, translate, scale, rotate, multmat,
or similar calls. Lookup what they do in the appendix to the reference manual
and do that matrix math in the host. All this work will probably buy you
2 bits of precision, giving you about 2^21 (1 part in 2097152). That would be
sufficient. It won't be as fast that way, and you won't be able to put
display manipulations in your display list (if you're using one). But it
should work.

Note that my imprecision calculations are not very precise themselves. And
it is really affected by just how many display manipulations you do. You're
mileage may very by quite a bit, and you could be as low as only 17 or 18
bits of precision by the time you get to the screen (in a really bad case).
All of this is mathematical conjecture on my part, having not worked with
a 24 bit Z buffer before. I would like to hear back if you can verify my
thoughts on this, however.

Rusty Sanders, Megatek Corp. --> rgs@megatek or...
         ...ucsd!
..hplabs!hp-sdd!megatek!jay
  ...ames!scubed!