This is completely redundant in prman21 because of PxrDirt, but since our project was in 20 I wanted a way to procedurally add dirt to our assets. In the end it wasn’t used, but it was a great introduction to the new RIS API!
I was lucky enough to compete in the 7 week national student competition BFX to produce a short 30 second animated film for a charity, we took a little bit longer to get everything finished but I’m happy with how it turned out!
My roles included
Pipeline
Required me to write Python/Bash based tools to automate rendering tasks, such as handling the uploading of assets to the renderfarm and submitting the job on the farm itself.
Configure SVN on a network drive and encourage the team to use it as a remote backup/version control system.
Shading/Lighting TD
Shader development & look development for the characters/environment.
Lighting multiple shots.
Our renderer of choice was Renderman 20.9 (RIS mode).
Compositing
Involved pulling in the various render AOVs/LPEs and putting everything together.
Final grading tweaks.
Director
This was my first time using Renderman for a full animation; while we did run into some bugs that caused us some pain, I would hope they wouldn’t happen again now I have more experience with it. I had a lot of fun lighting in it 🙂
‘CONTACT’ is a near 3 minute long VFX sci-fi short, showing an astronaut’s state of mental decay after experiencing an encounter with a 5th dimensional being while in orbit. The team worked hard to create over 80 CG assets, 3 digital environments, and a bespoke fractal render engine for the evolving tunnel sequence at the height of the piece. Over 26 shots were composited into these built environments and costumes, fleshing out the narrative and blending together the live-action and the digital elements of the film.
A group assignment I directed during my 2nd year, we developed an atmospheric survival horror game about the mythical Windigo.
In addition to directing responsibilities, I was in charge of pipeline (we used a Perforce setup with a remote server to version assets) and engine level C++ programming (primarily core gameplay features and supporting the AI developer with whatever engine features they required).
if( Serial.available() >= 4 ) { //Protocol >= 4 bytes (header + info + footer + Npayload)
Header = Serial.read();
PacketInfo = Serial.read();
unsigned int payloadLength = (PakInfo & 0x0F);
Byte payload[payloadLength];
Byte result = -1;
for(int i = 0; i < payloadLength; i++)
{
Byte result = Serial.read();
/* Premature packet footer */
if(result == FOOTER_ID)
break;
payload[i] = result;
}
/* Less data than expected */
if(result == FOOTER_ID)
{
return PACKET_ERR_INVALID;
}
Footer = Serial.read();
Byte chksum = CalculateChecksum(...); // Generate checksum somehow
Serial.write(chksum); // Send back to dealer for verification
}
Dealer side
Playing card
Data structure
Credit to my lecturer Ian Stephenson for the main idea behind this, his example implementation used macros to define the constants. I decided to use enums placed inside namespaces so they don’t pollute the global namespace while giving a readability benefit. I find Suit::Spade clearer than just SPADE.
A possible alternative would be to use bitfields, but in the higher level parts of the library these simple constants/macros are abstracted away with C++ classes and functions anyway.
Suit
namespace Suit
{
/* Suit is stored in the left nibble of a byte */
enum Value
{
Diamond = (1<<4), // 0001 0000
Heart = (1<<5), // 0010 0000
Club = (1<<6), // 0100 0000
Spade = (1<<7) // 1000 0000
};
}
Rank
namespace Rank
{
/* Rank is stored in the right nibble of a byte */
enum Value
{
Joker = (0x00), // This isn't used in poker, but is added for completeness
Two = (0x01),
Three = (0x02),
Four = (0x03),
Five = (0x04),
Six = (0x05),
Seven = (0x06),
Eight = (0x07),
Nine = (0x08),
Ten = (0x09),
Jack = (0x0A),
Queen = (0x0B),
King = (0x0C),
Ace = (0x0D),
/* Unused= (0x0E), */
/* Unused= (0x0F) */
};
}