Unconventional Lakehouse Model: Clear Plastic Tarp Material in Substance Painter and UE5

Work In Progress / 06 April 2023

Other than getting the first squeeze on a new tube of toothpaste, there aren't a lot of things more exhilarating than getting your glass material to work in Unreal. Every time I've made translucency shaders, it's been a massive headache, my computer crashes, Unreal crashes, just generally a lot of sadness. I took a different approach this time around and knock on wood, it seems to have worked. 

I UVed all of my tarps before I simulated in Maya to futureproof if I wanted to add Realtime simulations later in Unreal. Unfortunately the downside to this that I hadn't considered was that because of the irregular shapes I was working with, the final mesh had to be pretty high poly in order for it to not look too faceted. This put a bit of a dent in my optimization, especially because I won't be able to use nanite on this piece due to its transparency. If I really want/need to lower cost, I can always go back and remesh my tarps in their simulated positions but for now it stays as is because it can. 

Over in Substance Painter, I set up my shader for PBR-Metal-Rough-with alpha blending and did a bake. I did a couple test textures and tried them in unreal but found that, for the tarps at least, using the opacity channel in Substance Painter didn't give me the look I wanted. I ended up treating it like a normal PBR material and dealing with all of the transparency back in Unreal. Using a warm grey fill layer and some different noise effects/grunge maps, I built up a pretty generic plastic material. To really emphasize the folds in the plastic and show dirt buildup, I added another fill layer with a gradient effect and then gave it a dirt generator. The problem with this was that because the dirt generator uses my curvature and AO maps, the inside parts of my tarps got solidly filled. I messed with the settings for a while and even tried deleting the maps causing the issue, but it ended up being easier and looking better to use the generator as intended for the outside, and add an extra paint layer to my mask to fix up the insides. To finish it off, I added some edge wear and used particle brushes to hand paint drips/stains. The first thing I did when I opened unreal, was turn off nanite on my tarp mesh. I created a new master material for clear plastic, set the blending mode to Default Lit, and the lighting mode to Surface Forward Shading. Now I have access to the channels I need to make this work. Using a TextureSampleParameterCube I could assign my Reflection Vector a daylight cubemap, and lerp that with my Diffuse map's RGBA node into the BaseColor for my material. The ORM and normal maps were plugged straight in, and the only other thing I needed to do was set up a Fresnel for my refraction. The material itself wasn't that hard to make, but doing a bunch of test renders to make sure the refraction was just right was a real pain. My computer was not happy and neither was I. Eventually I got it though and am pretty happy with the final result. I'm going to fix up the lighting in my scene next and make it less harsh. In the render below, it looks good, but looking at it from any other angle, the textures aren't behaving properly because of all the light. When that's better, I plan to do my next post on creating and using decals to add interest and wear to some of my more uniform materials like the wood on my dock :)

This is what my boat is looking like now

Report

Unconventional Lakehouse Model: Modifiable Texturing in Substance Painter

Work In Progress / 21 February 2023

The happiness of being done these UVs and onto texturing is immense. After a while, their monotony can become a bit relaxing but it is definitely my least favourite part of the entire process. One of the most important, but grey hair-inducing. 

Now finally in Substance Painter, I started off with a bake. Because this piece is pretty simple and has no high poly mesh it was pretty quick. I set the output size to 2048, checked off Used Low Poly as High Poly, and turned down the Max Frontal and Rear distances.

This was definitely one of the easier bakes. For most of my other props, I changed the output size to 4096 (sometimes 8192 if I was feeling extra spicy), set some Antialiasing, and went through a lot of trial and error getting the Max Frontal and Rear distances exactly right. 

