Why is default interpolation done this way?

My question (before I give the backstory):
Why does the specification subtract 0.5 from coordinates when interpolating? The values I wish to use are stored at the vertices of my texture. This seems to be a “duh!” thing. I need values interpolated between these values. When I add 0.5 back into my coordinates, my output is very close to what I expect it to be, as you can see in my test output below.

My Texture Sampler:

  • NORMALIZED_FALSE
  • ADDRESS_NONE
  • LINEAR

On page 213 of the Specification rev 1.0.48 describes exactly what I am questioning in this excerpt:


i0 = address_mode((int)floor(u – 0.5)) 
j0 = address_mode((int)floor(v – 0.5)) 
k0 = address_mode((int)floor(w – 0.5)) 
i1 = address_mode((int)floor(u – 0.5) + 1) 
j1 = address_mode((int)floor(v – 0.5) + 1) 
k1 = address_mode((int)floor(w – 0.5) + 1) 
a = frac(u – 0.5)
b = frac(v – 0.5) 
c = frac(w – 0.5)

Excerpt of my Output:
L-Left
R-Right
T-Top
B-Bottom
N-Near
F-Far
Given - The value OpenCL computes default
Expected - The value I compute on the CPU with the same points


LTF <106,103,406>: 0.514389	0.491119	-0.702998
LTN <106,103,405>: 0.496854	0.472259	-0.728085
LBF <106,102,406>: 0.527932	0.47955	-0.700942
LBN <106,102,405>: 0.509431	0.460399	-0.726989
RTF <107,103,406>: 0.529114	0.47142	-0.70555
RTN <107,103,405>: 0.511618	0.45378	-0.72961
RBF <107,102,406>: 0.542256	0.459092	-0.703699
RBN <107,102,405>: 0.523821	0.441273	-0.728622
    Seed: 106.16	102.441	405.418
   Given: 0.513711	0.47053	-0.717095
Expected: 0.513768	0.470488	-0.71708

LTF <46,2,246>: -0.0206695	0.123715	-0.992103
LTN <46,2,245>: -0.0220052	0.12875	-0.991433
LBF <46,1,246>: -0.0121531	0.0824225	-0.996523
LBN <46,1,245>: -0.01143	0.0827354	-0.996506
RTF <47,2,246>: -0.0192425	0.123567	-0.99215
RTN <47,2,245>: -0.0205985	0.128544	-0.99149
RBF <47,1,246>: -0.0109675	0.0817531	-0.996592
RBN <47,1,245>: -0.0103092	0.0821067	-0.99657
    Seed: 46.7812	1.20099	245.167
   Given: -0.0126582	0.0912559	-0.99557
Expected: -0.0126794	0.0913456	-0.99556

LTF <79,81,330>: -0.0933031	-0.6752	0.73171
LTN <79,81,329>: -0.193758	-0.768985	0.609197
LBF <79,80,330>: -0.109483	-0.613193	0.782309
LBN <79,80,329>: -0.238349	-0.714039	0.658284
RTF <80,81,330>: -0.189178	-0.855614	0.481805
RTN <80,81,329>: -0.266574	-0.892155	0.36469
RBF <80,80,330>: -0.259245	-0.796311	0.546517
RBN <80,80,329>: -0.350817	-0.84717	0.399036
    Seed: 79.8822	80.8119	329.543
   Given: -0.227836	-0.844265	0.466802
Expected: -0.227862	-0.8441	0.46694

LTF <99,48,183>: -0.325013	0.939729	-0.106186
LTN <99,48,182>: -0.278117	0.959684	-0.0407043
LBF <99,47,183>: -0.313302	0.941127	-0.126975
LBN <99,47,182>: -0.264867	0.962246	-0.0626743
RTF <100,48,183>: -0.397135	0.904325	-0.156463
RTN <100,48,182>: -0.356216	0.930136	-0.0892023
RBF <100,47,183>: -0.384099	0.906393	-0.17584
RBN <100,47,182>: -0.34191	0.93324	-0.110275
    Seed: 99.8793	47.1705	182.77
   Given: -0.367897	0.916246	-0.151424
Expected: -0.367939	0.916212	-0.151521


I understand what is going on with ijk… it is just a C-style means to get floor() and ceil(), but why the a, b, and c components?

In OpenGL and OpenCL, pixels are located at the “center” of the area they occupy [1]. In some other APIs, pixels are located in the upper-left corner. The 0.5 offset comes from that.

[1] Spec lawyers, please don’t shoot.

:lol: :roll:

Thats what I figured. Someone has to draw the line between CL and GL somewhere and I can find no good arguments for or against changing it from how OpenGL does it. At least, none that I can’t immediately counter again.