3D Programming Fundamentals [Texture Mapping] Tutorial 7

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey everybody it's chilly here welcome back to 3d fundamentals tutorial 7 and today we're talking about texture mapping so what's deal with textures anyway why are they a thing well I mean the goal of 3d graphics is to reproduce real-life imagery with as much fidelity as possible I mean there are other goals but that's the main one right and what textures do they help us realize better fidelity with less resources so take a look at a scene like this you know you got a living room you got a carpet here now how do you render this carpet how do you render like we can look at this we can see that that's a carpet but how do you know and how do you render it if you look at a carpet up really close it's made up of a bunch of bundles of fibers and and we could model it we could model every individual fiber using you know like billions or trillions of triangles and I mean if you had infinite resources you could you know render all those triangles at a really high resolution and you would you know get something like this unfortunately we don't have unlimited resources so what we do instead is we take a picture of a carpet and then what we do is we just paint this picture on top of very simple geometry so you could represent this floor with you know a single single quad two triangles and then you could just paint this image onto those triangles repeatedly and then after you light it and everything you would get you know image that looks like this so and you would not require you know billions of triangles two triangles would do the job for you and that's the basic idea of textures right you're faking the detail by just painting over colors instead of having a bunch of different colored triangles and geometry you just have you can have some flat geometry but then you put a picture on that geometry and that picture could represent carpet or skin or grass or gravel or whatever wood texture tiles and that's how you did in the old days that's how you did it these days we've got so much goddamn texture memory that what we can do is we can just do a one-to-one painting of all the triangles and then map the texture onto those triangles so I mean you couldn't do this back in the day but now you can and it looks creepy you know it puts the lotion on its skin etc um now without textures looks boring so we want textures so the question is now how do we paint our texture images onto our geometry onto our triangles well first let me tell you how you don't do it so when I first introduced rotation and scaling to people a lot of them the first thing they try to do and I've done this myself when I was learning is they say okay I got and I know how to rotate and scale points so I'm going to roll I'm gonna have some source image some sprite and I'm going to scale and rotate the points onto that from that sprite onto the screen and then I'll get a rotated scale drawing of a sprite and that seems like it would work but when you actually do it what you realize is that you've only got a finite number of pixels right so when you take your source pixels in you for example try to scale them up you're going to be trying to cover a larger area with the same number of pixels you're going to get holes in your image it's going to look like Garbo all right well let's say you got some geometry a simple triangle and you've also got a texture which is an image that you want to paint onto that geometry you get a nice little a cactus here and so what do you do well I mean it starts off the same you're gonna draw your triangle much like you draw it if you're just doing a single solid color only instead of you know filling all the pixels with a single color you are going to for each pixel in the image here you're going to look at its center here you're going to see where that in relation to the three vertices of the triangle and you're going to reverse lookup into the texture at that point to figure out what color you should use to fill this pixel with and the way we do this is pretty simple first of all we create a mapping of our vertices of our geometry two points in our texture so now our vertices are not only containing XYZ coordinates they're also containing coordinates are inside the texture we call those coordinates UV coordinates so each one of these guys now each one these vertices in the model is going to have X Y Z and then UV all right now when you transform these vertices to screen space and you start rasterizing them you're going to get you know the points of the Centers of the pixel that you're drawing and what you can do is you can basically you can take the UV coordinates and you can interpolate them based on this point in screen space so here you're going to see you're going to get mostly the UV coordinates of the red and you're also going to get a little bit of the blue and a little bit of the green and if you mix them all together you interpolate them you'll get this point here now you guys know how to interpolate between two points right like for example when we draw this triangle we've got to split it up into flat bottom and flat top right so we split it up we find the split and we got to find this vertex point here by interpolating between this and this so you guys know how to interpolate between two vertices so if you want to interpolate between three the process is pretty similar let's say you're drawing this scanline here so you know what your Y is going to be so now you can use that to interpolate between these two vertices to get this vertex here which is going to have interpolated UV and you can interpolate between these two to get this one so you're going to have now you the interpolated one and you V interpolated two and then as you draw each of these pixels you're just going to be interpolating between these two guys so the first pixel is going to be mostly this guy then a little more of this guy a little more of this guy and is going to be mostly this guy that's lately first you interpolate between this vertex and these two to get the start and end scanline coordinates in the texture space and then you interpolate between these two guys and what that looks like in texture space is you're interpolating between this and this so you get a start that's maybe here and interpolate between this and this and you get a start that is maybe here and then as you are drawing these pixels going in this direction you are going to be looking up in your texture in this direction like this now the last thing I want to talk about before we get into the code is something called pre stepping so when you are drawing a pixel let's say we start at the let's start this is going to be the first pixel that we draw right and when you're drawing this what you're doing is you always draw based on the Centers of pixels that's how you determine whether a pixel is going to be drawn or not it's also how you determine where the lookup point in the texture is going to be so what people often do the mistake that people do is they start their rasterizer and they say okay so I'm starting at this vertex here this is going to be my start pixel so I'm going to start looking up into my texture in here but that's not correct because we're not starting drawing the triangle at this point no we're starting it drawing from this point so when we start our texture look up and interpolating we have got a step into the texture by this amount here so instead of starting from here we want to start from for example here a little bit into the textures you got to take that into account you've got a pre step based on where the center of your start pixels are where the center of the scan line is and where the center of the first pixel is in your scan line that you're going to be drawing so we'll see that in the code in a second all right let's take a look at the code it's the tutorial seven 3d fundamental stuff on the github I'm going to be looking at a lot of the changes and might not go over all of them so make sure you look at this code yourself and review it make sure you understand it I mean the best would be if you try to code it up yourself but hey not everyone got time for that but if you're not at least looking at the code I don't know I know what to say to you man so first things first we added a new file we added a new scene obviously because you know we want to show off some new but we also added a new utility file Tex vertex and the reason for this is because of course now our vertices don't just contain positions they also contain texture coordinates we can't just put a vector E and that's the vertex we've got to have a more complex vertex type that contains two coordinates one for the position one for the texture coordinate and I've also added a little utility function that interpolates between two texture vertices so it interpolates both the position and the texture coordinate and the way I do this is I've also added two vector in back three I have added a function to interpolate two vectors just makes the makes the syntax a little nicer indexed triangle list now instead of doing Veck three it's going to use templated type so now we can have any kind of vertex that we want textured vertex or just a simple vector E if we wanted and that is going to be reflected in the cube for example now well here in the constructor we're also putting texture coordinates and I'll get I'll get to that in a second how we map that but yeah now we have to set up the texture coordinates for every vertex and here now get let me see here get lines is basically the same get triangles now is going to return index triangle has changed its now templated so it returns index triangle list of x3 so just get normal triangles get textured triangles is going to return a index triangle list of texture vertices so that's how that works not too complicated the real magic is going to come in in graphics dot cpp well first let's take a look at graphic stage what we added was we added a interface function drop bangle tax and that guy is going to take you know three textured vertices and it's also going to take a surface that's the actual texture ah now from this front-end function it's going to be calling you know flat top and flat bottom same deal only for texture stuff for texture stuff and what else so now graphics dot H this is where this is where the magic happens right now what I'm going to do here is instead of comparing to previous because there is nothing in previous right we're just adding new functions what I'm going to do is I'm going to go to graphics dot CPP if I can can find it and then I'm going to drag a window down here so we can compare top and bottom so we've got draw triangle and let's see if we can find draw triangle text there it is draw triangle text so let's compare these two see how it's different in fact the top level function doesn't change almost changes not at all same thing here we're creating some pointers so that we can reorganize the vertices we can order them and we're doing the swapping the only difference is now for this one the vertices are just vector right for triangle it's just vectors actually vector E but you know polymorphism and that so all we do is we go vector Y you know vector Y and then down here vector X but here because we have multiple coordinates for each vertex we got to specify which one one so we go vector position Y you know here vector position X but other than that it is all exactly the same it's all the same you can verify that for yourself we find the alpha split that is the same here we are calculating the interpolation with some simple vector math here because we can't use simple vector math we don't have vectors we have vertices we've got to use the interpolate to function that's why I created it make this line a lot simpler instead of having to interpolate the texture and then the position separately we can do it all in one line with the interpolate to function and then down here it's again the same deal so basically drop the top-level interface function almost exactly the same all right now let's take a look at the meat here the flat top and flat bottom rendering functions to start off basically the same again because we have position and texture coordinates we got to specify but other than that it's the same thing we calculate a slope we calculate the start and the end scan lines and here is where things get a little different in it texture coordinate edges so we are now initializing the texture coordinates that we are going to be interpolating across the triangle when we draw it on the screen so we have edge left edge right and bottom and those are going to correspond to this vertex this vertex and this vertex but texture coordinates are in texture space so we're better off drawing them over here so we got left right and bottom we initialize those guys to these positions in texture space now the next thing we do is we calculate texture coordinate edge unit step and what that means is well if you look at the map here we're looking at the change in texture coordinate on the left side and the change on the right side for every change and unit change in Y in screen space so basically what that means is take this vector here and texture space and this vector here in texture space and divide it by this distance this Y distance here in screen space and what that will tell us is that'll tell us well basically you know for every one step in Y how much are we going to step on the left and how much are we going to step on the right edge of the triangle in texture space that's what this is telling us so that's edge step el and edge tip are now we can use that to do our texture coordinate pre step so we take what is this we take the Y start plus 0.5 that gives us the the y-coordinate of our starting pixel scanline we subtract the actual position of the Y position of the vertex and that will give us the difference between the center of our starting pixel and our vertex and we multiply that by the edge step so we get our pre step so what that is doing again in nice pretty pictures for you is well if we're going to be drawing this the first first pixel that we're going to draw rasterize is this one here right so this is not exactly on the vertex so we're going to have to step by a little bit here this Y distance so we multiply that by this edge step here to figure out where on the texture we're going to be for a pre step so we pre step along these left and right lines here so we're adding two edge el and edge are so agile Najah were originally at the vertex points and we're pre stepping them in a little bit based on the difference between the start scan line y and y of the vertex now in these next values here which is initialized in some constants that will be useful for us and they're mainly used for clamping to make sure we don't go outside of the bounds of our texture when we're doing a texture lookup so we just initialize texture width and height by getting the width and the height of the texture surface and then we initialize the clamping of X as the texture with minus 1 and the texture height minus 1 because we don't want to go beyond those texture coordinates we're going to be reading outside of the memory that we have and then we start our scanline loop here just like in the original one we loop from wise start to y end here we're also looking from Y I start to Y end but well not only incrementing y we're also incrementing the texture coordinate for the left and the texture coordinate to the right but we're incrementing it by the step left and step right because we're stepping by one and step left and step right is how much the texture coordinate changes for everyone why step so by adding this and this to our left and our right what we're going to be doing well basically we're drawing scan lines like this right running from left to right and so this is our pre step for left and our pre step for right every every y scan line we're just adding a little bit to the left and the right and we're marching down like this so as we draw these scan lines left to right on the screen we're going to be looking up into the texture along these lines here between the left and the right start points here now again we calculate the the X start let me think you're starting in points yeah so the X start and the x end again based on pixel centers with our fill rules and we do that here again no change and no change with the ceiling but here's where the change happens because now we've got to calculate our texture coordinates we have to pre well first of all we have to have to calculate the step moving one in the X direction now for every one that we move in the X direction in screen space for every one in this space how much do we move let me just get a different color here how much do we move in texture space so we calculate that by basically taking this vector from the start from the left to the right on texture space and we divide it by this distance here in screen space and that gives us how much change in texture space we get for every change in screen space in the X and then we use that to calculate the pre step so I mean if we're starting for drawing this triangle here we're drawing the scanline let's say we start with this pixel then we're going to have to step in by this much meaning wrap the step in by this much so we calculate the unit step in the scanline the basically this step in texture coordinates and then we use that to calculate the priest into the scanline once we've got the pre step it's basically the same idea as we had here we're going to loop in the X we're going to add X and we're also going to add the scan step to the texture coordinate now we've only got one thing to add right because in Y we've got the left and the right edge but now we're just interpolating across the scan line so there's only one thing to add for every iteration here and then we do the put pixel right except it's just x + y except instead of putting in just a fixed color we are going to look into the text recorded so we call texture the surface get pixel and then we look into it now this is a little strange first of all you might be wondering why were cap where we're multiplying the texture coordinate by the width of the texture and this is something is an important part of texturing so talked about pixel coordinates in direct3d already so for textures we usually specify the coordinates in the texture in normalized space meaning that one is going to be the very bottom or the very right of the texture and zero is going to be you know the top left hand corner so 0 0 is top left 1 1 is the bottom right so 0.5 0.5 is smack-dab in the middle of the texture and there are reasons for why we do this you can specify both ways in direct3d but most of the time we use UV coordinates going from 0 to 1 and and that's what we're going to be doing in the 3d engine that we're building so when we actually do the get pixel we've got to multiply the normalized coordinate by the width of the texture to get the actual pixel coordinate in the surface so we do that we get the pixel coordinate now we want to make sure that we don't go outside of the texture so we don't want to go beyond you know the last pixel in the texture so what I'm doing here is I'm going Steadman and I'm making it so that it's never greater than text X so this value is bigger than X here it's just going to take X and it's the same thing for Y and the reason why we do this is because with some floating point air it sometimes goes outside of one to be perfectly complete I should also have a stayed max here and make it so that it never goes less than zero but I found that I don't really need that it doesn't cause any problems so I've emitted it here but in general this is texture clamping and it's one way of drawing textures we'll see another way very soon but yeah this is how we draw our and it's basically the same idea for draw flat-bottomed there's not much change here you can you can examine it yourself if you're interested and so let's take a look at how how that looks on the screen so if we tab through our scenes here we get to what I like to call saurons butthole and here it is in all its glory beautiful I mean there it might look a little weird it might look like his buttholes puckering just a little bit well just pay that no mind for now we're gonna pretend like that's not a thing so yeah here you got your textured cube looks pretty sweet now you might be wondering why is the top and the bottom like all like up why why is my all jacked up here and the reason is because the limitations of how we are representing this cube and how we can map the textures so let's take a look again at the cube itself where is that all right well here is our model of our 3d cube now our cube has eight vertices and those vertices are being shared by a bunch of different triangles so if we want to put a texture on let's say this face here what we can do is we can map so this corner here is going to map to this point on the texture which is going to be you know 0 0 and the same for this one is going to map here so I'm going to map here and this one is going to map there and if we do that then we're going to get a good old texture do drawn on here great well what about this face well what we can do is this we've already because these guys share vertices we can't change this one for this face so this one has now got the map to here and this one has got the map to here we've already set that so we can't have it going left to right again but what we can do is we can flip it so now we can map the right corner to the left of the texture and this right corner to the left of the texture and what we'll get is we'll get the eyeball basically reversed it'll be mirrored in the x-axis so if you had an arrow pointing to the right in this one it would now be pointing to the left but you'd still get your saurons butthole would still look good right and you could do that for these four faces here but the problem is if you do that you've now set the texture coordinates for all the vertices they're all set what happens for the top and the bottom well it's going to look like this right you're going to have your goddamn red and blue and that's it so you're only going to have your your vertices for the top are all going to map to either this one or this one that is not going to give you the full texture that's only going to give you this top line and that is what you are basically seeing in the image you're just seeing the pixels of the top line interpolating across here and it's a diagonal pattern because this one is the same as this one and this one maps to the same point of this one so you get this kind of diagonal striation pattern but you're not going to get the texture image because we our hands are tied right all of these all of these vertices are shared and they're fixed so once you set the images for the sides you got you've got no choice you're stuck with this for the top and the bottom it's no good and we're going to solve that problem a little later but first off let's do a little bit of improvement on our texture during code so one thing that we can notice with our triangle texturing code now is let me see here let me just see we got draw flat top triangle alright so what we're doing is basically in a texture drawing code here as we have it so far we're taking our normal triangle drawing code where we loop through the X's and Y's and then we're interpolating texture coordinates during that process but when you are drawing a triangle you could also think of it as interpolating let me just get some up here you can also think of it as interpolating not only the texture coordinates but also the coordinates in space themselves are kind of being interpolated we're treating it as a loop and we're calculating the slopes and everything but you can also think of it as interpolating between these coordinates in space and if we do it like that we could actually unify our system so instead of having our loops and calculating our slopes and I start on our endpoints we could just have it as interpolating x and y and interpolating U and V unify it all together make the system a little sexier and that's what I do here so here instead of calculating the slopes for you know the coordinates in screen space what I'm doing is I'm calculating the change in all the vertex for all of the vertex coordinates for every change in Y so not only the change in U and V but also the change in X and the change in Y for every change in Y which should be 1 right that should just be the same and so now we are interpolating the whole vertex not just the texture coordinate by the way I forgot to mention it but in order to enable us to perform all these operations on texture vertices when I what I ended up doing is I ended up adding a bunch of operators to the texture vertex class so now we can treat it as a mathematical type and do all sorts of you know interpolation type bullshit's on it all sorts of operations on the entire vertex that work on the texture coordinate and on the space coordinate simultaneously and you see here that actually removes a bunch of code and makes our code shorter so we create edge in turbulence and that corresponds to here creating the the texture coordinate edges and then we calculate the start and the end scan lines that's mostly the same and then we do the interpolant pre step so now we're not only please stepping the U and V we're also pre stepping the X and then this is the same and then here we're not calculating the start and the end X based on the slope the start and the end X is just going to be the interpolant position X minus 5 ceiling so we don't have to use the slope to calculate to start in the end that is included in the interpolant and then we just do the the scanline stuff here what is this oh here here we're actually only for the scanline we're only interpolating the texture coordinate we're not interpolating the X and the y because that's all now going to be fixed by the loops there's no sense in interpolating that stuff so here we switch to just interpolating the the texture coordinate and and we here's the pre stepping of the texture coordinate so this is the interpolant for the texture coordinate going across the scan line and yeah you take the texture coordinate of the left hand side edge zero is the left hand side and we you know we pre step into that and then that is what is going to get added to in the loop so we unify the interpolation so let's now we're now interpolating both the screen coordinates and the texture coordinates and we're no longer using slope calculations for every scanline now we can do that for the flat bottom again and then what we can notice is the flat top and the flat bottom algorithms they're almost exactly the same they only have a little bit of difference between them so what I did is I factored out all of the parts that were the same and I put that in its own function so now what we have is we have a draw flat triangle texture and then we have draw flat top and draw flat bottom so draw flat top and bottom will do the parts that are different and then they will both call draw flat triangle which does the common parts so flat triangle takes a few more parameters it takes the delta for the left-hand side that's Delta V 0 Delta vertex 0 the Delta for the right-hand side and it also takes the interpolator for the right-hand side because that differs between these two cases so it has to be decided in these functions here so now we see all that draw flat top triangle Tex does it calculates the D vertex over dy the deltas and it calculates the right edge interpolant which is just going to be v1 right and then it calls draw flat triangle texture now draw flat bottom again it calculates the deltas and it calculates the the right edge which is v-0 notice that that's different and this one is v1 and so that is why we have to separate that out and pass that in to draw a flat triangle but once we have once we have those parts calculated out draw flat triangle is going to do the same that it always did before and except now we have it in a single function instead of two separate functions that are almost identical and that's better for code maintenance and it's just it's good so now that we have our triangle drawing routines I check string routines all refactored insects aside we can add a little bit more features to the system so up until this point we've just been doing what is called clamped texture rendering and we haven't been repeating textures at all it's been this deal here oh by the way in this next set of changes I added a thing where it outputs the name of the current scene to the window here the debug window so right now our textured cube butthole Sauron clamped dimensions one so it's just one by one filling fitting the cube now if I go to the next one here we've got clamped but I've got two so the texture coordinate for the left here is now zero this is going to be zero zero and this one's going to be two zero so what happens is it reaches one and then when it goes beyond one it just gets clamped to that and it just repeats it just smears out those last the last pixel and then you get this kind of pattern here so that's what clamp looks like when your texture coordinate goes beyond the texture it just clamps it like this now what happens if I instead of clamping I wrap and I'm not talking about M&Ms magnum opus rapgod here I'm talking about well the texture coordinate exceeds one it will wrap around back to zero and thus it will repeat and we will get something like this this is what texture wrapping looks like and something like this can be used to you know for example the example I gave at the beginning of video to texture a floor with some carpet you can have a repeating texture it looks kind of dumb what you know the butthole is sauron here's what here's it with texture coordinates 6 so now it's going from 0 to 6 and we're getting 6 repetitions in the X and the y but yeah so in order to do the texture wrapping I add a new set of functions so we have draw triangle text now we have draw triangle text wrap and again we've got you know flat top flat bottom and just normal one these are the implementation functions and the way that they looked is they're not they're almost exactly the same except for one little difference and that little difference is instead of doing Steadman we do state f mod modulus so modulus will mean that you know if we reach for example the value of one it will wrap back down to zero and likewise if we wrap if we go into like negative three it will wrap around to zero point seven but yeah the other stuff is exactly the same as before and this is what gives us text wrapping now let's go back and address that problem of texture mapping the top and the bottom so like I said because all of these faces share so many vertices we get stuck not being able to texture every face we map this one to you know zero zero zero one zero one one zero one like this it's going to give us problems now what we can do is we can actually unfold the geometry a little bit and break the basically break the welds between the sharing of vertices between some of this geometry so now like here we have the texture here 0 1 and I'm putting you know 0 here 1 here so Y is going to the right whereas Y is going up here it's gotta tilt your head a little bit but we can unfold this cube and it will make a shape like this and if we do this now the textures are independent enough that we can texture the top and the bottom and there are a number of ways we can do that we can make it so that the share vertices and are mirrored so for example if this arrow is pointing this way here it would point this way here and it would point this way here and this way here using our texture clamping system we could do this now another way you could do it is with that texture wrapping so if we said that this was 0 0 here and this is going in the Y direction this would be 0 1 2 3 4 so this will be 0 4 and here we could say this was 1 1 and so that would mean that here this would be 2 1 and likewise this one would be negative 1 1 and you get the idea so and then in this case they wouldn't be you know mirrored they would all be facing the same direction which is nice so you could solve that problem with texture wrapping or texture clamping but you have to brake you have to make some of these vertices independent you can't have perfect sharing of vertices and this is going to increase the number of vertices in your model here we had 8 in this one we have how many here we have 14 so and if we would have split it up so that every face was an independent square we would have 6 times 4 24 vertices so the more independent you make your vertices the more obviously the more work you're going to have to do to render them but you're also going to have more flexibility when it comes to texturing them so here's the original texturing scheme you know 0 1 1 1 0 0 1 0 for the 8 vertices now when we unfold the cube and do the same thing it's the same idea 1 0 0 0 etc but now we're doing it for 14 vertices we got more vertices to work with and if we unfold the cube but we do wrapping now we can see a little difference here now we got coordinates like 1 3 1 4 etc negative 1 1 so again 14 vertices but now we're wrapping and that will give the jamshil there'll be no mirroring anymore they'll all have the same orientation and if we tab through we can see all the different stuff we've got here weird X shaped textured that's wrapping here is folded texture clamped and you can see now we've got texturing on all the surfaces folded texture wrapped and again it's texture on all surfaces if you look really closely you can probably tell that one is mirrored and the other is not mirrored but we're not going to we're going to go into that level of anal-retentive Innes and what else do we got here and then we go back to the start alright so that's all I did for that one now we can take things a step further because now that we've unwrapped the texture instead of repeating a pattern on it we can create a skin for the geometry now and now that we've unwrapped the geometry I mean we can create a skin for that geometry that is the same shape as the unwrapped geometry and then we would just map it so that the points on the on the triangles map to points on this texture and when I did this code for skinning the cube I was super lazy so what I did was I copy and pasted the code for the unfolded wrapped texture you can see here it's got the coordinates going to 0 to 4 negative 1 to positive 1 I took these ones and then I just divided them by the dimensions of the texture so I took the U I add one to shift it over because we had negative ones and then I divided by three and then I take the V and I divide by four and that converts it to textures in this space here and it saved me some work which I like so now we can provide a texture that uniquely skins all of the faces of the triangle and that is going to look like when I just get to it here wrap cube here we go we've got the dice here's dice what is this and we've also got a weird office scene so yeah now we can skim the are and it's basically the same idea just a little bit different no repetition this time everything is uniquely identified in the texture now remember I said I was going to tell you the advantage of using normalized coordinates for your textures so let's say you've got two textures it's the same image but one is going to be a much smaller resolution so high resolution image low resolution image this one's maybe 400 by 400 and this one is maybe 100 by 100 now if you specify your texture coordinates as texels so this would be 0 0 this one would be you know like 400 or 399 0 etc this coordinate these mapping would work for this texture but if you tried to switch to this texture it would obviously be bad it would be going way outside the texture but if you map normalized there you know 0 0 1 0 1 1 0 0 it will work for both of these textures you can switch between them and you don't have to change the texture coordinates so you can dynamically switch between the different levels of detail different texture qualities and you don't have to change in your texture coordinates because one always means you know the edge and zero means the other edge and it doesn't matter the size of your texture so for example take a look at this one we're texturing it with a high quality texture but if I hit tab now we're in the low quality one hit shift tab back to the high quality and it's the exact same texture coordinates here I'm just using the same texture with different resolutions one more thing because I didn't give a really good example but here I've got the repeating texture it looks kind of dumb but if you replace it with a seamless texture like a wood panelling you can see it looks it looks pretty cool actually some bad well ignore the top in the bottom part but yeah this is what that texturing looks like repeat wrapped texturing with a proper seamless repeating texture and that's it that's all the code that I did for this tutorial all covered that my friends is texturing now there are other things that we could talk about I'll just so if we take a texture like this and we zoom in on it really far we see that it gets very pixelated usually you don't want that pixelated look so what we do is we do something called bilinear filtering normally we just take the basically the closest pixel and we use that when we're filling the screen but with bilinear filtering is what we do is we actually average we do a weighted average between the four nearest pixels so the sampling point here is see we are going to average between you know C 0 1 C 1 1 C 0 0 and C 1 0 to get a and B and then we're going to average between a and B to get C that's how you calculate bilinear filtering that's a setting that you have when you're rendering in direct3d or OpenGL but we're not going to we're not going to do that like I said in the beginning of this series we're not worrying about the aesthetics yet we're getting the basics down so we're not going to do bilinear filtering there are other kinds of filtering technologies bilinear tends to deal with what happens when you magnify things what it looks like there are things like mipmapping and anisotropic filtering and these tend to deal with what happens when you shrink and what happens when you shrink it at a different ratio in the X and the y and obviously the more of this you use the better your ship is going to look but I'm not going to deal with those details in this series I might take a look at it in the actual hardware 3d series basically the way that mipmapping works is instead of just storing the texture you also store versions of the texture that have been sized down and well and I isotropic also stores versions that have been sized down in only one court only one access X or Y and that gives you you know very nice scaling when you scale down for example here's what happens when you don't have mid mapping and when here's what happens when you do have MIT mapping it's a lot smoother right when you're scaling small but yeah that's texture mapping and it's a very important concept not only for the texturing for the mapping colors onto your geometry but there are other things that you map as well when you're rendering 3d graphics like you have normal maps that actually map the surface geometry the directions in which the surface is facing basically bumps on the surface and those are normal maps and you map them to pixels on the screen the same way that you map texture maps to pixels on the screen here's an example of effective use of normal mapping here's a model with 6000 polygons here's a model with 6 million you can see a lot more detail on the wrinkles and here is a model with again 6000 but it has a normal map and the normal map creates the wrinkle detail without blowing out your polygon count so yeah this idea of mapping and reverse lookup and interpolation very important and it comes up all the time so I encourage you to you know download the code that I've made here look over it yourself make sure you understand the concepts because they're pretty important kind of a big deal and as always if you have questions ideas discussion hit me up on the discord hit me up on the forum and you know we can talk it out it'll be fun but that's it for today I hope you enjoyed the video if you did please click the like button it helps a lot and I will see you soon with some more 3d fundamentals [Music] and and
Info
Channel: ChiliTomatoNoodle
Views: 15,194
Rating: undefined out of 5
Keywords: perspective, 3D perspective, 3D projection, perspective divide, DirectX, Direct3D, D3D, opengl, 3d programming, 3d graphics, 3d game, lesson, how to, C++, guide, code, tutorial, coding, windows, visual studio, game development, chili, chilitomatonoodle, triangle, texture mapping, texture map, texture
Id: UaOJxtWxICc
Channel Id: undefined
Length: 47min 24sec (2844 seconds)
Published: Sat Jun 10 2017
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.