I don't know if this is just a me thing or if everyone does it, but I love throwing random smart materials on my model just to see what it looks like. Mostly just for my entertainment, but every now and then I'll put something on and realize that there are actually parts in it that I could use. Once I finished trying alien skin materials on my dock, I tested all the different wood options. Wood Ship Hull Old, and Wood Beech Veined both had parts I liked so I applied them as well as Iron Old for the nails. I gave each Smart Material folder a black mask, and using the Polygon Fill tool, switch between Mesh and UV Chunk Fill to only apply the textures to the parts I want. Using the pre-existing layers in each Smart Material, I was easily able to modify all the ready-made parameters. For the most part, it was colour adjustments, scaling, placement, balance, and height that worried about. A lot of the layers come with some kind of mask already, so having the control to adjust individual components is really nice. 

With a pretty good starting base now, I decided to use the Wood Beech Veined Smart Material as my primary texture, and the Wood Ship Hull Old for the cut ends, then hid all of my folders except Beech Veined. 

It was still looking pretty flat at this point, so I started adding my own layers and masks. I added a new Fill layer and assigned its colour and height to Wood Fibers 1. After adjusting the parameters and setting the layer to Overlay, it already had a lot more surface variation. Next, I wanted to add some edge definition. I created another Fill layer and turned off everything except colour and roughness. I gave it a black mask and ended up using the Metal Edge Wear generator to get the effect I was looking for. The last thing I did, was add two more fill layers set with very low opacity to tint the overall wood colouring and adjustable ambient occlusion intensity. 

Repeating the same process for my wood ends material and my nail material, things were starting to come together. The last thing I wanted to do was smooth the transition between my two wood types to both make it more believable, and hide any visible seams. 

DONE! Now's the easy part. Because all of my layers are easily adjustable, I grouped my three materials and duplicated them. The duplicates can now be used for any other large wood props (in this file it's my two tables). All I had to do was change the colours in each layer to make these pieces look like they were built out of a lighter wood, then change the wood grain and grunge maps around to appear different. 

With the end in sight, I exported all of my texture maps and set up a material instance in Unreal 5.

I ended up having to go back into Maya to clean up a couple UVs that were slightly stretched or out of my texture space, but they were so minor I didn't need to redo anything in Substance Painter. Because I made so many of the pieces have sharing UVs, I couldn't include any big stains or scratches in this original texture or it would either look repetitive or not cover smoothly. That will all be done with decals later :)

Report

Unconventional Lakehouse Model: (Kind of) Efficient UVs in Maya and Photoshop

Work In Progress / 18 January 2023

In the recent past my work hasn't been particularly optimized which, has resulted in a lot of unnecessary work and some ungodly large files. This is something that I've tried to be conscious of throughout this project. It's been really challenging to find the balance between optimization and maintaining detail, and is definitely varied depending on the prop and my sanity. 

Out of what I've UVed and textured so far, the wood is probably the best example of my process. Because I still wanted to make detail a priority, the plan was to use overlapping UVs positioned over a couple reusable textures for anything that had multiple of the same pieces (ie. all of the wood slats on the dock). That way, I'd only have to worry about UVing, texturing, and giving map space to a couple of pieces then flip/rotate the remaining UVs on top of my preexisting ones to fake variation. 

I started by selecting the pieces I needed unique textures for (1 long beam, 1 short cube, 2 slats for variation, and 4 nails for variation). After UVing those pieces, I created a plane and used the Insert Edge Loop tool and the Multi-Cut tool to section off the areas for my different textures. 

In hindsight, this was probably unnecessary. I thought it would be faster to texture simple rectangles on a plane and apply the finished material to my dock (and anything else that needed a wood/nail texture) in Unreal, but the seams were extremely noticeable and over all it ended up looking pretty obvious that I'd tried to take a short cut. Had it been for a small/insignificant prop, I think this would have worked and saved me some time, but the size of the dock made it hard to get away with. But I didn't know any of that yet. 

I exported a UV snapshot of just the sectioned off plane and brought it over to Photoshop. Using the paint bucket, I dumped a rough colour in each section and then outlined the sections on a separate layer. 

Back in Maya, I edited my material to use a file instead of a colour, and selected the image I'd just made in Photoshop. With that applied to my dock, it was easy to check UVs and try out different colour combinations. In total, I only textured 8 pieces of my dock, rather than all 58. If I was really smart I would have created and UVed those 8 pieces first, then duplicated them to build the entire dock but alas, smooth brain. So my next step was to unwrap the remaining 50 pieces, and fit them exactly aligned with my 8. This took a while and I had large regrets.

