GAM531 DPS931 – Week 12 Textures and Samplers
Actor Composition Actor Mesh Material Shaders Textures Vertex Buffer Index Buffer Vertex Format Material Shaders Uniform Buffers Blend States Textures Samplers
What is a Texture? 2 x 2 pixels 265 x 265 pixels 26 x 26 pixels Red | Green | Blue | Alpha Red | Green | Blue SF_4X4BYTE_FLOAT SF_4X1BYTE_UINT SF_3X4BYTE_FLOAT SF_3X1BYTE_UINT
How Do We Make Use of Textures? [ 0, 10, 0 ] [ -7, -7, 0 ] [ 7, -7, 0 ]
How Does The Texture Map to The Object? UVW Mapping Class Vertex { [ 0, 10, 0 ] Vector<> pos; [ 0.5, 0 ] Vector<float,2> uv; [ 0, 0 ] [ 1, 0 ] }; [ -7, -7, 0 ] [ 7, -7, 0 ] [ 0, 1 ] [ 1, 1 ] [ 0, 1 ] [ 1, 1 ]
Rasterization And Interpolation? [ 0, 10, 0 ] [ 0.5, 0 ] [ 0, 0 ] [ 1, 0 ] [ 0, 1.5, 0 ] [ 0.5, 0.5 ] [ -3 , -2, 0 ] [ 0.28, 0.29 ] [ 0, 1 ] [ 1, 1 ] [ -7, -7, 0 ] [ 7, -7, 0 ] Texel [ 0, 1 ] [ 1, 1 ]
What Types of Textures Are There? 3D Textures 1D Textures 2D Textures Width (U) Height (V) Height (V) Width (U) Depth (W) Width (U)
Where are Textures Defined? Image Files Custom Textures Render Targets auto a = newTex2D(“custom”); a->initCustom(2, 2, SF_4X4BYTE_FLOAT); float t[] = {0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f}; a->fill((byte*)t, sizeof(t));
Programming Textures to Load From File int w, h, c; unsigned char* data = SOIL_load_image(filename, &w, &h, &c, SOIL_LOAD_RGB); glGenTextures(1, &textureID); dim = GL_TEXTURE_2D; glBindTexture(GL_TEXTURE_2D, textureID); switch(c) { case 1: iFormat = GL_LUMINANCE; format = GL_RGB; break; case 2: iFormat = GL_LUMINANCE_ALPHA; format = GL_RGBA; break; case 3: iFormat = GL_RGB; format = GL_RGB; case 4: iFormat = GL_RGBA; format = GL_RGBA; break; } type = GL_UNSIGNED_BYTE; GLint maxTextureSize; glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize); glTexStorage2D(GL_TEXTURE_2D, intLog2(min(w,h)), iFormat, w, h); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, format, type, data); glGenerateMipmap(GL_TEXTURE_2D); SOIL_free_image_data(data); D3DX11CreateShaderResourceViewFromFile(dev, filename, 0, 0, &texture, 0); //zeroes are load options, pump thread, hresult
Programming Custom Textures D3D11_TEXTURE1D_DESC desc; ZeroMemory(&desc, sizeof(D3D11_TEXTURE1D_DESC)); desc.ArraySize = //number of arrays (1 usually) desc.BindFlags = //how the texture will be used desc.CPUAccessFlags = //how the CPU can access desc.Format = //color format (use translation) desc.MipLevels = //number of mip maps (more later) desc.MiscFlags = //other flags (set to 0) desc.Usage = //dynamic for custom meshes desc.Width = //the width in texels Dev->CreateTexture1D(&desc, 0, &tex1d); Dev->CreateShaderResourceView(tex1d, 0, &texture); //This is only for 1D Textures glGenTextures(1, &textureID); dim = GL_TEXTURE_1D; glBindTexture(GL_TEXTURE_1D, textureID); //Translate format iFormat = _glTranslateFormat(fmt, format, type); glTexStorage1D(GL_TEXTURE_1D, 1, iFormat, size); //This is only for 1D Textures
Binding Textures to Shaders //bind to fragment shader con->PSSetShaderResources(slot, 1, &texture); //bind to vertex shader con->VSSetShaderResources(slot, 1, &texture); //slot is the memory slot in the shader the //texture will be associated with, 1 is the number //of textures to bind glActiveTexture(GL_TEXTURE0 + slot); glBindTexture(dim, textureID); //OpenGL does not require separate binds for each //shader type, dim is the type of texture to bind
Filling Custom Textures D3D11_MAPPED_SUBRESOURCE sub; con->Map(tex1d, 0, D3D11_MAP_WRITE_DISCARD, 0, &sub); memcpy(sub.pData, data, size); con->Unmap(tex1d, 0); glBindTexture(GL_TEXTURE_1D, textureID); glTexSubImage1D(GL_TEXTURE_1D, 0, 0, size / texelSize, format, type, data);
Texture Samplers Texture Sampler defines how texels will be sampled from a texture to be applied to geometry in the world
Minification and Magnification [ 0, 0 ] [ 1, 0 ] [ 0, 0 ] [ 1, 0 ] Interpolated UVs [0,0] [0.1,0] [0.2,0] [0.3,0] [0.4,0] [0.5,0] [0.6,0] [0.7,0] [0.8,0] [0.9,0] Texel Coords [0,0] [0.05,0] [0.1,0] [0.15,0] [0.2,0] [0.25,0] [0.3,0] [0.35,0] [0.4,0] [0.45,0] [0.5,0] [0.55,0] [0.6,0] [0.65,0] [0.7,0] [0.75,0] [0.8,0] [0.85,0] [0.9,0] [0.95,0] [ 0, 1 ] [ 1, 1 ] [ 0, 1 ] [ 1, 1 ] 20 x 20 texels Texture 10 x 10 pixels Geometry (clip space) Point Sampling
Texture Filtering [0, 0, 0] Point Sampling (Sample Once) UV = [0.2,0] [ 0, 0, 0 ] * 1.0 [26,26,26] 0.2-(1/3)/(1/3)=0.1 [ 0, 0, 0 ] * 0.9 + [255,255,255] * 0.1 Linear Sampling (Sample Two Closest, Average) UV = [0.2,0] [26,26,26] ~Equation above, but in 4 directions Bilinear Sampling (Sample Four Closest, Average) UV = [0.2,0]
Texture Address Modes Wrap Mirror Clamp Border UV[3.4,2.1] = Texel[0.4,0.1] UV[3.4,2.1] = Texel[1.0,1.0] UV[3.4,2.1] = Texel[0.6,0.1] UV[3.4,2.1] != Texel[*,*]
Texture Samplers Revisited
Mipmaps 512 x 512 256 x 256 128 x 128 64 x 64 32 x 32 16 x 16 8 x 8 4 x 4 2 x 2 1 x 1 1024 x 1024 Geometry 280 x 280 Geometry 80 x 80 Geometry
Texture Filtering With Mipmaps Trilinear Sampling (Sample Four Closest On Two Closest Mipmaps, Average) Point Sampling (Sample Once) Linear Sampling (Sample Two Closest, Average) Increases granularity of the scene, removes sudden changes in texture quality Bilinear Sampling (Sample Four Closest, Average)
Anisotropic Filtering 512 x 512 512 x 256 512 x 128 512 x 64 512 x 32 512 x 16 512 x 8 512 x 4 512 x 2 512 x 1 256 x 512 256 x 256 256 x 128 256 x 64 256 x 32 256 x 16 256 x 8 256 x 4 256 x 2 256 x 1 128 x 512 128 x 256 128 x 128 128 x 64 128 x 32 128 x 16 128 x 8 128 x 4 128 x 2 128 x 1 … 2X Anisotropic Filtering
Anisotropic Comparison
Programming Texture Samplers glGenSamplers(1, &samplerID); glSamplerParameteri(samplerID, GL_TEXTURE_WRAP_S, um); glSamplerParameteri(samplerID, GL_TEXTURE_WRAP_T, vm); glSamplerParameteri(samplerID, GL_TEXTURE_WRAP_R, wm); glSamplerParameterf(samplerID, GL_TEXTURE_MAX_LOD, xl); glSamplerParameterf(samplerID, GL_TEXTURE_MIN_LOD, nl); glSamplerParameteri(samplerID,GL_TEXTURE_MAG_FILTER,g); glSamplerParameteri(samplerID,GL_TEXTURE_MIN_FILTER,n); glSamplerParameterf(samplerID, GL_TEXTURE_LOD_BIAS,lb); glSamplerParameteri(samplerID, GL_TEXTURE_COMPARE_FUNC, cmf); glSamplerParameterfv(samplerID, GL_TEXTURE_BORDER_COLOR, bc.data); if(GLEW_EXT_texture_filter_anisotropic) { GLfloat mA; glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &mA); if (ma > maxAnisotropy) ma = (uint32)maxAnisotropy; glSamplerParameterf(samplerID, GL_TEXTURE_MAX_ANISOTROPY_EXT, (GLfloat)ma); } D3D11_SAMPLER_DESC sd; sd.Filter = //Texture Filter for min/mag/mip sd.AddressU = //Address mode for the U coord sd.AddressV = //Address mode for the V coord sd.AddressW = //Address mode for the W coord sd.MipLODBias = //Mip’s Level of detail bias sd.MaxAnisotropy = //Max level of anisotropy memcpy(sd.BorderColor, bc.data, sizeof(float)*4); //Copy in the color value for the border sd.MinLOD = //Minimum Level of Detail sd.MaxLOD = //Maximum Level of Detail sd.ComparisonFunc = //Compares sample data dev->CreateSamplerState(&sd, &sampler);
Binding Textures to Shaders //bind to fragment shader con->VSSetSamplers(slot, 1, &sampler); //bind to vertex shader con->VSSetSamplers(slot, 1, & sampler); //slot is the memory slot in the shader the //texture will be associated with, 1 is the number //of samplers to bind glActiveTexture(GL_TEXTURE0 + slot); glBindSampler(slot, samplerID); //OpenGL does not require separate binds for each //shader type
To Do Finish up work on engine enhancement Read this week’s lab Read this week’s notes Re-implement OpenGL Texture and Sampler functions