Tuesday, November 25, 2014

Engineering II - Assignment 10 - Directional and Ambient Lighting

Assignment 10- Directional and Ambient Lighting


ZIP LINK

Assignment10.zip

Write-Up


The basics of this assignment were to focus on getting correct lighting, both ambient and directional working in our game engine. This required our meshes to be using their normals, which required our Maya Exporters to include those as well.

With the normals being read by the Maya Exporter, this also required our shader programs (vertex and fragment) to use them as well.

Finally, we needed to include the ambient and directional lighting, with movement of the directional light, and then using PIX to capture some debug pixel information.


Technical Write-Up

Maya Exporter Update

The mesh type was already implemented in our last assignment, so I needed to have the exporter include the normal from the mesh as well. This was a simple addition into the exporter file requesting the newly included normal values.

The normal values are included in each vertex of the shape being imported. This is different than I initially viewed, as I expected the normal of the object to be with respect to its “side” or “face”. Maya includes additional vertices in the models to help make the rendering of the image correct with the additional vertices’ normals being included.

After this was done, I re-exported all of my initial mesh files and confirmed the normals were being included.

Ambient and Directional Lighting 

The inclusion of ambient and directional lighting was slightly more difficult. This required the alteration of the fragment shader to recognize the color of the ambient light, the color of the directional light, and the direction of the directional light.

The vertex and fragment shaders also required the normals to be input and output correctly. This allowed for the addition of the directional light and ambient light together, using the normal, and calculating the color correctly via the fragment shader.
The vertex shader required the normals to be calculated with the mesh, and the world rotation.

Here is an image of my scene with ambient and directional lighting:




The light for the image is coming from below and to the right (your right) of the character, and has a red-ish tint. The ambient light is white, and is fairly dark, while the directional light has the heavier value of red.

I implemented movement controls for the directional light, which allow you to change the direction of it. I also allow the user to alter the color of the ambient light, and the directional light as well.

If you were to access the code and alter the lighting manually, it would be inside of my Graphics.cpp file,and you would change the variable's values which are D3DXVECTOR3 values. For color the x would be red, the y would be green, and the z would be blue. While for the direction, x, y, and z would be as normal.

The control schemes for altering these values at runtime are as follows:

I - Move the directional light to face the negative z direction
K - Move the directional light to face the positive z direction
J - Move the directional light to face the negative x direction
L - Move the directional light to face the positive x direction


R - Adds to the red value of the directional light color
G - Adds to the green value of the directional light color
B - Adds to the blue value of the directional light color


T - Adds to the red value of the ambient light color
Y - Adds to the green value of the ambient light color
H - Adds to the blue value of the ambient light color
***These color controls add to the color value, and if they exceed 1.0f, they loop back to 0.0f.


PIX Debug Pixel 

The last thing to confirm was the pixel color information, and we used PIX to do this. Below is the captured PIX image:




The image shows that during the draw call, you can click on a pixel in render (right side of the image) and request its history of color information. It will also allow you to step through your code for the shader and see what the code is doing.

This allows you to more simply see, step by step, what your fragment shader code is doing.

This is similar to a previous PIX step where we were able to debug the vertex shader by selecting a vertex on the mesh and stepping through its code.

All of this code is done purely in Debug mode, as you cannot step through the code in Release mode.

Realized Learning Moments
This assignment allowed me to see the key reason for Maya including multiple vertices in a mesh. It was confusing to create your own mesh by hand, and understand that a cube has eight vertices, but when Maya generates a cube it has 24 vertices. These additional vertices are for UVs and normals. If these weren’t created, then the rendering method would take the eight vertices of a cube, create a cube surface, and render it almost as a slightly flat faced sphere.

I had a great learning moment of double checking the variable names being used in your shader, and how you access them. A simple mistake I made, and then an additional pair of eyes helped out with.

Time Used

Reading: 2 hours

Write-Up: 1.5 hours
Technical Write-Up: 1.5 hours
Coding: 4 hours

Monday, November 17, 2014

Engineering II - Assignment 9 - Maya Exporter - PIX Instrumentation - Basic User Settings

Assignment 9 - Maya Exporter - PIX Instrumentation - Basic User Settings


ZIP LINK

Assignment9.zip

Write-Up

The basics of this assignment required three specific tasks to complete.
First was to set up a Maya Exporter, and allow Maya to convert to a mesh format our game engine supports. Second, was to include PIX instrumentation for debugging. Finally, we used a basic ".ini" file to allow the user to alter the size of the window, up to full screen.

Technical Write-Up

Maya Exporter

The first setup for the Maya exporter required implementing my mesh type. This required reading in the mesh file from Maya, and converting it to my format of meshes. A particular mesh I created in Maya was called "pyramidMesh.lua". The name of the mesh must include "Mesh.lua" as the type, because this is how my pipeline recognizes the mesh.

