Textures that Fool

Shared by: fdh56iuoui
Categories
Tags
-
Stats
views:
7
posted:
10/10/2011
language:
English
pages:
42
Document Sample
scope of work template
							                     Textures that Fool
                       Alex Sawczuk



TEXTURES THAT FOOL

BY ALEX SAWCZUK


APRIL 2007




ROGER HUBBOLD




                             1
                                               Textures that Fool
                                                 Alex Sawczuk


ABSTRACT

My project is called Textures that Fool, which is an investigation into the use of impostering. It was produced
by myself, Alex Sawczuk during April 2007, with the assistance of my tutor Roger Hubbold

The general purpose of my project was to see if there is any noticeable loss of image quality when using a
technique called Impostering. Impostering is a form of level of detail [A9], which replaces the original
geometry by a much simplified version of the original. Impostering in particular makes gains by using a very
simple geometric model, and texturing this by rendering the original object in real time, and saving this texture
and mapping it to the imposter.

The key aims of my project are to see if there are any graphical differences between a scene using impostering
and one without, as well as looking into any performance disparities between the two.




ACKNOWLEDGEMENTS



Tutor: Roger Hubbold

Related Paper: A Three Dimensional Image Cache for Virtual by Gernot Schaufler and Wolfgang Sturzlinger

Livet Glen 3D Model Textures: Luc Van Camp




                                                        2
                                                                     Textures that Fool
                                                                         Alex Sawczuk


CONTENTS

 Abstract .............................................................................................................................................................. 2

 Acknowledgements ............................................................................................................................................ 2

 Chapter 1: Introduction ...................................................................................................................................... 5

    Introduction to imposters............................................................................................................................... 5

    Project Plans ................................................................................................................................................... 6

 Chapter 2: Background and Literature survey .................................................................................................... 7

    Imposter papers.............................................................................................................................................. 7

    Related Areas of Interest ................................................................................................................................ 7

    Imposter Implementation Article ................................................................................................................... 8

 Chapter 3: Design ............................................................................................................................................... 9

    Requirements analysis .................................................................................................................................... 9

    3d Model......................................................................................................................................................... 9

    impostering Internals.................................................................................................................................... 10

    User Interface ............................................................................................................................................... 13

    Statistics ........................................................................................................................................................ 14

    Summary ....................................................................................................................................................... 14

 Chapter 4: Implementation .............................................................................................................................. 15

    Setting up the scene viewer ......................................................................................................................... 15

    Completing the viewer ................................................................................................................................. 17

    Impostering................................................................................................................................................... 18

 Chapter 5: Results ............................................................................................................................................. 22

    User Menu .................................................................................................................................................... 22

    Scene Viewer ................................................................................................................................................ 25

    Impostering................................................................................................................................................... 26

 Chapter 6: Testing and Evaluation .................................................................................................................... 30

    Functionality Tests ........................................................................................................................................ 30

    Performance Related Tests ........................................................................................................................... 32



                                                                                  3
                                                                     Textures that Fool
                                                                         Alex Sawczuk

     Graphical Differences Testing ....................................................................................................................... 36

  Chapter 7: Conclusions ..................................................................................................................................... 39

     Achievements ............................................................................................................................................... 39

     Given More Time .......................................................................................................................................... 40

  References ........................................................................................................................................................ 41

     Background Research ................................................................................................................................... 41

     Implementation References ......................................................................................................................... 41

  Appendix ........................................................................................................................................................... 42




NOTES

All images are uploaded in full onto my site gallery. See references for link.

