From d18af703f1205f207297452906569195c9f7787e Mon Sep 17 00:00:00 2001 From: Masuo Suzuki <153872239+msuzuki-nvidia@users.noreply.github.com> Date: Thu, 17 Oct 2024 16:44:46 -0700 Subject: [PATCH] Add support `closest` texture lookup mode in MDL backend (#2072) Add support `closest` texture lookup mode in MDL backend. This change affects in all type of `image` nodes. --- .../mdl/materialx/stdlib_1_6.mdl | 90 ++++++++++++------- 1 file changed, 60 insertions(+), 30 deletions(-) diff --git a/source/MaterialXGenMdl/mdl/materialx/stdlib_1_6.mdl b/source/MaterialXGenMdl/mdl/materialx/stdlib_1_6.mdl index 601a10fda2..f5d661b17e 100644 --- a/source/MaterialXGenMdl/mdl/materialx/stdlib_1_6.mdl +++ b/source/MaterialXGenMdl/mdl/materialx/stdlib_1_6.mdl @@ -88,6 +88,24 @@ export material mx_surface_unlit( } } +// Helper function provides texture lookup coordinate with `closest` lookup type support +float2 tex_lookup_coord(float2 st, int tex_width, int tex_height, core::mx_filterlookup_type lookup_type, bool flip_v) +{ + float2 coord = st; + + // `closest` lookup + if (lookup_type == core::mx_filterlookup_type_closest) + { + int2 tex_size(tex_width, tex_height); + coord = (math::floor(coord * tex_size) + float2(0.5)) / tex_size; + } + + // `linear` and `cubic` uses the original coord + coord = flip_v ? float2(coord.x, 1.0 - coord.y) : coord; + + return coord; +} + // NOTE: need to map MaterialX return type overloads to different function names // or we require the mx_default to be always set explicitly @@ -121,8 +139,7 @@ export float mx_image_float( uniform core::mx_filterlookup_type mxp_filtertype = core::mx_filterlookup_type(core::mx_filterlookup_type_linear) [[ anno::description("Enumeration {closest,linear,cubic}."), - anno::display_name("Filter Type"), - anno::unused() + anno::display_name("Filter Type") ]], uniform string mxp_framerange = string("") [[ @@ -160,9 +177,12 @@ export float mx_image_float( return mxp_default; float returnValue = ::tex::lookup_float(tex: mxp_file, - coord: mxp_flip_v - ? float2(mxp_texcoord.x, 1.0f - mxp_texcoord.y) - : mxp_texcoord, + coord: tex_lookup_coord( + mxp_texcoord, + tex::width(mxp_file), + tex::height(mxp_file), + mxp_filtertype, + mxp_flip_v), wrap_u: map_addressmode(mxp_uaddressmode), wrap_v: map_addressmode(mxp_vaddressmode)); return returnValue; @@ -198,8 +218,7 @@ export color mx_image_color3( uniform core::mx_filterlookup_type mxp_filtertype = core::mx_filterlookup_type(core::mx_filterlookup_type_linear) [[ anno::description("Enumeration {closest,linear,cubic}."), - anno::display_name("Filter Type"), - anno::unused() + anno::display_name("Filter Type") ]], uniform string mxp_framerange = string("") [[ @@ -237,9 +256,12 @@ export color mx_image_color3( return mxp_default; color returnValue = ::tex::lookup_color(tex: mxp_file, - coord: mxp_flip_v - ? float2(mxp_texcoord.x, 1.0f - mxp_texcoord.y) - : mxp_texcoord, + coord: tex_lookup_coord( + mxp_texcoord, + tex::width(mxp_file), + tex::height(mxp_file), + mxp_filtertype, + mxp_flip_v), wrap_u: map_addressmode(mxp_uaddressmode), wrap_v: map_addressmode(mxp_vaddressmode)); return returnValue; @@ -275,8 +297,7 @@ export core::color4 mx_image_color4( uniform core::mx_filterlookup_type mxp_filtertype = core::mx_filterlookup_type(core::mx_filterlookup_type_linear) [[ anno::description("Enumeration {closest,linear,cubic}."), - anno::display_name("Filter Type"), - anno::unused() + anno::display_name("Filter Type") ]], uniform string mxp_framerange = string("") [[ @@ -314,9 +335,12 @@ export core::color4 mx_image_color4( return mxp_default; core::color4 returnValue = core::mk_color4(::tex::lookup_float4(tex: mxp_file, - coord: mxp_flip_v - ? float2(mxp_texcoord.x, 1.0f - mxp_texcoord.y) - : mxp_texcoord, + coord: tex_lookup_coord( + mxp_texcoord, + tex::width(mxp_file), + tex::height(mxp_file), + mxp_filtertype, + mxp_flip_v), wrap_u: map_addressmode(mxp_uaddressmode), wrap_v: map_addressmode(mxp_vaddressmode))); return returnValue; @@ -352,8 +376,7 @@ export float2 mx_image_vector2( uniform core::mx_filterlookup_type mxp_filtertype = core::mx_filterlookup_type(core::mx_filterlookup_type_linear) [[ anno::description("Enumeration {closest,linear,cubic}."), - anno::display_name("Filter Type"), - anno::unused() + anno::display_name("Filter Type") ]], uniform string mxp_framerange = string("") [[ @@ -391,9 +414,12 @@ export float2 mx_image_vector2( return mxp_default; float2 returnValue = ::tex::lookup_float2(tex: mxp_file, - coord: mxp_flip_v - ? float2(mxp_texcoord.x, 1.0f - mxp_texcoord.y) - : mxp_texcoord, + coord: tex_lookup_coord( + mxp_texcoord, + tex::width(mxp_file), + tex::height(mxp_file), + mxp_filtertype, + mxp_flip_v), wrap_u: map_addressmode(mxp_uaddressmode), wrap_v: map_addressmode(mxp_vaddressmode)); return returnValue; @@ -429,8 +455,7 @@ export float3 mx_image_vector3( uniform core::mx_filterlookup_type mxp_filtertype = core::mx_filterlookup_type(core::mx_filterlookup_type_linear) [[ anno::description("Enumeration {closest,linear,cubic}."), - anno::display_name("Filter Type"), - anno::unused() + anno::display_name("Filter Type") ]], uniform string mxp_framerange = string("") [[ @@ -468,9 +493,12 @@ export float3 mx_image_vector3( return mxp_default; float3 returnValue = ::tex::lookup_float3(tex: mxp_file, - coord: mxp_flip_v - ? float2(mxp_texcoord.x, 1.0f - mxp_texcoord.y) - : mxp_texcoord, + coord: tex_lookup_coord( + mxp_texcoord, + tex::width(mxp_file), + tex::height(mxp_file), + mxp_filtertype, + mxp_flip_v), wrap_u: map_addressmode(mxp_uaddressmode), wrap_v: map_addressmode(mxp_vaddressmode)); return returnValue; @@ -506,8 +534,7 @@ export float4 mx_image_vector4( uniform core::mx_filterlookup_type mxp_filtertype = core::mx_filterlookup_type(core::mx_filterlookup_type_linear) [[ anno::description("Enumeration {closest,linear,cubic}."), - anno::display_name("Filter Type"), - anno::unused() + anno::display_name("Filter Type") ]], uniform string mxp_framerange = string("") [[ @@ -545,9 +572,12 @@ export float4 mx_image_vector4( return mxp_default; float4 returnValue = ::tex::lookup_float4(tex: mxp_file, - coord: mxp_flip_v - ? float2(mxp_texcoord.x, 1.0f - mxp_texcoord.y) - : mxp_texcoord, + coord: tex_lookup_coord( + mxp_texcoord, + tex::width(mxp_file), + tex::height(mxp_file), + mxp_filtertype, + mxp_flip_v), wrap_u: map_addressmode(mxp_uaddressmode), wrap_v: map_addressmode(mxp_vaddressmode)); return returnValue;