If a new mesh was generated and renamed as "pyramidMesh.lua" it would replace the current mesh used in game. This mesh is placed on two objects in the game. You would need to replace the mesh file in the Assets folder, but as long as the name is still "pyramidMesh.lua", you will have no further changes to make.

The game currently is rendering five objects. Two pyramids, one fish humanoid, one floor plane, and one sphere. The pyramids are using the same mesh, but one is using a blue ray material, and the other is using a sun material. The sphere is also using the same sun material as one of the pyramids. The fish humanoid initially uses a scales material, but if you press the "E" key it will switch to the sun material. The floor plane is using a stainless steel material.

The keys to move the fish humanoid are:

Up Arrow - Moves Fish Humanoid away from the camera
Down Arrow - Moves Fish Humanoid towards the camera
Left Arrow - Moves the Fish Humanoid left of the camera
Right Arrow - Moves the Fish Humanoid right of the camera

The keys to move the camera are:

W Key - Moves the camera upwards
S Key - Moves the camera downwards
A Key - Moves the camera leftwards
D Key - Moves the camera rightwards

This allows you to see that the material and mesh components of the in-game object can be altered with a simple pointer movement. This is shown in the image below:


The left section of the image shows the fish humanoid with the scales material, and the right section of the image shows it using the sun material.

Overall in the scene, the pyramid on the left has the sun material, while the one on the right has the blue rays material. The sphere, with the sun material, is above the fish humanoid. The fish humanoid is floating above the floor plane with the stainless steel material.

A key point to recognize is that if the material is going to show appropriately with the UVs, the UVs must be adjusted in Maya. I do not know how to adjust the UVs in Maya for the meshes being exported, so they do not look correct in game.

PIX Instrumentation 

The second setup is for PIX instrumentation, which allows the engineer to generate the scene, capture a frame of rendering, and see what function calls are being made. It also allows the viewer to see what objects are being rendered, view the vertices, indices, and UVs of each object.

The instrumentation added to the current engine code allows the creation of your own custom events to wrap the engine code for easier visibility in PIX. This is currently being used in Debug mode only, as you wouldn't want to generate these calls in Release mode.

The two key pieces of information that is currently grouping function calls is the setup of new materials, and the drawing of new meshes. The material setups and the draw calls can happen every frame, and will show up in PIX. See the image below:


The left section of the image shows PIX using Debug mode and shows the "Set Material" event which is capturing each function in that event. The image also shows the "Draw Mesh" event, capturing the Draw Primitive function call. The right section of the image shows PIX using Release mode, and shows no events being called.

These events can be used throughout your code to help you more easily view specific function calls, group code that is important, or ignore function calls you do not want to see.

User Settings

Finally, the last implementation is the use of basic user settings for the engine. This allows the user to alter the "gameSettings.ini" file, in the Game directory, to change the screen size, or set it to full screen for their current resolution.

This required some additional code for the user settings to be altered. After implementing the included code, some reformatting was required. This happened in the Windows Program class and the Graphics class.

If the user sets the width and height to values less than zero, it sets them to default "800 x 600" (width x height). If the full screen variable is set to true, the width and height are ignored and the game is set to be at the current full screen resolution.

This file is generated in the game folder after the game is built. This allows the user to alter the .ini file that exists for that build, but still saves the original file in the original folder. This was done by a custom build tool for the in the .ini file. This prevents anyone, including myself from altering the original file from it's initial setup.

Realized Learning Moments

With the Maya materials I realized I had to save pointers to all of the meshes and materials, and this would allow my entities to change meshes and materials when needed. This required some reformatting of my mesh, material, and graphics classes. It is more robust now, but will require additional reformatting for the game to handle the entities in a more isolated manner.

The PIX implementation helped remove extraneous statements in Debug mode. You were able to find the needed functions or calls more quickly than hunting through "IDirect3DDevice9::..." descriptions. I was going to try and use more of this in my build for other parts of code, but would require using Direct3D code in those sections. This is for rendering purposes, and we'll leave that focus there.

The user settings was a fairly simple setup. There is an odd issue when using Alt-Tab to change to another window, but this causes the game to crash. If you use the "X" in the top right corner, or hit the escape button it will cleanly exit from the program.

This homework provided a stronger understanding of weak points in my architecture. I have realized points in my graphics code that needs to be isolated in another class, and will make it easier to read, and more difficult to alter by accident.

I need to change the ".lua" extension of the mesh and material files to appropriately fit ".mesh", ".material", or something more easily readable and usable.

I was also really happy to include this old fish humanoid model I made in Maya. It was my first attempt, and I thought it was fun to see in my game engine.

Time Used

Reading: 3 hours
Write-Up: 0.5 hours
Technical Write-Up: 1.5 hours
Coding: 9 hours