Lord Hayden's Activity
Lord Hayden added a topic in 3D and 2D Art[Student Thread] Jan1ssary - Lord HaydenAlright, so today's focus is going to be getting your model and getting it ready to go into a game engine. This will require us optimizing the mesh so it's as efficient as possible in-game, as well as adding in some geometry for vertex painting and improving the shading.
Because this tutorial is mainly covering the technicalities of getting your model/s in-game, I won't be going into detail about how to do certain things, they're going to be assumed knowledge. I will tell you what we will want to achieve and the reasoning behind it. Because you already know your way around a 3D modelling program, I'll be showing you examples from the program I am most comfortable in (Blender), but the steps will be very similar.
For the tutorial I will be showing you how to optimize one part of your model. You can go in to 3DS Max and follow along with the tutorial, and then go through the rest of the model and do the rest yourself. I'm going to be walking you through the top part of the temple, circled here:
First of all, we need to look at how much geometry we have at the moment, and how we are going to cut it down before adding in our loops and bevels. One of the first things we will want to do is clean up the geometry and remove a lot of the faces that the player will never be able to see (things like the inside walls and bottoms of the boxes) We also want to make sure we're using as little faces as possible. What I did in the below image was I duplicated the mesh and optimized the geometry in a way so that it's more efficient for the game. I also removed all the inside faces that the player will never be able to see, also reducing the geometry.
The next step we will want to do is go in and start beveling the hard edges. In the Creation Engine (Skyrim), hard edges can stand out quite a bit when they're on an outside edge (like the corners of the walls) so we bevel them so give them a smoother edge. You can see below an image of the geometry before I beveled it.
These were the edges I decided to bevel to make them smoother:
And this is what the mesh looked like after beveling:
Even in the modelling program, you can see that beveling those sharp edges can really improve the model without adding in too many extra faces. I also edited some more geometry to optimize it for the game, particularly the two tetrahedrons you had on the top of the temple:
Above is the before photo and below is the after cleanup photo. What I did was I deleted the inside vertices and faces (that the player cannot see) and then merged the outside ones so it's all a part of the same mesh and connected:
And then I beveled this to improve the way it will look in-game, and then added a smoothing group to it, to achieve this result:
I think this is a good place to end the first lesson. If you have any questions please feel free to ask, I'm happy to help out. There's going to be a bit of cleaning up required over the rest of the model, particularly removing the inside faces of the model (the ones the player can't see). Posting some WIP images as you go along would be great to see how you're cleaning up the geometry, and it'll also mean we can pick up on any other errors that might pop up.
- 2 replies
- 114 views
Lord Hayden added a topic in TutorialsBasic Landscape Textures using Substance Designer TutorialWith the growing need for more texture artists/landscape artists, I decided to throw together a tutorial/student thread for using Substance Designer to make basic textures suited to tilesets and landscapes.
In the following tutorial I'll be creating a desert sand texture for Elsweyr, as well as cover how I made it, how to make changes to it, as well as just the general layout, workflows and UI in Designer. Due to the highly iterative workflows used in Substance Designer, it is very difficult to make a step by step tutorial as I make it, so I created the textures in advance and will go over the processes and nodes I used instead.
To introduce the UI to you, I'm going to start by making a simple example Substance while going over the basics. This will also introduce some of the most basic nodes you will use in the Substance Workflow.
Here's the screen you'll be greeted with upon opening Substance. From here you can find the documentation, tutorials, as well as start up new files and open recent files. It's nothing too special and I generally just close it. You can bring this back up later by going to the top toolbar under Help -> Welcome Screen.
Now, this is how I've set out my Substance Designer UI. Like many modern programs, you can change and move just about any window, separating it from the main window, etc. by dragging them around. I personally separate the 3D view and drag it over into another monitor (until it broke), allowing me to see all that finer detail in the viewport while giving myself a lot of room for my graph and 2D view.
You can easily identify the windows by the names in the top right corner of each of them. The ones you will be using the most of will probably be the Graph, 3D View, 2D View and the Parameters windows. Personally I don't use the Library often, and the Explorer doesn't have that much functionality.
3D View - This view is where you can see your material in 3D, as well as how light reacts to it. You can navigate around the mesh by holding left click, zoom by holding right click, and pan by holding down the middle mouse button. When you have a material open, you will also have a toolbar that allows you to change various material and rendering settings. I'll cover this a little bit more at the end of the tutorial.2D View - The 2D View displays the texture map of your currently selected node. You can zoom by using the mousewheel, or do a smooth, finer zoom by holding down Alt and using the right mouse button. You can also pan by holding down the middle mouse button. With a material selected you will have more options and display properties such as the texture resolution, and the ability to swap between all the output maps if you don't have a single node selected. You also have buttons to export the current image.Graph - The Graph is there all the nodes go. It works in a similar way to all the modern node editors, where you use the left mouse button to select, drag and connect the various nodes, as well as rearrange your graph. Similar to the 2D view, you can pan with middle mouse, or zoom by scrolling (or fine zoom with Alt + Left Mouse). Once you have a Substance open, the corresponding graph will be loaded up, with extra toolbars added along the top, with buttons such as zoom to selection, view info, as well as your node display settings. It also has a quick toolbar where all the most commonly used nodes are for easy access (called Atomic Nodes). By pressing space bar while your mouse is in the graph area, you can bring up the search bar where you can type in the name of a node you're after and see a selection of results (I recommend this only if you have been using Substance for a long time, as a lot about learning new nodes can be through trial and error, you won't come across new nodes if you're only searching for what you know. Stick to the library if you're a beginner) Parameters - The parameters window is where all the different options are for your selected node. This is where you can change the properties of just about whatever you have selected. There's not much else to say about this part, but it's one of the most used areas in the Substance workflow.Explorer - The explorer is essentially your file browser. When you first load up Substance, it will be empty, but as you open up new Substance files (.sbs or .sbsar), they will be added into the explorer, as well as all of their associated graphs. This is probably the least used window in Substance, and is only really used when you need to reference a graph (more about this later) or select a graph to change the properties (eg. the resolution of the texture)Library - This is where you can browse through all your different generators, effects, materials, and every other thing you might need in Substance Designer. This is where you should be searching for or browsing through to find all your nodes when you first begin with Substance Designer to know what you have at your disposal and familiarize yourself with everything.Now that we've covered the basics of the UI, we can start on our first Substance, a very quick and nasty stucco/rough plaster texture.
Click on File -> New Substance, and you'll be greeted with the following window:
Here you can select from various presets. I prefer to work in PBR Metal/Rough, so I select Physically Based (Metallic Roughness). I generally name my graph whatever that paticular graph will include, for example 'Rocks' or 'Sand'. I make sure my size and format modes are set to Relative to Parent. (So they can be changed easily later.
My new Substance will load up and I'll be greeted with my full Substance toolset:
In my graph I now have 5 new nodes, these are my output nodes (in Substance Designer 5 you'll only have 4 output nodes; no height). These nodes are linked to my 3D view, and will display whatever I plug into them. This will also create a new Unsaved Package in the explorer. When we go File -> Save for the first time, then we will be given the option to name the package/Substance. This Substance is a .sbs file and can contain multiple different graphs. If you zoom into the graph you can see that each node has a resolution and format underneath it, as well as a value. This value determines how expensive that particular node is, but because we are working towards creating bitmap textures, I'm not going to cover optimizing our textures or worry about how expensive they are to performance. (If you were using the .sbs/.sbsar to generate materials at runtime in an engine like Unreal for example, you would want to optimize your texture as much as possible)
One of the first steps I take in creating a texture is making sure I'm working in an appropriate resolution to see what details I am adding to it. Going back to our explorer, we can select the graph. You can see below where I have selected the 'ExampleGraph' graph, and the parameter window below it shows the properties I can change.
Under Base Parameters you can see the Output Size. This is where we can define the outputs of the graph. By default it's set to 0 on both the X and Y, giving our texture a resolution of 256x256. I bump up my X and Y values to 3, which brings our texture to 2048x2048, which I find the most appropriate to work in. (a value of 0 is 256, 1 is 512, 2 is 1024, and 4 is 2048, etc.)
By changing the output value of our graph, this means that any generator we create in our graph will have the same resolution by default, this also means our outputs will have that resolution.
Now that the basics of our Substance are set up, we can move over to our graph and library and start working on our Substance. For this 'My First Substance' example, we're going to want to use the generator 'Clouds 1', which is in our Library under Generators -> Noises. Find Clouds 1 and drag it over into your graph and it should snap into place on the grid. Your 2D View should also change to represent the texture you just placed into your graph, while your 3D view should not change at all (as the 3D view only shows what is connected into your Outputs by default).
Now we can use our clouds noise to generate our texture! Being a very simple example, we won't use too much in terms of nodes, just enough to get started and create some relevant outputs.
The general workflow we use when creating PBR materials in Substance involves generating an accurate heightmap first, and then extrapolating all the information we need for the other texture maps from our heightmap. I'll detail the various different maps and how they work in the glossary. We're going to be using our Clouds 1 noise as our heightmap (Yes, this is a super simple example). Since we have our heightmap, we're going to pull in a Normal node, which is found under Filters -> Normal Map in our Library. This uses the grayscale (black and white) information to generate a normal map. Now, you'll notice that the output of our Clouds 1 node was grey, and the input to our Normal node was also grey, however, the output of our Normal node is yellow. In Substance, you'll work with many different nodes, but most of the work is done in grayscale textures for outputs such as height, ambient occlusion, metallic, and roughness. Grayscale textures are shown as grey nodes and connectors in Substance, while any textures that contain color information (AKA, anything but black and white) are represented by yellow nodes and connections. If you zoom in to your outputs, you can see that these are half yellow and half grey inputs, meaning they will accept either a color or grayscale texture input.
Your Substance graph should still look pretty bare, with your 5 output nodes sitting alone, and your Clouds 1 plugged into your Normal node. From here you can go ahead and plug the output of your Normal node into your Normal Output. This should now influence your 3D view, adding some Cloud 1 bumps to whatever mesh you have loaded up (You can change your mesh in the 3D View window by selecting 'Geometry' and choosing from the drop down menu).
We're now going to load up 3 new nodes which can all be found in the Atomic Nodes library, a Grayscale Conversion, a Uniform Color, and a Gradient Map. From here we can plug the output from our Normal node into the Grayscale Conversion to create a grayscale version of our normal map. I'll then plug the grayscale output from the Grayscale Conversion into the roughness and height Output nodes, as well as our Gradient Map node. I'll then take the color output from the Gradient Map node and plug that into our Base Color. Finally, I'll plug my Uniform Color node into my Metallic Output node. You'll notice that our Uniform Color node is outputting a color map into our Metallic Output map. By single clicking on our Uniform Color, we can go into the parameters window and swap between a Color and Grayscale option, as well as select the color/value of the node. Metallic texture maps are generally single grayscale textures, so we will select grayscale, and, selecting a solid black value, plug it into our last remaining Output node.
And there you have it, your very first Substance that that could resemble something like a stucco or rough plaster material!
Next part of the tutorial is coming soon! Just proofreading and writing it as I go.
The true power of Substance lies in it's procedural material generation methods, it's iterative workflow, and the power to reference other graphs. We're going to create another rather quick material, but this time going more in depth with the capabilities of Substance. This is in no way a high quality Substance you might expect in AAA games, but it covers the basic workflow you would undertake to create a PBR material. In the end we will use my basic PBR conversion node to convert the PBR material into a tradition texture with some baked lighting, somewhat more suitable for Skyrim.
The most important step before you even get started is to make sure you have a lot of reference material for whatever kind of texture you plan on making. You can then refer back to your material when iterating on your Substance. We also want to start with our larger shapes and forms, similar to when you would sculpt something in a 3D program, and then proceed to work in the smaller details. Our final Substance is going to be some sand dunes, with smaller rocks and pebbles scattered throughout it, so we're going to start with our largest of shapes; the sand dune waves.
The Sand Dunes
The first step is to create a new Substance, which I called SandBasic. This will be the graph for our sand, containing all the height, color, normal, metal and rough maps for the standalone texture. As usual, I scale up the Output Parameters on the graph so I am working in 2048x2048 textures. Looking at my references, I can see I need to create some random waves of varying height as my basic shapes, and then refine them further to make the peaks all smooth, as though they've been blown around in the wind naturally, yet randomly.
This was the sand material I came up with for this example. It gets across the general message, and if I wanted to go back and refine this to a better standard, I can do at any time. Material breakdowns of each graph can be found in the spoiler tags.
Now that my sand is complete, I can move on to my pebbles. Before I do, I'm going to select my SandBasic graph in the explorer window and change the Output Size back to 0 (this will make the texture 256x256 again)
To create my pebble material, I'm going to start with a single pebble heightmap to use to generate the rest of my pebbles. The following material is the graph I used to generate my pebble heightmap. As you can see, I'm only using one Output node set to Height, and I deleted all the other Output nodes that are included by default. Although simple, this graph is done for now, and I can make a new graph to generate multiple stones. Material breakdown can be found in the spoilers.
This is where Substance Designer really begins to shine. After opening a new, empty graph (excluding the default output nodes), I can go over to my explorer window and find my single pebble graph. From here, we can drag the name of the graph straight from the explorer window into our empty graph window, creating a single node with the pebble we made earlier as the output. This is a graph reference, or, if it's an easier way to think about it, a graph within a graph. What I'm going to do now is drag in 2 more references of my single pebble graph, and line the 3 of them up nicely. I can now select each of these graphs individually, and, within the parameter window, change the Random Seed value. What this does is it changes the random seed used to generate each of the graphs, while still maintaining the same graph structure (all the information still gets warped, blended, transformed, etc. in the same way, it's just all the noise generators you used within the graph have been randomized, resulting in a similar, yet different output)
I then use these 3 different pebbles and use a Tile Sampler to scatter them randomly on the map, before finishing off the other outputs. Material breakdown in the spoiler tags.
One important step that I would like to highlight here before moving on is in the parameters of our Tile Sampler node. By selecting the node and looking through the parameters, we can find our X Amount and Y Amount parameters. By clicking on the graph looking icon in the top right of that parameter box (see image below), we can select the option to 'expose' them.
Now we can choose an input name for our exposed parameter, I'm going to call it pebble_count (because it influences the amount of pebbles). I do the same thing for the other parameter, giving them the same Input Name. This ensures that their values will be tied to this one value, or, mathematically speaking, it will mean X = Y.
The final step before moving on to our next graph is to select the ScatteredStones graph (the current one we're working on) from the explorer window, and, within the properties window, scroll down to the Input Parameters drop down box. There you can find the identifier you just created (pebble_count) as well as some extra details. The final step is to change the label to something we will be able to recognize, in this case for me, 'Pebbles Count'. We can now move on and create our next graph.
In a similar way we referenced the single pebble to create a scattered pebble material, we're now going to reference our original sand material and our scattered pebble material to create our final, combined material. It's as simple as creating a new graph and dragging in our two previous graphs. I then used a Material Height Blend node to blend my sand and pebble materials into one single material and linked up the outputs. You can see the result below:
Now, while we have both materials blending nicely over each other, the pebbles look a little out of place on the surface of the sand, so by using the height information from each of our graphs and the blend, we can make the texture look a lot better. It's important to think about the story behind your material (what is it made of? why is it here? how long has it been here? what has happened to it, etc.). Just for the sake of examples, lets just say our pebbles were all thrown onto the surface of the sand very recently (not really believable, I know, but lets see what we can do to work with it)
To add make it look like our stones just landed on the surface of the sand recently, I took the blended heightmap of the pebbles and sand materials, and then subtracted to sand material, leaving me with what should be a very close to accurate mask of where my pebbles are on the final texture. I then put this through a levels node to better isolate the remaining details, blurred it and inverted it, then put it into a normal map. I then used a Normal Combine node to combine the original blended normal map with my 'pebble divots' normal map, giving the impression that there are divots around where the pebbles have landed.
Now, remember those parameters we exposed in our ScatteredPebbles graph? If we select the node in our graph, we can see it has one property: Pebble Count. We can use this to change the number and size of the pebbles in our final, combined material with one slider, without having to go back into the referenced graph (ScatteredPebbles) and changing the parameters from there.
And there we have it, a materials that somewhat resembles a collection of pebbles landing in the sand. It's not the best material, but I hope that it has outlined what possibilities Substance can have for creating landscape textures. Due to it's highly iterative workflow, I could go back at any point and further edit the pebbles graph, and those changes would then carry on down each of the graphs that referenced that. One simple change to a single pebble graph would carry on down to influence this graph as well. The ability to expose parameters can also be exposed across multiple graph references too. Material breakdown for the final result in the spoilers.
I realize the end result might have become a little confusing through the process, but the main idea here is that we combined two graph references (one of which contained a reference to a reference) to create our final result, and having this ability opens up a lot of possibilities to further develop and combine many different textures and graphs. For example, if you've previously made a mud texture, but want a blend of mud and dirt, or if you have an underlying rock, but want sand to appear within the cracks, it's very simple to do and expose parameters to give you more control in your final material.
If there's any questions/critiques, please let me know. I'll be expanding a bit more on this at a later date with more in-depth looks, as well as more material breakdowns!
- 0 replies
- 183 views
Lord Hayden added a topic in TutorialsAnimated Textures in Nif Files TutorialIntroduction
To add animations to your textures, you're going to need to become familiar with 3 new nodes in NifSkope which you won't have had to deal with before:
BSLightingShaderPropertyFloatControllerNiFloatInterpolatorNiFoatDataGetting to know these new nodes don't require too much effort, as they're pretty basic on their own but contain a lot of possibilities. To get started with the example, we are going to use a quick .nif I threw together for the tutorial exported straight from the 3D modelling program, no changes or tweaks at all.
Here's our fresh .nif with the basic nodes and textures applied as you would with any other static mesh. The first changes I am going to make is to add in the new nodes we will be using to animate the texture. This can be done by right clicking in the Block List (top left) and clicking Block -> Insert.
You'll find the BSLightingShaderPropertyFloatController node under the Bethesda menu, and you can find the other two nodes under the NiF... menus. You can add these in in any order, and they should just appear in your Block List either above or below your BSFadeNode root.
Now, the first thing we need to do is organize our new blocks. I generally start with the BSLightingShaderPropertyFloatController. When selecting the block, you can see the array of variables in the Block Details panel (bottom). From here we can link this block to the others by using the number values on the right of the block name in our Block List. The block we want within the BSLightingShaderPropertyFloatController is the NiFloatInterpolator, so to do this, I would type '0' into the 'Next Controller' value. Keep in mind that when you change the position of blocks in your tree, the numbers associated with them can also change (although if they are already linked the numbers will automatically change).
Now go ahead and edit the NiFloatInterpolator node to add the NiFloatData block into it so you have a tree similar to the above image. (BSLightingShaderPropertyFloatController -> NiFloatInterpolator -> NiFloatData)
Now I'm not going to go through every tiny detail about each of these nodes, although I will cover the basics you will need to create this animated texture.
This node is where we tell the texture what is going to happen.
The major changes you need to make to this node after linking it up is to change the flags to active (click on the flag icon and tick Active). You will also want to change the frequency to 1, and your stop time to the full length of the texture loop (40 in my case). You can also change the Target to the BSLightingShaderProperty node in your original NiTriShape you wish this animation to effect, this will appear to create a second BSLightingShaderProperty within your NiFloatInterpolator, but you can ignore this for the time being. Your 'Type of Controlled Variable' is where you can select how you are animating your texture. There's a lot of different options so I would suggest exploring them yourself, but for the slow moving flow of this lava I'm going to change my texture to U Offset.
This is the most simple node, and as long as you have linked it correctly to your NiFloatData block, you're all done with this. It acts as a bridge between the FloatController and the FloatData basically.
This block essentialy controls the maths behind how the texture is going to be offset. Because we want our texture to 'flow' (or, be offset) at a steady pace, we are going to use a Linear Integration, which also means we're going to need 2 Num Keys.
I'm not going to go into depth about the maths behind it or what's possible, these functions can be Googled and researched across various game engines
Once you have filled out your Num Keys and Interpolation values, you can click on the little green icon to refresh the 'Keys' which will give you two keys, which will be our 'start' and 'end' of the linear motion. Because we want our animation to start at time 0 and an offset of 0, we keep the first key the same.
The second key is the 'end' key, which is where the animation will then go back to your starting key to loop. The 'value' is how much the texture has been offset by since the loop started. If you are using a tileable texture, you will want this value to be 1 (or -1 to move in the opposite direction), so it has gone through 1 whole 'tile' of the texture. The time is how much time has passed in the animation, which we generally want to be the same as our Stop Time we set earlier in the BSLightingShaderPropertyFloatController, to give us a nice smooth loop.
The final steps to get the mesh ready for in-game is to go into our original BSLightingShaderProperty (the one in the NiTriShapeData) and find the 'Controller' data. This is where we can link the controller and all of it's nodes to our original mesh. Fill in the Controller value and your block tree should change so you only have your BSFadeNode as your Root Node and nothing outside of it. We can then right click on our BSFadeNode and go 'Add Extra Data', adding a BSXFlags into our .nif if it didn't have one already. You'll need to edit the flags in the BSXFlags to make sure you have the 'animated' flag ticked.
The final step I usually take is use the NifSkope spell 'Reorder Blocks' which puts everything into a nice order. After that the .nif is ready to put in-game and should include your animating texture. You can incorporate multiple animated textures, as well as include NiAlphaProperties for more complicated animations. Below is a link to the example .nif, excluding the original texture files you can use to research the techniques. As always, all questions are welcome and I'll be going back through to clean up the tutorial over time. Below is a result of animating two textures with the inclusion of a NiAlphaProperty for testing purposes.
- 1 reply
- 226 views