Cycles: Adding native support for UINT16 textures.

Textures in 16 bit integer format are sometimes used for displacement, bump and normal maps and can be exported by tools like Substance Painter. Without this patch, Cycles would promote those textures to single precision floating point, causing them to take up twice as much memory as needed.

Reviewers: #cycles, brecht, sergey

Reviewed By: #cycles, brecht, sergey

Subscribers: sergey, dingto, #cycles

Tags: #cycles

Differential Revision: https://developer.blender.org/D3523
This commit is contained in:
Stefan Werner
2018-07-05 12:37:52 +02:00
parent cd17b32583
commit 4d00e95ee3
13 changed files with 198 additions and 18 deletions

View File

@@ -35,13 +35,13 @@ template<typename T> struct TextureInterpolator {
static ccl_always_inline float4 read(uchar4 r)
{
float f = 1.0f/255.0f;
float f = 1.0f / 255.0f;
return make_float4(r.x*f, r.y*f, r.z*f, r.w*f);
}
static ccl_always_inline float4 read(uchar r)
{
float f = r*(1.0f/255.0f);
float f = r * (1.0f / 255.0f);
return make_float4(f, f, f, 1.0f);
}
@@ -63,6 +63,18 @@ template<typename T> struct TextureInterpolator {
return make_float4(f, f, f, 1.0f);
}
static ccl_always_inline float4 read(uint16_t r)
{
float f = r*(1.0f/65535.0f);
return make_float4(f, f, f, 1.0f);
}
static ccl_always_inline float4 read(ushort4 r)
{
float f = 1.0f/65535.0f;
return make_float4(r.x*f, r.y*f, r.z*f, r.w*f);
}
static ccl_always_inline float4 read(const T *data,
int x, int y,
int width, int height)
@@ -481,15 +493,21 @@ ccl_device float4 kernel_tex_image_interp(KernelGlobals *kg, int id, float x, fl
return TextureInterpolator<half>::interp(info, x, y);
case IMAGE_DATA_TYPE_BYTE:
return TextureInterpolator<uchar>::interp(info, x, y);
case IMAGE_DATA_TYPE_USHORT:
return TextureInterpolator<uint16_t>::interp(info, x, y);
case IMAGE_DATA_TYPE_FLOAT:
return TextureInterpolator<float>::interp(info, x, y);
case IMAGE_DATA_TYPE_HALF4:
return TextureInterpolator<half4>::interp(info, x, y);
case IMAGE_DATA_TYPE_BYTE4:
return TextureInterpolator<uchar4>::interp(info, x, y);
case IMAGE_DATA_TYPE_USHORT4:
return TextureInterpolator<ushort4>::interp(info, x, y);
case IMAGE_DATA_TYPE_FLOAT4:
default:
return TextureInterpolator<float4>::interp(info, x, y);
default:
assert(0);
return make_float4(TEX_IMAGE_MISSING_R, TEX_IMAGE_MISSING_G, TEX_IMAGE_MISSING_B, TEX_IMAGE_MISSING_A);
}
}
@@ -502,15 +520,21 @@ ccl_device float4 kernel_tex_image_interp_3d(KernelGlobals *kg, int id, float x,
return TextureInterpolator<half>::interp_3d(info, x, y, z, interp);
case IMAGE_DATA_TYPE_BYTE:
return TextureInterpolator<uchar>::interp_3d(info, x, y, z, interp);
case IMAGE_DATA_TYPE_USHORT:
return TextureInterpolator<uint16_t>::interp_3d(info, x, y, z, interp);
case IMAGE_DATA_TYPE_FLOAT:
return TextureInterpolator<float>::interp_3d(info, x, y, z, interp);
case IMAGE_DATA_TYPE_HALF4:
return TextureInterpolator<half4>::interp_3d(info, x, y, z, interp);
case IMAGE_DATA_TYPE_BYTE4:
return TextureInterpolator<uchar4>::interp_3d(info, x, y, z, interp);
case IMAGE_DATA_TYPE_USHORT4:
return TextureInterpolator<ushort4>::interp_3d(info, x, y, z, interp);
case IMAGE_DATA_TYPE_FLOAT4:
default:
return TextureInterpolator<float4>::interp_3d(info, x, y, z, interp);
default:
assert(0);
return make_float4(TEX_IMAGE_MISSING_R, TEX_IMAGE_MISSING_G, TEX_IMAGE_MISSING_B, TEX_IMAGE_MISSING_A);
}
}