Using the same process, I planned to use the top half of the map space for my two wooden tables inside the boat. Because they are built with less modular and more unique pieces, using the same 'gridding off' technique wasn't going to work. I started by separating the UVs into groups based on their world positioning. For example, all of the large, horizontal flat surfaces like table tops, bottoms, and shelves were put together. Then I did the same for the sides. The most visible piece in each pile (ie. the table top) were what needed to be textured, and determined the maximum side for the other UVs to fit within. This was only applicable for the large horizontal and vertical flat surfaces, and nails on each table. All of the edge strips were done individually. 

I've made this mistake once before, and once was more than enough to learn my lesson. DUPLICATE YOUR MODELS :( With everything UVed, I combined my copy of the dock and two tables, set them to the same material, and deleted all of the faces with overlapping UVs, only keeping the ones I needed to texture. 

Now all that's left is to export this and head over to Substance Painter! 

Although it's not the most efficent, I'm happy with the balance I was able to get between optimization and maintaining detail. There's still some extra map space in the top right quadrent, so I'll probably end up fitting another prop in there later. In the next part, I will be going over the texturing process for these pieces in Substance Painter, and adjusting the overlapping UVs back in Maya to clean up/transform the modular faces so they look unique.

Report

Unconventional Lakehouse Model: Cloth Simulation in Maya

Work In Progress / 03 January 2023

I would like to preface this with: I'm probably going to redo my simulations in an entirely different way later. The method I used worked great for creating a still model, but because it technically isn't rigged, I can't use real-time effects in Unreal to animate the pieces of cloth that would move naturally with wind. For pieces like the blanket wrinkled on the mattress, having a real-time simulation doesn't matter, but for the tarps that enclose the boat, it wasn't ideal. Regardless, I'm going to go through the three different simulations I learned how to do and will potentially be making a separate post about real-time cloth simulation in Unreal at some point in the future. 


Blanket

I started by creating a plane, scaling it to roughly the size of my mattress, adding subdivisions, and raising it so it isn't touching any of the other meshes. With that set up, I switched over to FX mode and turned my plane into nCloth. If I hit play on the time bar right now, the blanket would infinitely fall, so I need to make a collision. In my case, I want the blanket to react with the mattress and the boat, so I combined the two objects it will hit and set them as a passive collider. Now if I hit play, the blanket will settle properly. All that's left is to mess with some settings and the placement to get the effect I want. 

In the Attribute Editor tab, I changed the Thickness to 0.010, bumped up the Friction, slightly increased Stickiness and Mass, changed Max Iterations to 20000, Max Self Collide Iterations to 52, and Collide Last Threshold to 0.65. 

I scrubbed through the timeline to find the frame where the blanket looked best (good folds, no clipping, completely settled) and deleted my blanket's history and froze its transformations. Now if I hit play, nothing happens and my blanket stays exactly how I want it. I did the same to the mesh I had it collide against, and then deleted Nucleus, nCloth, and nRigid from my outliner. If I go back into my Attribute Editor for either mesh, there are no longer any remnants of a cloth simulation and my blanket can be treated as any regular model. The last thing I did was select all of the blanket's faces and make an extrusion downwards to give the blanket a tiny bit of thickness. In my case, this turned the entire mesh black because it was adding depth to the wrong direction, so I just selected all of the faces again and reversed the normals. 


Pillow

To make my pillow, I started with a cube instead of a plane. Just like before, I added subdivisions, positioned it above where I'd like it to land, turned it into nCloth, and turned the mesh it will fall hit into a Passive Collider. In the Attribute Editor under the nClothShape tab, I set Pressure to 0.5. Now when I hit play, the pillow inflates and falls onto the mattress. I messed around with the same other settings as I'd used on my mattress to give it a bit more realism, making sure to increase the Stickiness so that the pillow doesn't slide out of place. 

