Friday, September 23, 2022
HomeGame Developmentprojection - D3D12: methods to allow perspective correction when interpolating UV coordinates?

projection – D3D12: methods to allow perspective correction when interpolating UV coordinates?


Good morning,
I’m at the moment operating right into a UV interpolation challenge with D3D12 that appears like this:

2D quad

Is there one thing that must be set when initialising the pipeline in order that the GPU does the right interpolation or do I’ve to do it myself?
I’ve seen a number of examples of textured 3D objects that seemed superb and the related code didn’t appear to do something particular to compute the right UVs manually, so I suppose I simply forgot to set a flag or one thing?

EDIT: right here is a few extra data (shaders are trimmed to the core):

// That is the enter knowledge description.

D3D12_INPUT_ELEMENT_DESC quad_layout[NUM_ELEMENTS_IN_QUAD_LAYOUT] = {
    {"Vertex_Position", 0, DXGI_FORMAT_R32G32_FLOAT,       0, 0,                            D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA,   0},
    {"Uv_Coords",       0, DXGI_FORMAT_R32G32_FLOAT,       0, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA,   0},
    
    {"Color",          0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 0},
    {"Place",        0, DXGI_FORMAT_R32G32_FLOAT,       1, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 0},
    {"Scale",           0, DXGI_FORMAT_R32G32_FLOAT,       1, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 0},
    {"Font_Texture_Coords", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 1, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 0},
    {"Texture",         0, DXGI_FORMAT_R32_UINT,           1, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 0},
    {"Flags",           0, DXGI_FORMAT_R32_UINT,           1, D3D12_APPEND_ALIGNED_ELEMENT, D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA, 0},
};

/*
typedef struct
{
    v2 place;
    v2 uvs;
} Quad_Vertex;
*/

/////////////////////////////////////////////////////////////////////
// NOTE: I tweaked the higher corners to focus on the difficulty, usually
// place parts are set to 1 or -1.
/////////////////////////////////////////////////////////////////////
Quad_Vertex quad_vertex_buffer_data[4] = {
    {{-0.5,  1}, {0, 0}},
    {{ 0.5,  1}, {1, 0}},
    {{ 1,   -1}, {1, 1}},
    {{-1,   -1}, {0, 1}}
};
// Vertex shader:

ConstantBuffer<Renderer_Info> renderer_info : register(b0, space0);

struct To_Pixel_Shader
{
    v4  place      : SV_Position;
    v4  color        : Color;
    v2  uvs           : Uv_Coords;
    v4  font_texture_coords : Font_Texture_Coords;
    u32 texture_index : Texture;
    u32 flags         : Flags;
};

To_Pixel_Shader most important(
    v2  vertex_position : Vertex_Position,
    v2  uvs             : Uv_Coords,
    
    v4  color          : Color,
    v2  place        : Place,
    v2  scale           : Scale,
    v4  font_texture_coords : Font_Texture_Coords,
    u32 texture_index   : Texture,
    u32 flags           : Flags
)
{
    To_Pixel_Shader consequence;
    
    v2 rt_dimensions = v2(renderer_info.rt_width, renderer_info.rt_height);
    v2 rt_scale_factor  = 1.0f / rt_dimensions;
    
    v2 updated_position = (vertex_position * scale + place * 2.0f) * rt_scale_factor + v2(-1, 1);
    
    consequence.place      = v4(updated_position.xy, 0, 1);
    consequence.color        = color;
    consequence.uvs           = uvs;
    consequence.font_texture_coords = font_texture_coords;
    consequence.texture_index = texture_index;
    consequence.flags         = flags;
    
    return consequence;
}
// Pixel shader:

ConstantBuffer<Renderer_Info> renderer_info : register(b0, space1);
Texture2D<v4> colour_atlas : register(t0, space1);
StructuredBuffer<Atlas_Texture> colour_textures : register(t1, space1);
SamplerState bilinear_sampler : register(s0);
SamplerState point_sampler    : register(s1);

v4 most important(
    v4  place      : SV_Position,
    v4  color        : Color,
    v2  uvs           : Uv_Coords,
    v4  font_texture_coords : Font_Texture_Coords,
    u32 texture_index : Texture,
    u32 flags         : Flags
) : SV_Target
{
    v4 texture_colour = 1;
    
    Atlas_Texture t = colour_textures[texture_index];
    
    v2 updated_uvs = uvs * t.uv_ratio + t.uv_offset_in_atlas;
    
    v4 texture_colour_bilinear = colour_atlas.Pattern(bilinear_sampler, updated_uvs);
    v4 texture_colour_point    = colour_atlas.Pattern(point_sampler,    updated_uvs);
    
    texture_colour = lerp(texture_colour_bilinear, texture_colour_point, (flags & SAMPLE_EXACT) / SAMPLE_EXACT);
    
    return linear_to_srgb(color * texture_colour);
}

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -
Google search engine

Most Popular

Recent Comments