@@ -16,6 +16,9 @@ const COLOR_MAPPER_OFF = 1u;
16
16
const COLOR_MAPPER_FUNCTION = 2u ;
17
17
const COLOR_MAPPER_TEXTURE = 3u ;
18
18
19
+ const FILTER_NEAREST = 1u ;
20
+ const FILTER_BILINEAR = 2u ;
21
+
19
22
struct UniformBuffer {
20
23
/// Top left corner position in world space.
21
24
top_left_corner_position : Vec3 ,
@@ -48,6 +51,9 @@ struct UniformBuffer {
48
51
/// Exponent to raise the normalized texture value.
49
52
/// Inverse brightness.
50
53
gamma : f32 ,
54
+
55
+ minification_filter : u32 ,
56
+ magnification_filter : u32 ,
51
57
};
52
58
53
59
@group (1 ) @binding (0 )
@@ -90,6 +96,18 @@ fn vs_main(@builtin(vertex_index) v_idx: u32) -> VertexOut {
90
96
return out ;
91
97
}
92
98
99
+ fn is_magnifying (pixel_coord : Vec2 ) -> bool {
100
+ return fwidth (pixel_coord . x) < 1.0 ;
101
+ }
102
+
103
+ fn tex_filter (pixel_coord : Vec2 ) -> u32 {
104
+ if is_magnifying (pixel_coord ) {
105
+ return rect_info . magnification_filter;
106
+ } else {
107
+ return rect_info . minification_filter;
108
+ }
109
+ }
110
+
93
111
@fragment
94
112
fn fs_main (in : VertexOut ) -> @location (0 ) Vec4 {
95
113
// Sample the main texture:
@@ -98,14 +116,50 @@ fn fs_main(in: VertexOut) -> @location(0) Vec4 {
98
116
// TODO(emilk): support mipmaps
99
117
sampled_value = textureSampleLevel (texture_float_filterable , texture_sampler , in . texcoord, 0.0 );
100
118
} else if rect_info . sample_type == SAMPLE_TYPE_FLOAT_NOFILTER {
101
- let icoords = IVec2 (in . texcoord * Vec2 (textureDimensions (texture_float ). xy));
102
- sampled_value = Vec4 (textureLoad (texture_float , icoords , 0 ));
119
+ let coord = in . texcoord * Vec2 (textureDimensions (texture_float ). xy);
120
+ if tex_filter (coord ) == FILTER_NEAREST {
121
+ // nearest
122
+ sampled_value = textureLoad (texture_float , IVec2 (coord + vec2 (0.5 )), 0 );
123
+ } else {
124
+ // bilinear
125
+ let v00 = textureLoad (texture_float , IVec2 (coord ) + IVec2 (0 , 0 ), 0 );
126
+ let v01 = textureLoad (texture_float , IVec2 (coord ) + IVec2 (0 , 1 ), 0 );
127
+ let v10 = textureLoad (texture_float , IVec2 (coord ) + IVec2 (1 , 0 ), 0 );
128
+ let v11 = textureLoad (texture_float , IVec2 (coord ) + IVec2 (1 , 1 ), 0 );
129
+ let top = mix (v00 , v10 , fract (coord . x));
130
+ let bottom = mix (v01 , v11 , fract (coord . x));
131
+ sampled_value = mix (top , bottom , fract (coord . y));
132
+ }
103
133
} else if rect_info . sample_type == SAMPLE_TYPE_SINT_NOFILTER {
104
- let icoords = IVec2 (in . texcoord * Vec2 (textureDimensions (texture_sint ). xy));
105
- sampled_value = Vec4 (textureLoad (texture_sint , icoords , 0 ));
134
+ let coord = in . texcoord * Vec2 (textureDimensions (texture_sint ). xy);
135
+ if tex_filter (coord ) == FILTER_NEAREST {
136
+ // nearest
137
+ sampled_value = Vec4 (textureLoad (texture_sint , IVec2 (coord + vec2 (0.5 )), 0 ));
138
+ } else {
139
+ // bilinear
140
+ let v00 = Vec4 (textureLoad (texture_sint , IVec2 (coord ) + IVec2 (0 , 0 ), 0 ));
141
+ let v01 = Vec4 (textureLoad (texture_sint , IVec2 (coord ) + IVec2 (0 , 1 ), 0 ));
142
+ let v10 = Vec4 (textureLoad (texture_sint , IVec2 (coord ) + IVec2 (1 , 0 ), 0 ));
143
+ let v11 = Vec4 (textureLoad (texture_sint , IVec2 (coord ) + IVec2 (1 , 1 ), 0 ));
144
+ let top = mix (v00 , v10 , fract (coord . x));
145
+ let bottom = mix (v01 , v11 , fract (coord . x));
146
+ sampled_value = mix (top , bottom , fract (coord . y));
147
+ }
106
148
} else if rect_info . sample_type == SAMPLE_TYPE_UINT_NOFILTER {
107
- let icoords = IVec2 (in . texcoord * Vec2 (textureDimensions (texture_uint ). xy));
108
- sampled_value = Vec4 (textureLoad (texture_uint , icoords , 0 ));
149
+ let coord = in . texcoord * Vec2 (textureDimensions (texture_uint ). xy);
150
+ if tex_filter (coord ) == FILTER_NEAREST {
151
+ // nearest
152
+ sampled_value = Vec4 (textureLoad (texture_uint , IVec2 (coord + vec2 (0.5 )), 0 ));
153
+ } else {
154
+ // bilinear
155
+ let v00 = Vec4 (textureLoad (texture_uint , IVec2 (coord ) + IVec2 (0 , 0 ), 0 ));
156
+ let v01 = Vec4 (textureLoad (texture_uint , IVec2 (coord ) + IVec2 (0 , 1 ), 0 ));
157
+ let v10 = Vec4 (textureLoad (texture_uint , IVec2 (coord ) + IVec2 (1 , 0 ), 0 ));
158
+ let v11 = Vec4 (textureLoad (texture_uint , IVec2 (coord ) + IVec2 (1 , 1 ), 0 ));
159
+ let top = mix (v00 , v10 , fract (coord . x));
160
+ let bottom = mix (v01 , v11 , fract (coord . x));
161
+ sampled_value = mix (top , bottom , fract (coord . y));
162
+ }
109
163
} else {
110
164
return ERROR_RGBA; // unknown sample type
111
165
}
0 commit comments