I brought in a human scale model from Maya's Content Browser and positioned him where I'd want his head to rest, leaving room for the pillow to inflate when I simulate. After setting the human model to another Passive Collider, I got the effect I was looking for.


Tarp

This is the section that I'll probably redo differently later to make it dynamic in Unreal, but it was still a good learning curve so I'm going to include it. I started by creating planes that roughly fit over the frame I'd made. Each plane was subdivided and then using soft select and a large brush, I pushed the geometry to fit the curvature of the structure it would be attached to. Using wireframe and X-ray made it a lot easier to ensure that all of the edges were completely inside the frame geometry. When I turn my plane to nCloth and hit play on the timeline, it drops infinitely like in both previous simulations because it has nothing to collide with. This time, I want my cloth to be held up by its edges, so it has to be done a bit differently. With my plane set as nCloth, I switched to Vertex select and clicked on all of the plane's outer edge vertices, then selected the frame mesh I want it attached to and under the nConstraint menu, chose PointToSurface. 

Now when I hit play, it drops as though it's properly fastened to the frame like I want it. Just like before, I adjusted some of the settings, froze transformations and deleted history on the frame I liked, and deleted the cloth simulation tools I'd used from my Outliner. 

Hindsight is 20/20 and in retrospect, I wouldn't have done all of my simulations this way, but it was great to learn how to apply nCloth to such a variety of materials, and I can always go back and change things later. I had a lot of fun playing around with nCloth and learned a lot throughout this process. My next post will be about creating efficient UVs and trim sheets in Maya :)

Report

Unconventional Lakehouse Model: Intro

Work In Progress / 18 November 2022

Every summer, my family and grandparents pick a week or two when we rent a cottage on a lake. I am by no means an outdoorsy person and unquestionably rely on the amenities of urban life, but it's a nice reset to take some time away from wifi and the monotony of the everyday. One morning, while my dad and I were out in the canoe looking for turtles, I saw the coolest boat. It was this little blue, rusty tin can, and I loved it. We continued on, but I couldn't get it out of my head. I spent that evening thinking about what it would look like if someone were to anchor it in the middle of the lake and live there. My dad and I went back the next morning to take photos. 


Over the next couple of days, I drew my plan.

Using my drawing as an image plane in Maya, I pretty quickly blocked out the big elements. After throwing in Maya's standard human model for scale, I realized what I had didn't work at all. I used the row boat my Didi had attached his old fishing motor to as a more technical reference, and the original blue boat as the vibe. Things went much easier with proper measurements. 

I underestimated the scale of this project and had no intention of it being something that would take this much time and learning. So having just finished modelling now in November, and knowing it's still going to be a hot minute before it's completed, I'm going to document my process so my Artstation isn't dead for the next couple of months.

I've broken down my rough plan into the key parts that were/I expect will be big learning curves

1. Cloth simulation in Maya

2. Efficient UV's in Maya, to texturing in Substance Painter (texture atlas?)

3. Modifiable texturing with parameters (shortcut)

4. Clear tarp material in Unreal

5. Decals in Unreal (shortcut)

6. Water material in Unreal

7. MAYBE water physics and boat animation in unreal


I'm currently around parts 2 and 3, and will be backtracking to show the cloth simulation process. 

This is what my project looks like right now, having just completed the modelling, blocking in colours, and beginning to texture.



Report

Galaga 1981 Arcade Machine: Customizable Workflow

Making Of / 27 July 2022

I had a plan. After dedicating months to my last couple pieces, I wanted to take a bit of a break from working big and focus on getting some smaller projects done. So in my infinite wisdom, I figured making an accurate arcade machine would be quick and easy. I was wrong. As it turns out, there's a lot more to it than I realized. 

After making arcade machines in my final project last term, I knew this time I needed to work from real reference. It was the perfect excuse to check out 8-Bit Beans, a retro arcade caffe I'd been meaning to explore. Tucked away in a inconspicuously hidden room, I found it. A 1981 Galaga machine that you could easily tell had been in good use for its 41 years. It was perfect. 