References are noted by [R#]

Appendix references are noted by [A#]

Total word count approximately 12,000




                                                                                  4
                                               Textures that Fool
                                                 Alex Sawczuk


CHAPTER 1: INTRODUCTION




INTRODUCTION TO IMPOSTERS

The purpose of this project is to investigate if there are any performance and image quality differences
encountered when using a technique called impostering in a 3d scene.

As briefly mentioned in the abstract, an Imposter is a simple object, such as a plane or a box that is textured
and replaces an original mesh which has a much more complex geometry. This is effectively a form of Level of
Detail [A9], where high resolution meshes are replaced with lower detailed meshes when the object is far
away from the user’s viewpoint. In impostering, the imposter has its texture generated dynamically, by
rendering the original object on its own and taking the texture produced from this and mapping it onto the
imposter. If the user stays in the same viewpoint the imposter should look identical to the original. However as
the user moves away from the original point, the object will start to look distorted. Hence as the user moves
around the environment the various imposters will need to be recalculated.

There are two methods that can be used to generate such imposters. Firstly you can pre-process this and
generate all of the imposters before hand for future use. Or they could be generated on the go whilst
rendering the scene. Pre-processing would result in a very heavy use of textures and memory in order to try to
cover as many view points as possible. Ultimately this is not a particularly viable method of generating
imposters. With dynamic imposter generation only imposters valid for the current view need be generated and
used; this will in theory, if handled correctly, be more efficient in terms of memory usage.

To dynamically generate imposters, the system needs to calculate each time if the current imposter in use is
valid or whether the user’s view point has changed too much and the object requires regeneration. If there is
too much regeneration the performance increases made will drop as the most performance costly operation is
the regeneration of an object and saving the texture from screen to memory.

Modern graphics systems in computers are advancing extremely quickly and capable of so much more than
ever before, however, the greater the processing power available, the more detailed models and more
complicated shader settings are used to take up this processing power. As a result optimizations are always
needed and there are several situations where an impostering solution would prove very effective. Such as
outdoor scenes like a forest or a city area, where many the objects further away can be greatly simplified and
loss of minor details or distortion would not be noticed as much.




                                                       5
                                                Textures that Fool
                                                  Alex Sawczuk


PROJECT PLANS

For this project I plan to use platforms that are familiar to me. This means I intend to use Java and an OpenGL
port in order to get the maximum out of my programming skills. In addition my project will implement the
basics of impostering and in a way that can be visually shown, due to the limitations in time I have to
implement a solution. Using a visual manor to generate imposters will allow the user to see the impostering
take place by showing which objects are being replaced as well as other visual aids, such as the ability to turn
impostering on and off on the fly and detailed statistics of polygon savings amongst other things. The
alternative would be to hide the actual impostering in an off screen buffer, this would likely be more efficient
but would be harder to develop.

The project will also look to use various additional free classes available to load 3ds files (a generic 3d model
file format [A1]) and any generic dds\targa\bitmap textures. This should allow for various different models to
be imported to the viewer with relative ease, in addition to adding a user interface to help the user setup any
relevant settings.

In summary I plan to look at the actual visual differences more than the performance issues and hope to
implement this in a flexible manor allowing the loading of different models.




                                                        6
                                               Textures that Fool
                                                  Alex Sawczuk


CHAPTER 2: BACKGROUND AND LITERATURE SURVEY

For background reading I found a few related papers to help with the development of my system, however
finding all relevant information proved difficult, and some relevant articles were not found until after I had
programmed my implementation.




IMPOSTER PAPERS

The main source of background information for my project is a paper by Gernot Schaufler and Wolfgang
Sturzlinger entitled ‘A Three Dimensional Image Cache for Virtual Reality’. This paper published in 1996
outlined the general concepts of impostering as well as further details in how to optimize the operation.

In the paper, Imposters were generated by taking the extremes of the bounding box and imposing the viewed
texture onto a plane through the centre of the objects bounding box, and with its normal pointing directly at
the viewer. The regeneration of imposters was then calculated by measuring a series of angles generated
when the viewer moves away from the generation point, and the imposters regenerated when a set threshold
is broken. These angles were calculated in two separate manors, one for lateral movement and one for motion
towards and away from the object, based on the change of angle between points on the bounding box and the
plane.

The three dimensional image cache implemented allowed for further optimizations in the procedure. This kept
a hierarchy of bounding box [A5] image data to be stored, with the lower levels used to generate the
imposters at higher levels. This approach requires a recursive bounding box to be setup for all objects in the
scene, where all objects in the scene are split up based on their location. This results in quick regeneration of
imposters that include many objects, and only any invalid lower level objects need regeneration. This produces
automatic grouping in a pre-processing step of the objects that you wish to imposter. In the tests conducted in
this paper, they experienced approximately an average 50% decrease in frame draw time, although certain
frames with a high load could take much longer than the non impostering examples.

More recent work in the field has lead away from the basic impostering and into how to optimize the situation
further for animation. The paper ‘True Imposters’ by Eric Risser was published last year and details how to use
height data in each individual pixel in the imposter to give a more effective effect when the viewers
perspective changes. This extension is particularly useful for rendering large volumes of items, such as a school
of fish or a flock of birds. However this isn’t particularly relevant to my line of investigation and merely shows
the further potential in the area.




RELATED AREAS OF INTEREST

In addition to these papers I did some further research into similarly related areas. I read three such papers
which helped give some insight into other options available and the possibility of perhaps the merging of
separate ideas.

The first such paper was ‘A Survey of Advanced Interactive 3-D Graphics Techniques’ by Dieter Schmalstieg.
This simply documented several methods of optimizing the displaying of 3d scenes. Such techniques included
using Level of Detail [A9] and Image Based Rendering [A6]. These two techniques have similarities with
impostering and as so were worth looking into.


                                                        7
                                               Textures that Fool
                                                  Alex Sawczuk

Level of Detail is the technique of using different 3d meshes as an object moves away from the user’s
viewpoint. This means that a mesh of lower detail can be shown when further away from the current
viewpoint and the reduction in detail is not as noticeable. The paper details several algorithms to reduce the
amount of detail in the mesh; however this can also be done manually by the modeller. There can also be
issues when switching between different models. Especially if the user is walking back and forth on the
borderline of a level of detail change, this can result in a popping in and out effect which can be visually off
putting. One such method to adjust this is to blend between the two different levels of details so the changes
become more gradual. This area is particularly interesting in relation to impostering as impostering is actually a
form of Level of Detail, with the original mesh being replaced by a simplified version in the imposter.

Another interesting area, slightly less related is that of Image Based Rendering. I read two papers on this
subject; the first named “Relief Texture Mapping” by Manuel M. Oliveria, Gary Bishop and David McAllister
and the second by Lenard McMillan and Steven Gortler entitled “Image Based Rendering: A New Interface
Between Computer Vision and Computer Graphics”. Between these two they quite comprehensively covered
the topic, which is using height data in the texture to give the object more detail. An example of a brick wall is
given where using the Relief Texture Mapping technique; the bricks are made to stand out rather than looking
simply like a flat texture. This is done by warping the texture based on the height data stored in the relief map.
This and other image based rendering [A6] techniques offer performance increases over the modelled
alternatives and are another way of increasing the performance of rendering the scene. In the future a relief
texture solution could perhaps be integrated with impostering; this would then allow imposters to be valid for
a larger range without significantly looking disfigured.




IMPOSTER IMPLEMENTATION ARTICLE

After completing the implementation of my project I found an article by Ashley Davis, explaining how to
implement impostors in DirectX. This is especially useful as it explains the pit falls and difficulties to be had
when implementing such a system. Here issues with transparency are highlighted, as well as the size of texture
to render too. The issue with transparency is that the usual source alpha – inverse source alpha method of
rendering objects requires objects to be rendered from back to front in-terms of visibility. However if an object
is being impostered then it is rendered on its own and the alpha transparency will not be kept. As a result a
more simple method of transparency needs to be used or the saving of the alpha channel [A3] from the object.
Also decisions need to be made as to how to manage the amount of memory space given to individual
textures. Several options available include setting aside a preset amount of pixels per every imposter or
calculating the amount required as each imposter is generated. This article in general covers some of the areas
I had difficulty with and how to solve them, and in some cases I used a similar method to solve these issues.




In summary these are the background material I have studied in order to help me design and implement my
project. However most of these do deal with the question of performance rather than visual quality. As a
result using the perhaps slightly less efficient Java implementation of OpenGL should not cause any problems.
Also as I am familiar with both of these languages the program is likely to be of a higher standard as such.




                                                        8
                                               Textures that Fool
                                                  Alex Sawczuk


CHAPTER 3: DESIGN

The design of my system starts out with taking into account the features and background knowledge acquired
previously. In addition it explains the core ideas behind impostering and how these are to be implemented.




REQUIREMENTS ANALYSIS

In order to successfully design and implement my project I shall first look at what goals, milestones and
features I wish to implement with in my system. These can then be used to judge how successful my final
application is.

Firstly I wish to produce a system which has the following features; these features were compiled by looking
into how impostering has been carried out previously, and also in an effort to make an easy to use
demonstration.

    OpenGL and Java based solution, with GUI to setup settings and scene, and on screen messages in viewer
    to show current settings and details.
    The ability to load generic 3ds files (geometry files)[A1] and the usual texture files (i.e.
    Bitmap\Targa\DDS).
    Variables to control the amount of impostering.
    Impostering, to be able to toggle it on or off in run time.
    Statistics. Various statistics for using in Evaluation, based on savings made and other usage statistics.
    Various other options to give a complete user interface, such as help options, validating model (i.e.
    missing textures) and setting up other generic settings, such as viewer screen size as well as saving and
    loading these settings.




3D MODEL

For this project I will require a 3d model to navigate around and to use for impostering. For this I will be using
the 3d model which I have created last year for motor racing simulator rFactor. This is a fantasy circuit named
Livet Glen and has a virtual track length of 1.4 miles, approximately 100,000 polygons and was scratch built in
the 3d design software, 3ds Max[A2]. This should offer sufficient objects to show the impostering capabilities
of my project. Due to the nature of impostering, only certain objects in the scene will be used for impostering,
objects such as the terrain and sky will not be used for impostering. The model will not look as good as it does
in the game due to the lack of shader settings in my project, and the circuit was built to use these, rather than
look good on flat textures. The track was modelled by myself, and the textures were created by Luc Van Camp.
Links on further details on the circuit are available in the references section.

The track will be exported into the 3ds file format and the textures used in dds format. These will easily load
with the available libraries for Java.




                                                        9
                                                Textures that Fool
                                                  Alex Sawczuk




IMPOSTERING INTERNALS

Next to look at is exactly how to implement the impostering and how to control where and when the
impostering is carried out.

The first thing to look at is what form the imposters will take. There are several options that could be used, for
instance, for greater detail and to allow for the imposter to be valid for longer it could be setup as a box. Or a
lamp could be setup as a billboard [A4], whereby it always faces the current viewpoint, or finally the imposter
could just be generated onto a flat plane.

To use box style impostering would be the easiest to implement, as the objects bounding box can be used, and
the performance difference in using 6 polygons rather than 1 is negligible. The ability to have a billboard style
imposter, where the polygons of the imposter are always pointing towards the user is unlikely to be of any real
use and would require some kind of manual assignment of a pivot point or line of symmetry to give an
accurate effect. Plane style impostering generally takes a little more calculation when setting up the object
than the bounding box; however it is ultimately slightly more efficient, dependent on how long the imposter is
valid for. As a result I shall implement the box method first, as this is in theory the simplest and then the
generic plane option if time permits.

Another potential option to look at is whether to group objects together or not. If various objects are grouped
together then they can offer greater efficiency in that several objects are replaced by one imposter. However
there then becomes the issue of how to group the objects together. In the paper ‘A Three Dimensional Image
Cache for Virtual Reality’ the grouping was done in a pre-processing step based on their location. This was then
placed in a tree structure and various leaves regenerated as required. However this does not allow the user to
setup any grouping of their own, and there maybe situations missed which would make sense to group
together that are missed. To implement such an automatic grouping method would be quite complex and
would require the development of a hierarchy of bounding volumes [A5] setup, this is perhaps something that
could be implemented at a future date if this project were to be expanded. As a result I shall only offer manual
grouping. The easiest way to implement this will be via the naming of the objects, whereby if so many
characters are the same objects are
automatically grouped together and act as one.
In addition adding a wildcard character as the
first in the name of the object to indicate no
grouping will allow for certain objects to never
be impostered, as maybe required for some
objects. (For example terrain and skyboxes don’t
lend to being impostered, due to their
complexity.)

For the controlling when to use Imposters, the
usual way is to give thresholds for lateral
movement and movement to and from the
object, this method was used in reference #1. In
order to simplify this slightly I shall simply use
one threshold and create a valid sphere from
the point the object was impostered. Rather
than giving a valid distance for each imposter, it
should be based on how far away from the object the imposter was created. Hence I shall use a validity angle,


                                                        10
                                                Textures that Fool
                                                  Alex Sawczuk

and use simple trigonometry to calculate the actual valid distance from the imposter’s source point, rather
than using a static distance. This gives the desired behaviour of objects close to the user’s viewpoint having a
smaller validity range, where as objects further away from the user stay valid for longer.

Additionally logically, there will become a point where the object is too big in screen size to make little sense
to continue impostering. Therefore I shall also implement a maximum screen size for impostering. When the
object is bigger than this threshold then it is simply rendered in all its geometry. This is likely to be a naive
calculation just using the objects bounding box to estimate its onscreen size.

When handling the regeneration of imposters, I propose to implement a queue system which will render the
imposters when there are sufficient resources to do so. In addition it’d be wise to add objects to such a queue
when approaching the end of the imposter’s validity area. This means that the imposter is likely to be
regenerated without needing to switch to and from geometry first. The queue method will offer scope for load
balancing, regardless of the method used to imposter objects.

Below is some sample psuedocode to demonstrate the above ideas:

If(objectSize > maxImposterScreenSize)
         renderObject();
else{
         if(imposterInvalid)
                   if(!inQueue)
                            addObjectToImposterQueue();
                   renderObject();
         else if(imposterNearlyInvalid)
                   if(!inQueue)
                            addObjectToImposterQueue();
                   renderImposter();
         else
                   renderImposter();
}


The next major issue is exactly how to create imposters. For this several things need to be carried out, the
object needs to be rendered on its own from the current viewpoint, then the visible texture needs to be saved
for future use. Also the object needs to have the geometry of the imposter calculated, which will be one of a
flat plane imposter or to use the object’s bounding box. There are then further options which could be setup,
like saving several imposters when they become invalid for future use. These could be implemented if there
was sufficient time.

In order to actually save the imposter there are a few options, firstly an off screen buffer could be setup, or
perhaps more easily a second context could be used. The advantage of an off screen buffer is that it would be
far more efficient in than a second context, however it would ultimately be more difficult to setup correctly as
you simply can’t see the end results. Using a second context is a far more inefficient method; however it does
allow the user to view the actual impostering as it takes place. As this is meant to be a demonstration of
exactly how the impostering works, and I have limited time to implement my solution, using a separate
context will allow the user to view the impostering as it happens more clearly and also allow for a solution to
be produced more quickly. However this is likely to result in an inferior performance compared to using an off
screen buffer.

Within the java implementation of OpenGL, “JOGL” [R12] there are several classes which will assist the
development of this project, none more so than the handling of saving the imposters. Here a screenshot class
will be used which offers the ability to save the image to memory for future use. The image will be cropped to

                                                        11
                                                Textures that Fool
                                                     Alex Sawczuk

the nearest possible size, making sure that the image’s dimensions are kept to, 2 to the power of. (Images
need to saved like this, i.e. 32x64 pixels in order to operate efficiently and correctly with in most graphical
environments). These images can then be saved easily and displayed on the generated imposters.

As for the calculating the geometry of the
imposters there are two options available here.
For impostering with boxes the base bounding
box can be used. This would be calculated when
loading the 3ds files by keeping a log of the
extreme values along the axis, and would also
have to be calculated for any grouping too. These
are then rendered with backface culling, so only
the faces pointing towards the viewer are shown
in the user’s current view. The texture co-
ordinates of the box are then calculated by using
the position of the vertices of the bounding box
on the texture they were when the imposter was
created. This means that the texture is effectively
overlayed onto the box as is seen in its current
projection, and mapped so that the part that is
seen where the front of the box is, is mapped
onto the front of the box, and the same for each
of the other sides. In theory the object will look
as it does in geometry when its impostered when the user is standing at the creation point. The more the user
changes their viewpoint the more distortion will become obvious in the object. In addition box shaped
imposters make sense for certain objects, such as buildings as they allow the object to keep a sense of depth in
the actual geometry also, where as a flat plane imposter is likely to become distorted much more quickly, at
ultimately a small cost, with only 6 polygons to be rendered, or even less if we are able to only render the
polygons facing the current viewpoint.

The alternative method is to use a flat plane
imposter. This would require the use of an
objects bounding box to calculate the necessary
plane anyway. The plane would have to be
centred in the middle of the objects bounding
box, and facing the user’s viewpoint. This would
require some trigonometry to calculate the
plane. Then the plane would need to be
trimmed to the extent of the bounding box in 2d
space, as shown in the below images. This can
be quite difficult to calculate the 4 points which
make the borders to the imposter.

The calculating of the plane is ultimately much
more complicated and likely to result in delays;
as a result I shall implement the simpler box
option first, and if I have time I will implement
the plane style impostering afterwards.




                                                         12
                                                 Textures that Fool
                                                    Alex Sawczuk


USER INTERFACE

Within my system there will be two main areas of user interface control. Firstly there will be a screen to allow
the user to setup the impostering as well as various other settings, and that shall be followed by the actual
scene viewer. The viewer will allow the user to walk around the 3d environment, as well as toggle various
impostering options and visual aids through keyboard hot keys.

For the initial settings screens, options will be grouped together by various tabs allowing the user to navigate
and find options and information more easily. Also the UI will allow the user to save and load their settings,
allowing for the user to quickly make small adjustments to their settings. Included also will be a list of all the
available hotkeys in the scene viewer for reference. Finally this initial screen will still be available once the user
starts up the scene viewer, however with options which could cause trouble disabled, i.e. the user will not be
allowed to start up a second scene viewer. All related settings for impostering will be modifiable here, as well
as logged statistics and a help screen detailing the various hotkeys available from within the viewer. In order to
show exactly what I meant by these ideas I have brought forward an image from my actual implementation.




With regards to the scene viewer itself, I will implement some helpful options to allow the user easier
navigation around. The major issue really is notifying the user when they change something. So I will
implement a message system which is displayed when the user carries out an action, i.e. Toggle Wireframe
Mode. This message will be overlaid onto the screen, helping them to find their way easier.




                                                         13
                                               Textures that Fool
                                                  Alex Sawczuk


STATISTICS

One other vitally important item to implement is some form of statistical analysis. It is important to know
exactly what effect the impostering is having on the system. As such I have a few plans to help with this.

Firstly the system will include a path system, where a set path around the user’s environment can be recorded
and then replayed afterwards. This will allow statistics to be logged fairly under the same environment for
analysis. This can be done by simply logging the users view point at each frame and then simply asserting these
viewpoints for each frame when playing the path. Then from the time it takes to run this path with a set
number of frames, it can easily be calculated the frames per second of the previous run.

Secondly I shall implement a statistical logging system. This can record polygons rendered, polygons saved
through impostering, amount of imposters generated etc. It will also be important to include these in different
contexts, for instance separate statistics when playing a set path, as well as an overall statistics, and also for
the current frame also where relevant.

These statistics should give me sufficient data to analyse the effects of the impostering in terms of
performance issues. With regards to the visual effect the only way to compare these is to apply a difference
filter on two screens from the same location, one with impostering enabled and one with it disabled. Only then
will this show statistically the amount of error in the visual performance.




SUMMARY

In summary the above points are all that I need to implement as a bare minimum to get a working demo that
will allow me to get sufficient data to report and analyse, there are many other features which could be
implemented however time constraints mean that they must be saved for the evaluation.




                                                        14
                                                 Textures that Fool
                                                    Alex Sawczuk


CHAPTER 4: IMPLEMENTATION

The implementation of my project was carried out in the java integrated development environment, NetBeans,
and also was built for a windows platform; however it can be adapted to others, such as Linux, with relative
ease. This does require some extra library classes to be downloaded however.




SETTING UP THE SCENE VIEWER

My first task during implementation was to set up a base scene viewer. To simplify this to start with I simply
tried to import a textured 3ds cube and render it.

In order to set this up I needed to get my underlying architecture correct first. In order to set this up I used the
following design (with a few levels of abstraction here).




         UserMenu.java                         ModelData.java                          Viewer.java




Here the UserMenu sets up the various settings and stores them in the ModelData class. These settings are
then accessed and modified as required via the viewer once it is loaded.




USER MENU BASICS

In order to view even a basic scene I first had to implement a basic user interface to setup the required
settings for the system before the scene is loaded. The user interface was produced using NetBeans own visual
designer in order to give a consistent and professional looking design. Initially this included just options to
specify separate directories to load images and for 3ds files. These made use of the FileChooser component in
java to select the appropriate directories. Also the valid files in the current directories were listed in list boxes,
so only 3ds files in the model list, and only valid textures for the texture list, regardless of any other files
present. I also offered the ability to save the directories used for easier loading during testing.

Once these settings were selected they were automatically saved to the ModelData class which was then
passed to the viewer as a reference when the viewer was loaded.




MODEL DATA BASICS

In order to import 3ds files I have used a modified java importer available from joglutils [R9]. The classes
available here allow the 3ds files to be imported into arrays of vertices, faces, normals, texture coordinates
and various other required information. I used these classes in order to import my 3ds files. (And actually
added extra functionality including fixing a bug which meant some numbers weren’t read correctly and also
adding the ability to calculate the objects bounding box).

                                                         15
                                                Textures that Fool
                                                   Alex Sawczuk

To begin with, in order to get the basics working correctly I simply saved a list each for the associated texture
files and 3ds files – these are stored when the user sets them up in the user menu. In addition I created
‘accessor’ methods for the underlying imported 3ds data which is stored in a separate class created by the
aforementioned classes.

When the viewer is loaded the model data initiates the appropriate methods to import the stored 3ds files,
then it is checked that all the required textures are present during loading, and stores the data in a way
accessible by the viewer to render the scene. Then all of the objects within the 3ds files are put into one
arraylist for easier processing when rendering. Below is some psuedocode to demonstrate exactly how the 3ds
files are loaded

LoadData() Psuedocode:

public void load_data(boolean Final){
    loaded=true;

      for all 3ds files
        load3dsfile();

      if(Final){
         for all objects loaded
           add new object to arraylist

  }




VIEWER BASICS

Once I had the model data and user menu basics setup I had sufficient resources to get an initial 3d scene
viewer working. In order to do this I reused some code from my CS2072 labs from last year. This was mainly
the basic navigation around the scene and basic rendering details. Whilst these labs were done in C, the Java
implementation of OpenGL is effectively just an interface to the underlying C programming language and
almost all of the syntax is the same. This allowed me to quickly get a working prototype of the scene viewer.

As a result the following methods were added:

          Calculate_lookpoint() – Calculates the look point based on the current settings based on how the user
          moves around the scene with the keyboard and mouse. Usually called every frame.
          Diplay() – Called every time a frame is rendered. Contains code to render all the appropriate objects
          in the scene. At this stage it just renders every object regardless of whether it’s on screen or not.
          Init() – Handles the initialization of the viewer. Here all the textures for the current scene are loaded
          amongst the setting up of other scene related variables, such as how to handle transparency.
          keyPressed(), keyEvent() and keyReleased() – KeyListener interface methods for handling keyboard
          events.
          mouseClicked(), mouseDragged(), mouseEntered() etc.. – MouseListener interface methods for
          handling mouse events.
          moveViewpoint() – A method that moves the eyey and eyex variables based on the given variables.
          This method presumes there is no ground tracking as eyez stays constant.
          Reshape() – Handles resizing of the viewer’s window.




                                                        16
                                                Textures that Fool
                                                  Alex Sawczuk

These methods allowed for a basic viewer to be constructed and allow the user to walk around it. With a basic
textured cube this showed up fine and the basics of walking round the scene worked sufficiently. Further
objects could easily be added to the scene by including more 3ds files in the loading options.

However there were some bugs that I had to overcome when this was up scaled to some larger models.




COMPLETING THE VIEWER

In order to get a fully working viewer I had to carry out some adjustments to the basic viewer I initially setup.
All of these changes were carried out before I started to work on the actual impostering, as it was very
important to get a fully working viewer first.




OBJECT HANDLING

Firstly the handling of objects needed to be changed with in the viewer scene. The reasoning is that opengl
supports a feature called compiled lists [A8]. These should be used as they offer greater efficiency at runtime.
These lists need to be created for all forms that each object will take, including textured, wireframes and
bounding box options.

To handle these various options I introduced a new class entitled “ttfObject”. This dealt with all of the
rendering of objects and related information, such as texture details and acts as an interface to the underlying
base geometry.

In line with these changes, the LoadData() method in ModelData() was adjusted to use ttfObjects to
encapsulate the data. Further in the Viewer a genLists() method was added to generate lists for all the objects.
The psuedocode for this is given below:

private void genLists(GL gl){

    getObjectIterator()
    while we have more objects{
      getNextObject();
      int x = new glGenList();
      compileList();
      renderTextureObject();
      endCompileList();
      saveObjectTextureListReference(x);
    }

    getObjectIterator()
    while we have more objects{
      getNextObject();
      int x = new glGenList();
      compileList();
      renderBoundingBoxObject();
      endCompileList();
      saveObjectBoundingBoxListReference(x);


                                                        17
                                                Textures that Fool
                                                   Alex Sawczuk

     }

     getObjectIterator()
     while we have more objects{
       getNextObject();
       int x = new glGenList();
       compileList();
       renderWireframeObject();
       endCompileList();
       saveObjectWireframeListReference(x);
     }
}

Once these lists are generated they can be used to simply render various objects as follows (the same
technique can be followed for bouding boxes, wireframe and textured polygons):

    If bounding boxes are being displayed{
        getttfObjectIterator()
        while we have another ttfObject{
          callList(get current object bounding box list id)
        }
    }




OTHER CHANGES

In addition to adjusting how the objects were handled there were lots of other fine tuning tweaks required in
order to get the viewer working just as I liked.

One of the major issues I had was with how to handle transparency in the scene. The traditional way of using
alpha blending requires objects to be rendered in a set order. With the objects furthest away first and the
closest to the viewer last, if not there can be issues with incorrect transparencies. Unfortunately I didn’t have
time to do this, and had to settle with an ultimately not quite as nice looking method and use an alpha test.
This removes all parts of textures which have an alpha channel [A3] value over a given value.

As I briefly mentioned earlier I found two bugs with the 3ds file importer. The first being that some float values
were being imported as ‘Not a Number’, after looking into the source code I replaced the used method to
import floats with the standard way of converting 4 bytes to a float, and this fixed this issue. After solving this
it became apparent there was also an issue with the texture co-ordinates generated from the 3ds file importer,
as sometimes they were correct and other times they appeared to be severely wrong. After some investigation
I found that one of the values needed to be inverted. After making this change all objects worked as required.

In addition to these changes I made some other updates to the user menu including several graphical options,
such as the initial screen size, whether to enable anti aliasing and a help page explaining all of the hot key
shortcuts.

Once most of these changes had been made I was able to walk around my correctly configured 3d scene of
Livet Glen, and toggle on and off wireframe and bounding box options. At this point I felt I was at a sufficient
point to attempt to start the development of the impostering.


IMPOSTERING


                                                        18
                                                Textures that Fool
                                                  Alex Sawczuk

In order to get impostering working correctly I had to implement a number of changes in order to make this
happen. These started with User Menu and Model Data changes to store the required variables to handle the
impostering.

In order to have sufficient variables to enable impostering I added a number of variables to the user menu and
consequently the model data too. In order to carry this out I added variables for “Imposter Switch” and
“Imposter Validity Angle”. These are the two main values to control how long imposters are valid for, and at
what distance objects become valid for impostering.




VIEW FRUSTUM CULLING

In order to manage which objects need a new imposter generating I simply kept a queue of these objects.
Then objects in this queue were rendered when they were visible on screen. In order to tell if an object was
visible I needed to do some extra calculations.

As a result I was required to setup some view frustum culling in order to check this. This caused me some
difficulty in getting it working correctly. However eventually after finding I hadn’t inversed a matrix correctly I
managed to get it setup properly. View frustum culling works by setting up an instance of ttfViewFrustum for
the viewer. Then when deciding whether to render an object, the 6 vertices that make up the objects
bounding box should be passed to the view frustum instance in order to check if the object is within the visible
planes. The object can only be impostered if all 6 vertices are within the 6 planes that make up the visible area.

I setup the View Frustum Culling with the assistance of a tutorial from Lighthouse 3d and I also used a modified
plane class from a different java graphics engine named “Java Monkey Engine”. Links can be found in the
references chapter.




GROUPING

Also I had to setup the grouping methods in order to correctly setup the impostering. In order to explain a little
better how I ordered the grouping here is a diagram to show it.



                          Reference to all groups                                1 imposter
    Group List                                                   ttfGroup                         ttfImposter
                                                                                 per group
                                                                       0..1

                          Reference to all Objects                     Many
    Object List

                                                                  ttfObject


   Not Grouped
   Objects List           Reference only to objects
                          that don’t belong to a group




                                                         19
                                                Textures that Fool
                                                  Alex Sawczuk

Previously I had just a list of all the objects in the scene, in order to implement groupings this obviously needed
to be changed. Firstly I implemented a new group class, this stores a list of all of its objects, as well as a
combined bounding box, it also handles the rendering of the whole group and managing of the imposter.

The grouping is setup when the data is loaded according to objects that have the first 6 characters in their
name the same. With the exception that is of objects that start with an underscore – this is a wild card to
always render the geometry of this object. In addition to the implementation of the groupings I also setup a
series of lists referencing the groups and objects according to whether they are grouped together or not. This
makes it easier to render the scene when impostering is enabled as all objects that aren’t being impostered
can be simply rendered (every object is placed in a group unless it uses the wildcard to prevent impostering).

In addition the ttfGroup class also handles all of the impostering according to the rules given in the pseudo
code in design chapter ‘Impostering Internals’. This means that it decides when to add the group to the
reimposter queue as well as when to render the base geometry – whether it be the object takes up a large
screen space or the current imposter is not valid as the user’s viewpoint is too far from the imposter’s creation
point.




IMPOSTERING WINDOW

In the design process I decided to use a separate context to carry out the impostering. In order to do this I had
to setup a completely new class which would handle the rendering of the impostering. To begin with I just
cloned the Viewer.java class and named it ImposterViewer.java.

For the main part the basic methods stayed the same, however there were some adjustments. For instance
the viewpoint for the imposterviewer was adjusted so that it’s set by the normal viewer every time it changes
its viewpoint. Also the display method was modified to only render one group; this would be the first group in
the queue that was currently completely on screen (calculated using view frustum culling). In addition I found
that with this being a separate context, it was not possible to reuse textures and lists from the original viewer,
and these all had to be reloaded at run time. In reflection this severely hampers the performance of the
impostering.

In order to save the imposter I made use of a screenshot class with in the jogl implementation. This allowed
me to take a cropped screenshot of the currently viewed screen and save it to an image buffer. This image
buffer is then passed to the ttfGroup which then saves it to its associated imposter class. Then due to the
change in context between the imposterviewer and the normal viewer, the first time the imposter is rendered
in the normal viewer, the image buffer must be loaded. One final note, whilst the imposter class could have
been integrated with the group class, to do so would mean that the system would be restricted to only ever
storing one imposter per group. Under my system it would be fairly easy to implement a system where by a set
amount of memory or a set number of imposters could be stored as this would allow for less regeneration –
going under the assumption that the user may walk around in similar areas where older imposters may
become valid again.




                                                        20
                                               Textures that Fool
                                                  Alex Sawczuk

The diagram below demonstrates the ideas implemented here.


               1. Request Render Group                        2. No valid imposter add
  Viewer                                      ttfGroup                to queue           ImposterViewer
                 3. Render Geometry
                                                               4. Return new imposter
              6. Request Render Group

                 8. Render Imposter



         7. Return rendered imposter, load               5. Save image data, generate required
                        texture if required              geometry and texture co-ordinates



                                              Imposter




Once these ideas were all implemented I was able to get impostering working successfully. However it became
quickly apparent that there were issues with the ‘box’ method of impostering. These were that noticeable
differences between the rendered geometry and when impostering was enabled. Unfortunately due to the
development time required to get to this stage, I only had time to quickly try to implement plane impostering.
Regrettably I could not get this working at all in the limited time I had left, and decided to work on some
statistical options for the program instead.




STATISTICAL FEATURES

After getting impostering work, even if it wasn’t quite as I’d hoped I implemented some statistical options.
These included logging of the amount of impostering carried out and exactly how many polygons were being
saved. This was simply a matter of sending an update to a statistics class when an imposter or object is
rendered and was fairly simple to implement.

However in order to compare the statistics with different settings of impostering fairly I needed to implement
a method of walking a set path each time. In order to do this I added a feature to either record or play back a
path. This works very simply by allowing the user to record the viewpoint at each frame and save them to a
file. In order to play the path back, the system just streams the viewpoint from the file, ignoring any related
buttons the user may press. This worked quite well and also allowed other statistics such as fps to be
calculated as there are a set number of frames during the render time.




                                                         21
                                               Textures that Fool
                                                 Alex Sawczuk


CHAPTER 5: RESULTS

This chapter of the report details the results of the implementation and how to use the application, shown
through various screenshots and explanations.




USER MENU

When the user starts Textures that Fool they are greeted with the user menu. This allows them to setup the
required options before loading the scene. This menu can also be used to adjust settings whilst the viewer is
being used, with those options that we do not want to be changed disabled.

Below is the file setup tab from the user menu. This allows the user to specify directories to load the 3ds files
from and the textures from. In addition these settings can be saved or loaded via files saved with the extension
“ttf”. Also there is an option to check if there are any missing textures with the current settings.




                                                       22
                                               Textures that Fool
                                                  Alex Sawczuk

In the visual options tab, the user can setup a number of Imposter related settings as well as some other
generic settings. Here the user can choose how much screen space they wish to use, and how much
antialiasing they wish to use (this doesn’t quite work correctly, however it does help with aliasing issues
slightly).

The impostering options are fairly self explanatory. Firstly if you disable impostering none of the subsequent
imposter related settings are editable. The geometry buffer related options control when an object is lower
than the specified percentage of the screen size, then it is impostered. The Imposter Validity Angle controls the
size of the valid sphere for each imposter. Using trigonometry this angle specifies the distance valid, meaning
that the further away the object is from the user the greater valid area it has.

The path options allow the user to specify a file to save or load a path around the environment too. Then the
user picks whether they wish to record or play, and then when the scene is loaded they can press the ‘r’
hotkey to do which ever they selected. These options can be changed at scene run time. Path files are saved
with the extension “ttp”.




The next tab is the statistics details. This displays all the statistics recorded at run time, these can only be
updated at scene run time by pressing the appropriate button. As can be seen these options are grouped into
various similarities, with Scene based on the total objects in the scene, Total based on how many times items
have been rendered so far, Frame are just related to the last frame rendered, and Path statistics are related to
the last time a path was run. Further explanation of the statistics tab is given later in this chapter.




                                                       23
                                                 Textures that Fool
                                                    Alex Sawczuk




Finally there is the help page; this lists all the hot keys available within the scene viewer.




                                                         24
                                             Textures that Fool
                                               Alex Sawczuk


SCENE VIEWER

Once you have setup your options in the user menu, you are ready load the scene viewer. This allows you to
walk around the scene and toggle on and off extras such as wireframe and bounding boxes. Initially these
screens just demonstrate the Livet Glen circuit without impostering enabled.

This first screen shows what the viewer looks like when you walk around the scene without impostering
enabled.




                                                     25
                                               Textures that Fool
                                                  Alex Sawczuk

And this second screen shows the game with bounding boxes and wireframe enabled. (By pressing the
appropriate hot keys)




IMPOSTERING

The user can enable or disable impostering with the hotkey ‘I’. This will work using the settings defined in the
user menu. Below you can see some comparison shots of impostering enabled and when it’s disabled.

The first screen shot shows impostering enabled, and the second shows it disabled. The changes when looking
between the two are perhaps minor, however when watching in video the pop ups are noticeable. Further
below is a difference shot of the two. With white meaning no difference you can clearly see which objects are
being impostered and that there is quite a bit of difference between the two shots taken from the same spot.
This is due to the box style impostering not working correctly which has caused major problems for comparing
the graphical difference between the impostered and the non-impostered versions.




                                                       26
                                             Textures that Fool
                                                Alex Sawczuk




                  Impostered                                                Geometry




                                         Difference (White no difference)

See online for more comparison images, link in references.




                                                     27
                                                 Textures that Fool
                                                    Alex Sawczuk

The imposter viewer is a separate window from the scene viewer which simply renders one object that is
completely visible that is in its imposter buffer. Here are two screenshots showing items being rendered to
texture. This is done in the background whilst the viewer is active. This is slightly difficult to see here, see the
references chapter for a link to an online gallery with full sized images.




In addition there are some tools to help with statistical comparisons whilst running the viewer. By selecting a
file to save to the user can record a walk through the scene by pressing the ‘r’ key. Pressing ‘r’ again saves the
path to file, and can be replayed in the future by selecting the appropriate settings in the user menu. When
playing the path the system displays to the user a number of statistics upon completion of the route, including
the average amount of frames per second, as shown below.




                                                         28
                                                Textures that Fool
                                                  Alex Sawczuk

In addition further statistics can be seen by using the user menu. On the statistics tab here the ‘Update’ button
can be pressed at any time to update these. Below you can see that all the statistics for the path, each
individual frame, total and scene are all stored. Unfortunately I had to disable the total polygons rendered
tests as they were running out of memory when the viewer was open for a while.

The statistics here are grouped into 4 similar lists. Scene statistics are constant statistics which won’t change
once the scene has been loaded. Here we can see there are a total of 1230 objects in the scene, of which 994
are grouped for impostering into 202 different groups. Also there are a total of 108,357 polygons for
rendering. Of course it’s unlikely all of these objects will be visible at one time to render.

The next grouping is for Total renderings in the current session of the viewer. The frame grouping shows just
for the last frame rendered how many of each item is in use. In particular there are only approximately a third
of all the objects polygons in the scene visible at this moment in time.

Finally we have the path related statistics. These how the savings made and the time taken to undertake the
last path run by the user.

Further analysis of these statistics and tests under various settings can be found in the testing and evaluation
chapter.




                                                        29
                                                Textures that Fool
                                                  Alex Sawczuk


CHAPTER 6: TESTING AND EVALUATION

In order to perform a thorough testing procedure I have split my tests up into two separate types. Firstly we
have the functionality tests. These check that the program does as expected in the basic manor in many
places. For instance when I press ‘w’ I expect wireframe mode to be toggled on or off. Then there is the second
set of tests. These are related to the performance of the impostering and the statistics that I gathered from the
program based on the changing of various imposter related options available.




FUNCTIONALITY TESTS

Below are the various functionality tests that I carried out on my application to see if it reacted as expected.

The following tests were carried out to test the functionality of the user menu.

Test No     Test                                Expected Result                       Actual Result
1.1         Test that model directory           Load a model folder with 3ds files    As expected
            correctly loads files in the        in. Only the 3ds files are
            directory.                          displayed.
1.2         Test the texture directory          Load a folder which contains          As expected
            correctly loads the textures in     textures. Only valid texture files
            the directory.                      are displayed in the application.
                                                (i.e. dds, tga, jpg)
1.3         Initial Screen Size tests, test     Changed resolution of monitor         As expected. Changed
            that only valid screen sizes are    and only sizes smaller than           resolution from 1440x900
            given, and that correct screen      screen resolution selectable. In      to 800x600. Only valid sizes
            size loads.                         addition correct resolution used      were available and they
                                                when loaded.                          correctly loaded
1.4         Enable\Disable Impostering          Impostering only used when            As expected
            switch                              impostering check box checked
            Enable\Disable Impostering          Imposter Viewer should only be        Failed: This function was
            Viewer                              visible when this is checked.         disabled due to
                                                                                      impostering not working
                                                                                      correctly when the viewer
                                                                                      was disabled
1.5         Test that all settings are          Set settings as required, then        As expected
            correctly saved and loaded by       save to file. Close the application
            using the save and load buttons     then reload the settings with load
                                                button. All settings should be
                                                restored.
1.6         Geometry Switch Enabled             When enabled imposters will           As expected
            checkbox works correctly.           switch out to geometry once they
                                                get too close to the viewer. When
                                                walking towards objects they
                                                should switch to geometry
1.7         Check Textures button correctly     Load check the scene for textures     Both checks as expected.
            checks for all required textures.   with a few textures purposely
                                                removed. Also check with all
                                                textures present.




                                                        30
                                               Textures that Fool
                                                 Alex Sawczuk

The next set of tests are also to test the functionality of the system. However these checks will make sure that
the viewer carries out actions as expected.

Test No     Test                          Expected Result                                         Actual Result
2.1         Test navigation round the     When mouse is moved the view point follows the          As expected.
            viewer                        mouse, pressing directional keys moves the
                                          viewpoint. In addition A\S and Z\X move the
                                          viewpoint up and down and strafe respectively.
                                          Page up and page down also should rotate the
                                          viewer up or down.
2.2         Test Bounding Box toggle      Bounding boxes are toggled on and off when              As expected
                                          pressing ‘B’
2.3         Test Wireframe toggle         Pressing ‘w’ to toggles wireframe on and off            As expected
2.4         Test textures toggle          Pressing ‘t’ toggles textures on and off                As expected
2.5         Test bounding boxes for       Test that pressing ‘G’ toggles bounding boxes for       As expected
            imposter groups toggle        groups on and off. Also should only work when
                                          impostering is enabled.
2.6         Test toggle wireframe for     Test that pressing ‘h’ toggles wireframe for            As expected
            imposter groups               grouped objects on and off. Should only work
                                          when impostering is enabled.
2.7         Test Impostering              Test that pressing ‘I’ correctly enables and disables   As expected
            enable\disable toggle         impostering on the fly when in the scene viewer.
2.8         Test Geometry switch          Test that pressing ‘o’ correctly toggles imposter       As expected
            toggle.                       geometry switch on\off. Once again should only
                                          have an effect when impostering is enabled.

These tests show that the program carries out the basic functionality correctly. Next I carried out some test to
look into the performance of the system.




                                                       31
                                              Textures that Fool
                                                 Alex Sawczuk


PERFORMANCE RELATED TESTS

In order to judge the effectiveness of the various settings I made available to control the impostering in my
system, I have carried out a number of tests on different settings. These tests were also run on two separate
computers. Below are the specifications of the two systems used:

1.   AMD 3000+ 64bit CPU, 1GB DDR400 Dual Channel RAM, x1950pro 256mb PCI-E, Windows XP
2.   AMD Turion 64 ML-28, 512MB DDR RAM, ATI Mobolity Radeon X700 128MB PCI-E, Windows XP

The first system is quite a bit more powerful than the second with a superior graphics card and more RAM. As
a result one would expect tests on the first system to run more smoothly.

I devised 5 separate tests to run, and would note down the results given for the playing of a set path under
each test for each system. These tests used varying amounts of impostering in order to show the performance
related results. Listed below are the settings used for each test:

1.   No Impostoring Enabled
2.   Impostoring Enabled, "Minimum Impostoring" Geometry Switch 5%, Impostor Validity 10 degrees
3.   Impostoring Enabled, "Medium Impostoring" Geometry Switch 12%, Impostor Validity 5 degrees
4.   Impostoring Enabled, "High Impostoring" Geometry Switch 20%, Impostor Validity Angle 1 degree
5.   Impostoring Enabled, "Maximum Impostoring" Geometry Switch Disabled, Impostor Validity 1 degree


Below are the results produced when these tests were run:

Test 1: No Impostoring Enabled
     Objects   Object Polys Impostors Impostors Polys Impostors Polys Savings Frames Time               FPS
S1    941251      92498393            0                 0                          0   1976 67.797       29.145
S2    941251      92498393            0                 0                          0   1976 74.219        26.62


Test 2: Impostoring Enabled, "Minimum Impostoring" Geometry Switch 5%, Impostor Validity 10 degrees
S1    966284      80119922       38295            229770                  17426648     1976     73.54    26.867
S2    961671      79867716       38868            233208                  17669601     1976     84.06    23.506


Test 3: Impostoring Enabled, "Medium Impostoring" Geometry Switch 12%, Impostor Validity 5 degrees
S1 1002384        84634608       28270            169620                  13018033     1976      81.9     24.11
S2    993734      84163264       30428            182568                  13506740     1976     91.25    21.654


Test 4: Impostoring Enabled, "High Impostoring" Geometry Switch 20%, Impostor Validity Angle 1 degree
S1 1056923        89632239       17405            104430                   8170309     1976     83.86     23.56
S2 1056592        89406978       17554            105324                   8412112     1976 95.594       21.112


Test 5: Impostoring Enabled, "Maximum Impostoring" Geometry Switch Disabled, Impostor Validity 1 degree
S1 1056548        89762260       17567            105402                   8043950     1976     83.75     23.59
S2 1087537        91425600       12042             72252                   6393534     1976 99.469       19.865



These tests show that generally the higher amount of impostering enabled the worse the general performance
of the system. Below are some graphs in attempt to help explain these results further.



                                                      32
                                                            Textures that Fool
                                                              Alex Sawczuk

Firstly below is a graph of the average frames per second achieved with each test.

                               30
                                    T1 S1

                               28

                                                    T2 S1
                                            T1 S2
   Average Frames per second




                               26



                               24                                   T3 S1
                                                            T2 S2                    T4 S1           T5 S1


                               22
                                                                             T3 S2
                                                                                             T4 S2

                               20                                                                            T5 S2



                               18


Here you can clearly see that the greater the amount of impostering enabled the poorer the performance of
the system. This is likely to be related to the method I have used to generate and handle the impostering,
however you would expect the higher the level of impostering the lesser the advantages made. With a more
efficient method of handling the imposter’s one would expect that the results from T1 to be worse
comparative to the rest, however one would expect the degradation of performance from T2 to T5 to remain.

This next chart shows exactly how many imposters were rendered throughout the path under taken in the
test.




                                                                    33
                                                                        Textures that Fool
                                                                             Alex Sawczuk



                                                                Impostors Rendered
                                      45000

                                      40000
                                                                T2 S1 T2 S2
                                      35000
 Total Imposters Rendered




                                      30000                                              T3 S2
                                                                                 T3 S1
                                      25000

                                      20000
                                                                                                 T4 S1 T4 S2 T5 S1
                                      15000
                                                                                                                       T5 S2
                                      10000

                                       5000

                                          0       T1 S1 T1 S2

Here you can clearly see that there are actually less imposters rendered the higher the regenerate rate is set in
the test. This is likely to be caused by objects becoming invalid too quickly then there are too many objects in
the imposter queue to regenerate objects in time for rendering. This generally means that more resources are
devoted to regenerating objects and results in the slower performance of the system.

Finally here is a graph showing the amount of polygons saved through impostering in each test.

                                                             Impostors Polys Savings
                                      20000000

                                      18000000                                T2 S2
                                                                     T2 S1
 Polygons Saved Through Impostering




                                      16000000

                                      14000000
                                                                                              T3 S2
                                                                                      T3 S1
                                      12000000

                                      10000000

                                       8000000                                                        T4 S1   T4 S2   T5 S1

                                       6000000                                                                                 T5 S2

                                       4000000

                                       2000000

                                              0      T1 S1   T1 S2


Here we can see as one would expect that the higher the reimpostering settings, the fewer saving are made in
terms of raw polygons. This is down to each time an object is reimpostered the object needs to be rendered in
its full geometry. In addition with the higher impostering settings, it’s more likely that the object needs to be

                                                                                 34
                                               Textures that Fool
                                                 Alex Sawczuk

rendered as full geometry due to the likelihood that there is not a valid imposter to use, due to longer queues
for reimpostering.

Overall the performance of my application is somewhat disappointing. There is a performance decrease which
is not what one would expect in such a scenario.

The main reasons for the lack of performance with in my implementation are most likely to be due to the naive
approach I used. The system uses an entirely separate context to render the imposters, rather than using an
off screen buffer. This results in extra resources being required to run the impostering, with all the textures
needing to be loaded to memory twice, with geometry lists to be recompiled for a second time also. All of
these factors add an extra performance issue, which ultimately cause the performance of the system to
deteriorate with impostering.

Finally are some tests I did to check the graphical difference between impostering and non impostering.




                                                       35
                                             Textures that Fool
                                                Alex Sawczuk


GRAPHICAL DIFFERENCES TESTING

As demonstrated briefly in the results section I have carried out some graphical tests to compare how much
difference there is between impostering and a normally rendered scene.

Once I was able to get impostering technically working, i.e. simplified textured objects were replacing the
original geometry it quickly became apparent that there were serious issues with the actual method of doing
the impostering. I only had chance to implement the ‘box’ method, which makes use of the bounding box
geometry, and then maps the generated texture onto the box, and in theory should give a correct image.
However this was not the case as can be seen in the images below.




                   Impostered                                                      Geometry




                                          Difference (White no difference)




                                                     36
                                               Textures that Fool
                                                 Alex Sawczuk

From the first comparison above from a distance you can’t tell much difference in the objects and the scene. If
the objects are small enough then the issues of them impostering incorrectly are less noticeable. At first glance
when comparing the two images above one can’t notice too many issues. However the popping in and out of
geometry is an issue.

Below is another comparison up close to show exactly how big the issues are with this method of impostering.




Here the grand stand clearly shows how skewed the texturing becomes when objects are impostered. This is
due to the values of the texture co-ordinates being incorrectly interpolated on the polygons. Perhaps if the box
used was of a higher density of polygons this may be reduced. However ultimately I feel that the chosen
method is simply not really viable to use in its current form for impostering.


                                                       37
                                              Textures that Fool
                                                 Alex Sawczuk

In summary, my application was able to carry out dynamic impostering however unfortunately in the short
time frame I had available to me; I was unable to get the application running at either an efficient performance
or graphically correctly, but was able to demonstrate the process of impostering, and show how it takes place
too.




                                                      38
                                               Textures that Fool
                                                 Alex Sawczuk


CHAPTER 7: CONCLUSIONS


ACHIEVEMENTS

Looking back at my design requirements, I was successfully able to setup a working impostering environment.
The ability to load a generic textured 3d scene, an easy to use interface, the ability to control the amount of
impostering, and toggle it on and off. All of these goals were successfully achieved. However these were
mostly the side goals, and aims to make the demonstration a more whole solution.

The major aims of this project were to look into the visual differences between impostering and normal
rendering and also to look at what performance differences there are between the two.

Unfortunately I wasn’t able to program a fully productive solution for either of these cases. The visual
differences between the impostered and non impostered objects where rather obvious close up in my
implementation and there was serious popping in and out when switching between geometry and imposters.
That said for objects at a sizeable distance from the viewpoint, the differences were much less noticeable.
Despite this ultimately my chosen method for impostering turned out to be unusable. In theory both my tutor
and I believed that this method would work, but perhaps in hind sight I should have noticed that none of the
literature I read used such a method. Also I did not have sufficient time to code an alternative using imposters
that utilize a plane rather than a box.

With regards to the performance issues, I didn’t have great expectations for my implementation to be much
more efficient than normal. I ultimately chose to implement the impostering in the most visual manor and
easiest to debug, this means that extra resources were used in order to successfully demonstrate the
impostering. This also included using up more resources than I initially intended, in the reloading of textures
and setting up display lists for the imposter generation, the data then needed to be transferred across
contexts and loaded into the original viewer. Perhaps with a greater knowledge of OpenGL when I started this
project I could have avoided some of these issues. Typically based on reports from other programmers on the
internet they have experienced at least a 25% performance increase when using impostering correctly.

In addition there were also some features that had to be cut from the final version; I had originally hoped to
include some form of semi automatic grouping in addition to a choice of which type of impostering was being
used. These could be implemented in the future as touched on below.

However despite these issues I’ve encountered I am reasonably pleased with what I was able to achieve in a
relatively short development time of around a month and half. The program does demonstrate impostering
and has a range of tools to help analyze the performance of the system on various different levels of
impostering. Overall I would say that as a result of my project and implementation of Impostering I have learnt
much and regardless of the short comings of the actual program, these are more likely to be caused due to
perhaps an over ambition on my part, and perhaps trying to do too much in the time available. In the time I
have developed this project my knowledge of OpenGL has been greatly expanded, and given further time I am
confident that I’d be able to both have the impostering working better graphically and more efficiently.




                                                       39
                                                Textures that Fool
                                                   Alex Sawczuk


GIVEN MORE TIME

If I had more time I would look into implementing the plane impostering. I quickly attempted to implement
this, however I was not able to efficiently calculate the exact size of the plane to cover the entire of the objects
bounding box. If this could be implemented in the place of my current solution, it would be interesting to see
the respective visual differences between impostering and the base geometry.

In order for performance increases, the whole impostering part of the system would require re-coding from
scratch really. The impostering needs to be carried out in the same context as the rendering to save on
resources. However in this case some load balancing would be required to make sure that the system does not
spend too much processor time on the imposter generation. In addition some knowledge of how to program
with graphics cards may also help, with perhaps working out how to keep image data on the graphics card,
rather than saving to memory and then returning. Further performance gains could be found from looking into
how today’s graphics cards handle objects and the rendering of them, as well as exactly which calls within
OpenGL require the most resources.

If these issues could be solved then other points to look into would be the use of automatic grouping of
objects for impostering, this would be a pre processing step that splits up the scene and groups objects close
to each other. Also looking to solve issues of impostered objects occluding each other when they are not
meant too, this could be linked into the grouping of objects, with objects occluding each other grouped
together, although this could potentially cause too many objects to be grouped together.

In addition one could look into the possibility of setting up a set amount of memory for impostering and then
using this up, and keeping some imposters for future use, this way it may be possible to reduce the amount of
regeneration, based on the likely fact that users may walk around the same area, making some imposters that
are invalid, become valid again. Also to deal with the issue of ‘popping’ when imposters switch in and out of
view, there could be a system implemented where the two objects changing merged together.

If all of these suggestions were implemented it would be interested to see the graphical and performance
issues involved, one would expect the graphical visuals over my current version to improve greatly, however
it’d also be interesting to see if there are any performance setbacks for making these improvements.




                                                        40
                                                 Textures that Fool
                                                    Alex Sawczuk


REFERENCES


BACKGROUND RESEARCH

[1] Paper:
A Three Dimensional Image Cache for Virtual
by Gernot Schaufler and Wolfgang Sturzlinger
Published: 1996

[2] Paper:
True Imposters
Eric Risser, University of Florida
Published: 2006

[3] Paper:
A Survey of Advanced Interactive 3-D Graphics Techniques
Dieter Schmalstieg

[4] Paper:
Image Based Rendering: A New Interface between Computer Vision and Computer Graphics
Leonard McMillan and Steven Gortler

[5] Paper:
Relief Texture Mapping
Manuel M Oliveira, Gary Bishop and David McAllister

[6] Article:
Dynamic 2D Imposters: A Simple, Efficient DirectX 9 Implementation by Ashley Davis
http://www.gamasutra.com/features/20060105/davis_01.shtml




IMPLEMENTATION REFERENCES

[7] Lighthouse 3d View frustum culling tutorial:
http://www.lighthouse3d.com/opengl/viewfrustum/index.php?clipspace

[8] Java Monkey Engine (used a modified version of their plane class): http://www.jmonkeyengine.com/

[9] JOGL Utils (Utilities for JOGL including 3ds file importer): https://joglutils.dev.java.net/

[10] SLN Updates (Textures used for Livet Glen 3d model): http://sln.rscsites.org

[11] Gallery of Project Images:
http://www.alexsawczuk.co.uk/index.php?option=com_gallery2&Itemid=42&g2_itemId=5653

[12] JOGL: JOGL stands for Java OpenGL, this is a binding to the C version of OpenGL that effectively just works
as an interface to the underlying OpenGL code. https://jogl.dev.java.net/




                                                          41
                                               Textures that Fool
                                                  Alex Sawczuk


APPENDIX


APPENDIX A: EXPLANATIONS

[1] 3ds Files: 3ds is a proprietary file format from Autodesk and their 3d design software, 3ds Max. The file
format for these files is widely known and many importers for various platforms are available.

[2] 3ds Max: This is an advanced 3d design studio application by Autodesk with advanced features for
rendering, modelling and animation.

[3] Alpha Channel: Alpha Channel is an extra channel used to store the opacity of each pixel. This channel can
be used to blend objects together, or if the alpha value is below a given value this piece can be completely
discarded.

[4] Billboard: A Billboard is a textured plane that always faces the user’s viewpoint. This can be good for
objects that have a line of symmetry, for instance poles, and save on the geometry calculations. They can also
be used for items such as trees, where a detailed texture can give just as good a look as expensively modelled
objects.

[5] Hierarchy of Bounding Volumes: This is where objects are split up into a tree type structure based on their
location in the scene. This allows the program to cull whole objects quickly if they are in an area not currently
visible, as well as know which objects are close to each other.

[6] Image Based Rendering: This is using images rather than geometry to manipulate or render other images.

[7] Imposter: An Imposter is a simple object (usually a plane) which represents a detailed via geometry object.
This is textured by how the geometry object looks from the current viewpoint.

[8]Compiled Lists: Compiled lists are a method opengl uses of storing the geometry used to render an object
more efficiently, this list can then be simply called when rendering objects, and has greater efficiency than
telling the system to render each face of the object individually over and over again.

[9] Level of Detail: Level of Detail is the process of removing high resolution meshes with simplified versions as
the distance to the object changes. Impostering is a form of Level of Detail.




                                                        42

						
Related docs
Other docs by fdh56iuoui
Analogue Display
Views: 110  |  Downloads: 0
Binary to Decimal Conversion Worksheet
Views: 109  |  Downloads: 0
FRUIT BREEDING AND IMPROVEMENT AT SOFRI
Views: 71  |  Downloads: 0
4120 Attempt
Views: 112  |  Downloads: 0
The 2010 GRI Readers Choice Awards
Views: 43  |  Downloads: 0
Fit and Proper Policy
Views: 65  |  Downloads: 0