Base Model

As far as the model itself goes, it's pretty simple. I did all of the building and UVs in Maya, and worked using shipping dimensions I was able to find online. The one thing that I did find very helpful during the early stages, was creating a rough trim sheet of the cabinet art so I could see where my sizing or placement was slightly off.

The screen was done in two pieces, with the TV display recessed into the cabinet, and a plane covering the gap to make the entire front look like a single sheet of glass later in Unreal.

Texturing

Most of the texturing was done in Substance Painter, using Smart Materials as starting points and modifying their individual layers and masks. I worked a lot with generators and different noise maps to give it random wear, but a lot of the grunge had to be custom made. One of the things I didn't do the last time I made an arcade machine, was really think about what parts the dust would collect on, or where tiny scratches would happen. I'd never gotten to play on a classic arcade machine until researching for this project at 8BitBeans, so it was extremely beneficial to physically be able to see what areas people would be constantly touching. 

I found all the cabinet art online, and used an AI upscaler on most of the images before bring them into Photoshop. Once I had all my images as high resolution as I could get, I'd use Photoshop to remove any backgrounds, straighten edges, and edit out light sources if need be. Then it was just a matter of saving each piece of cabinet art out as a separate PNG and applying them like stickers to my model in Substance Painter. 

Details like the tape on the coin door, and the edge wear on the control panel were hand painted and faked using height and normals. 

Glass (Substance Painter and UE5)

I can say with full confidence that I will never make glass this way again. My goal this time was to optimize my final files better while still maintaining quality, and I didn't achieve that balance with this particular part. My arcade machine was comprised of two main materials. One for the big areas like the sides and back, and one for the smaller pieces like the control panel, wheels, buttons, etc. I had my glass on the detail trim sheet thinking I would treat it as a regular material in Unreal, but use the alpha channel as a mask over a glass shader that I'd add in. 

I fought with this blueprint for two days before finally admitting defeat and assigning the glass its own material. Trying to make a material act both as a classic hard surface, and glass at the same time was not a worthwhile resource management strategy to take. Once I had the materials separated, it was much more straight forward to apply my grunge overlay on the glass without messing up the cabinet itself. 

Unreal 

Setting up the file and importing all of my work was pretty standard. Sadly translucent materials still aren't supported by Nanite so I did have to uncheck that when I brought in my model. 

Glass (UE5)

I did use the basis of my original plan in my new glass setup, incorporating the texture maps I'd previously made in Substance Painter. The Diffuse map acted as Base Colour, and a very slight Emissive. The Opacity was done using a Fresnel and parameters for the middle and edge opacity. For the Refraction, I used a lerp node to transition between the IOR strength for the edges and inner glass. Lastly, I set my Normal map, added some scaler parameters for the ORM map, and gave Specular a value of 1.

Cabinet Material

To save resources, I created a pretty standard master material that would work as a base for everything except the screen and glass. I parameterized the four maps I could potentially need (Diffuse, Normal, ORM, and Emissive), threw in some scalers to edit the intensity of particular components, and multiplied all of the textures with a Texture Coordinate and another scaler to edit any texture sizing for later when I build it a miniature set. Everything applied to my cabinet was a Material Instance.

Screen

With the exception of a couple scaler parameters, everything was done through the Emissive channel. This was unquestionably the most challenging part of the process and took me about a week to figure out. My end product was an amalgamation of concepts I liked from other artists screen work, and my own interpretation and integration. 

Scaling and Position

  • This is a pretty standard setup appending two scaler parameters as U Tile and V Tile, and multiplying the append by a Texture Coordinate, allowing me to adjust the placement and height/width of the final screen output.

Screen Jump

  • I started with creating a seed, by adding a time node with a divisible scaler parameter. By multiplying the seed into two sine nodes, I was able to get a fairly random looking flash between black and white. Using a high contrast VHS noise texture, another Texture Coordinate, a Panner, and some more scaler parameters, I stretched the texture and panned it up to show randomly sized white stripes running through the black base. After that, I used an Fmod to bridge between the sines and my new moving VHS texture. Using a noise texture, I set it up with scaler parameters and a panner to travel diagonally. I merged my Scale/Position segment using a Break Out Float2 Component node, subtracting the R by my diagonal noise, and finishing with a Make Float2 to bring the Subtract (X) and the Break Out Float2 (Y) together. 

Pixelation

  • The pixelation was also pretty straightforward. I used a scaler parameter to determine the number of pixels the end product would be converted into, plugged that into a Floor node, multiplied it by my screen jump, plugged the multiply into another Floor, and divided my new Floor by the first. 

Distortion

  • I made the distortion/interference using the same method as explained in the screen jump. It really was just a matter of running different combinations/different valued texture coordinates, panners, and sines through a smudged image of a black and white gradient. When I had a couple variations of different effects, I used the texture samples R channels to bring them together. Lastly, I created an empty texture sample with my Pixelation plugged into its UVs, and the texture plugged into my texture object (what I want displayed on the screen). Using a Break Out Float3 Component node, I connected my texture sample with all of the distortions I just made. 

Exposure Distortion

  • Using another empty texture sample, I connected its texture input to my texture object, and added my distortion (previous step) with a Float2 calling on a scaler parameter. I gave it a clamp and another scaler parameter to adjust the strength and then added the end product with my distortion again. 

RGB Pixel

  • For this component, I used a standard image of an RGB pixel, and with a texture coordinate and scaler parameter, modified its scale and opacity. 

Media Textures

Setup

Now's when things get tedious. I created a new folder called Movies in my root Content folder. If it's not put here or not precisely named Movies, Unreal can get upset. Leaving Unreal and opening a File Explorer window on my computer, I located my Movies folder in the UProject and dragged in my video file. The video file will only show up in a file explorer window and won't be visible in Unreal's content browser. Back in Unreal, I right clicked an empty area in my Movies folder and under the Media dropdown, created a Media Player. As soon as this is done, there is a popup asking to create a Media Texture out of the player, and it is imperative to say yes. With that done, I right clicked in another empty area, and in the Media dropdown, created a File Media Source.  Opening the File Media Source, I set the file path the the video I'd dropped in my Movies folder through my computer's File Explorer. I then opened my Media Player, double clicked my video file at the bottom of the screen (it's ok if it doesn't display the video right now), and in the details panel, checked off Play on Open, and Loop. I opened my Media Texture, and assigned my Media Player in the details panel. Finally, In my project settings, I searched for RHI and made sure Default RHI was set to Default. 

I'd been using DirectX 12 for another project and learned the hard way that it doesn't react well with media textures. 

Level Blueprint

In my Level Blueprint, I added a new variable, and clicked the dropdown (default is Boolean) to change its type. In the dropdown, I searched Media Player and chose Object Reference from its dropdown. 

I dragged my Media Player variable into the graph, and chose Get. By dragging the Media Player's output node into empty space, I could search Open Source and it created me a render target. For whatever reason, the Open Source node doesn't show up in the right click menu, so it has to be done this way. Because I wanted to have multiple different vides for different screens, I needed to create a sequence node. I plugged an Event Begin Play into the Sequence input, and the first Sequence output into my Open Source input. After compiling the blueprint, I was able to assign my content browser's Media Player to the media player node. Then, directly on the Open Source node, I clicked the dropdown under Media Source and selected the Media File Source I'd made in my content browser. To add more videos, I just repeated this entire process, only sharing the Event Begin Play node, the sequence input, and clicking the Sequence node's '+' to add more outputs. After one last compilation, it's done. 

Application

This is the fun part. I created a Material Instance out of the base screen material, and changed my Texture Object parameter from the still image I'd been using to test the blueprint, with the Media Texture I'd made in my content browser. Now it's just a matter of playing with the parameters I'd set up to adjust the screen exactly how I want it, and applying the Material Instance to my model.

I learned a lot from this project and really enjoyed the process. As always, there are many things that I'd do differently next time, but it was a much more technical undertaking than I'd attempted before. 


Report