Skip to content

Commit d767407

Browse files
committed
Implement bilinear filter for bumps
1 parent eab0267 commit d767407

File tree

2 files changed

+123
-54
lines changed

2 files changed

+123
-54
lines changed

App/CL/texture.cl

Lines changed: 117 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ THE SOFTWARE.
3434
#define TEXTURE_ARGS_IDX(x) x, textures, texturedata
3535

3636
/// Sample 2D texture
37+
inline
3738
float4 Texture_Sample2D(float2 uv, TEXTURE_ARG_LIST_IDX(texidx))
3839
{
3940
// Get width and height
@@ -121,6 +122,7 @@ float4 Texture_Sample2D(float2 uv, TEXTURE_ARG_LIST_IDX(texidx))
121122
}
122123

123124
/// Sample lattitue-longitude environment map using 3d vector
125+
inline
124126
float3 Texture_SampleEnvMap(float3 d, TEXTURE_ARG_LIST_IDX(texidx))
125127
{
126128
// Transform to spherical coords
@@ -137,6 +139,7 @@ float3 Texture_SampleEnvMap(float3 d, TEXTURE_ARG_LIST_IDX(texidx))
137139
}
138140

139141
/// Get data from parameter value or texture
142+
inline
140143
float3 Texture_GetValue3f(
141144
// Value
142145
float3 v,
@@ -158,6 +161,7 @@ float3 Texture_GetValue3f(
158161
}
159162

160163
/// Get data from parameter value or texture
164+
inline
161165
float4 Texture_GetValue4f(
162166
// Value
163167
float4 v,
@@ -179,6 +183,7 @@ float4 Texture_GetValue4f(
179183
}
180184

181185
/// Get data from parameter value or texture
186+
inline
182187
float Texture_GetValue1f(
183188
// Value
184189
float v,
@@ -199,7 +204,94 @@ float Texture_GetValue1f(
199204
return v;
200205
}
201206

207+
inline float3 TextureData_SampleNormalFromBump_uchar4(__global uchar4 const* mydatac, int width, int height, int t0, int s0)
208+
{
209+
int t0minus = clamp(t0 - 1, 0, height - 1);
210+
int t0plus = clamp(t0 + 1, 0, height - 1);
211+
int s0minus = clamp(s0 - 1, 0, width - 1);
212+
int s0plus = clamp(s0 + 1, 0, width - 1);
213+
214+
const uchar utex00 = (*(mydatac + width * t0minus + s0minus)).x;
215+
const uchar utex10 = (*(mydatac + width * t0minus + (s0))).x;
216+
const uchar utex20 = (*(mydatac + width * t0minus + s0plus)).x;
217+
218+
const uchar utex01 = (*(mydatac + width * (t0)+s0minus)).x;
219+
const uchar utex21 = (*(mydatac + width * (t0)+(s0 + 1))).x;
220+
221+
const uchar utex02 = (*(mydatac + width * t0plus + s0minus)).x;
222+
const uchar utex12 = (*(mydatac + width * t0plus + (s0))).x;
223+
const uchar utex22 = (*(mydatac + width * t0plus + s0plus)).x;
224+
225+
const float tex00 = (float)utex00 / 255.f;
226+
const float tex10 = (float)utex10 / 255.f;
227+
const float tex20 = (float)utex20 / 255.f;
228+
229+
const float tex01 = (float)utex01 / 255.f;
230+
const float tex21 = (float)utex21 / 255.f;
231+
232+
const float tex02 = (float)utex02 / 255.f;
233+
const float tex12 = (float)utex12 / 255.f;
234+
const float tex22 = (float)utex22 / 255.f;
235+
236+
const float Gx = tex00 - tex20 + 2.0f * tex01 - 2.0f * tex21 + tex02 - tex22;
237+
const float Gy = tex00 + 2.0f * tex10 + tex20 - tex02 - 2.0f * tex12 - tex22;
238+
const float3 n = make_float3(Gx, Gy, 1.f);
239+
240+
return n;
241+
}
242+
243+
inline float3 TextureData_SampleNormalFromBump_half4(__global half const* mydatah, int width, int height, int t0, int s0)
244+
{
245+
int t0minus = clamp(t0 - 1, 0, height - 1);
246+
int t0plus = clamp(t0 + 1, 0, height - 1);
247+
int s0minus = clamp(s0 - 1, 0, width - 1);
248+
int s0plus = clamp(s0 + 1, 0, width - 1);
249+
250+
const float tex00 = vload_half4(width * t0minus + s0minus, mydatah).x;
251+
const float tex10 = vload_half4(width * t0minus + (s0), mydatah).x;
252+
const float tex20 = vload_half4(width * t0minus + s0plus, mydatah).x;
253+
254+
const float tex01 = vload_half4(width * (t0)+s0minus, mydatah).x;
255+
const float tex21 = vload_half4(width * (t0)+s0plus, mydatah).x;
256+
257+
const float tex02 = vload_half4(width * t0plus + s0minus, mydatah).x;
258+
const float tex12 = vload_half4(width * t0plus + (s0), mydatah).x;
259+
const float tex22 = vload_half4(width * t0plus + s0plus, mydatah).x;
260+
261+
const float Gx = tex00 - tex20 + 2.0f * tex01 - 2.0f * tex21 + tex02 - tex22;
262+
const float Gy = tex00 + 2.0f * tex10 + tex20 - tex02 - 2.0f * tex12 - tex22;
263+
const float3 n = make_float3(Gx, Gy, 1.f);
264+
265+
return n;
266+
}
267+
268+
inline float3 TextureData_SampleNormalFromBump_float4(__global float4 const* mydataf, int width, int height, int t0, int s0)
269+
{
270+
int t0minus = clamp(t0 - 1, 0, height - 1);
271+
int t0plus = clamp(t0 + 1, 0, height - 1);
272+
int s0minus = clamp(s0 - 1, 0, width - 1);
273+
int s0plus = clamp(s0 + 1, 0, width - 1);
274+
275+
const float tex00 = (*(mydataf + width * t0minus + s0minus)).x;
276+
const float tex10 = (*(mydataf + width * t0minus + (s0))).x;
277+
const float tex20 = (*(mydataf + width * t0minus + s0plus)).x;
278+
279+
const float tex01 = (*(mydataf + width * (t0)+s0minus)).x;
280+
const float tex21 = (*(mydataf + width * (t0)+s0plus)).x;
281+
282+
const float tex02 = (*(mydataf + width * t0plus + s0minus)).x;
283+
const float tex12 = (*(mydataf + width * t0plus + (s0))).x;
284+
const float tex22 = (*(mydataf + width * t0plus + s0plus)).x;
285+
286+
const float Gx = tex00 - tex20 + 2.0f * tex01 - 2.0f * tex21 + tex02 - tex22;
287+
const float Gy = tex00 + 2.0f * tex10 + tex20 - tex02 - 2.0f * tex12 - tex22;
288+
const float3 n = make_float3(Gx, Gy, 1.f);
289+
290+
return n;
291+
}
292+
202293
/// Sample 2D texture
294+
inline
203295
float3 Texture_SampleBump(float2 uv, TEXTURE_ARG_LIST_IDX(texidx))
204296
{
205297
// Get width and height
@@ -222,84 +314,55 @@ float3 Texture_SampleBump(float2 uv, TEXTURE_ARG_LIST_IDX(texidx))
222314
int s0 = clamp((int)floor(uv.x * width), 0, width - 1);
223315
int t0 = clamp((int)floor(uv.y * height), 0, height - 1);
224316

317+
int s1 = clamp(s0 + 1, 0, width - 1);
318+
int t1 = clamp(t0 + 1, 0, height - 1);
319+
320+
// Calculate weights for linear filtering
321+
float wx = uv.x * width - floor(uv.x * width);
322+
float wy = uv.y * height - floor(uv.y * height);
323+
225324
switch (textures[texidx].fmt)
226325
{
227326
case RGBA32:
228327
{
229328
__global float3 const* mydataf = (__global float3 const*)mydata;
230329

231-
// Sobel filter
232-
const float tex00 = (*(mydataf + width * (t0 - 1) + (s0-1))).x;
233-
const float tex10 = (*(mydataf + width * (t0 - 1) + (s0))).x;
234-
const float tex20 = (*(mydataf + width * (t0 - 1) + (s0 + 1))).x;
330+
float3 n00 = TextureData_SampleNormalFromBump_float4(mydataf, width, height, t0, s0);
331+
float3 n01 = TextureData_SampleNormalFromBump_float4(mydataf, width, height, t0, s1);
332+
float3 n10 = TextureData_SampleNormalFromBump_float4(mydataf, width, height, t1, s0);
333+
float3 n11 = TextureData_SampleNormalFromBump_float4(mydataf, width, height, t1, s1);
235334

236-
const float tex01 = (*(mydataf + width * (t0) + (s0 - 1))).x;
237-
const float tex21 = (*(mydataf + width * (t0) + (s0 + 1))).x;
335+
float3 n = lerp3(lerp3(n00, n01, wx), lerp3(n10, n11, wx), wy);
238336

239-
const float tex02 = (*(mydataf + width * (t0 + 1) + (s0 - 1))).x;
240-
const float tex12 = (*(mydataf + width * (t0 + 1) + (s0))).x;
241-
const float tex22 = (*(mydataf + width * (t0 + 1) + (s0 + 1))).x;
242-
243-
const float Gx = tex00 - tex20 + 2.0f * tex01 - 2.0f * tex21 + tex02 - tex22;
244-
const float Gy = tex00 + 2.0f * tex10 + tex20 - tex02 - 2.0f * tex12 - tex22;
245-
const float3 n = make_float3(Gx, Gy, 1.f);
246-
247-
return 0.5f * normalize(n) + make_float3(0.5f, 0.5f, 0.5f);
337+
return 0.5f * normalize(n) + make_float3(0.5f, 0.5f, 0.5f);
248338
}
249339

250340
case RGBA16:
251341
{
252342
__global half const* mydatah = (__global half const*)mydata;
253343

254-
const float tex00 = vload_half4(width * (t0 - 1) + (s0 - 1), mydatah).x;
255-
const float tex10 = vload_half4(width * (t0 - 1) + (s0), mydatah).x;
256-
const float tex20 = vload_half4(width * (t0 - 1) + (s0 + 1), mydatah).x;
257-
258-
const float tex01 = vload_half4(width * (t0)+(s0 - 1), mydatah).x;
259-
const float tex21 = vload_half4(width * (t0)+(s0 + 1), mydatah).x;
344+
float3 n00 = TextureData_SampleNormalFromBump_half4(mydatah, width, height, t0, s0);
345+
float3 n01 = TextureData_SampleNormalFromBump_half4(mydatah, width, height, t0, s1);
346+
float3 n10 = TextureData_SampleNormalFromBump_half4(mydatah, width, height, t1, s0);
347+
float3 n11 = TextureData_SampleNormalFromBump_half4(mydatah, width, height, t1, s1);
260348

261-
const float tex02 = vload_half4(width * (t0 + 1) + (s0 - 1), mydatah).x;
262-
const float tex12 = vload_half4(width * (t0 + 1) + (s0), mydatah).x;
263-
const float tex22 = vload_half4(width * (t0 + 1) + (s0 + 1), mydatah).x;
349+
float3 n = lerp3(lerp3(n00, n01, wx), lerp3(n10, n11, wx), wy);
264350

265-
const float Gx = tex00 - tex20 + 2.0f * tex01 - 2.0f * tex21 + tex02 - tex22;
266-
const float Gy = tex00 + 2.0f * tex10 + tex20 - tex02 - 2.0f * tex12 - tex22;
267-
const float3 n = make_float3(Gx, Gy, 1.f);
268-
269-
return 0.5f * normalize(n) + make_float3(0.5f, 0.5f, 0.5f);
351+
return 0.5f * normalize(n) + make_float3(0.5f, 0.5f, 0.5f);
270352
}
271353

272354
case RGBA8:
273355
{
274356
__global uchar4 const* mydatac = (__global uchar4 const*)mydata;
275357

276-
const uchar utex00 = (*(mydatac + width * (t0 - 1) + (s0 - 1))).x;
277-
const uchar utex10 = (*(mydatac + width * (t0 - 1) + (s0))).x;
278-
const uchar utex20 = (*(mydatac + width * (t0 - 1) + (s0 + 1))).x;
279-
280-
const uchar utex01 = (*(mydatac + width * (t0)+(s0 - 1))).x;
281-
const uchar utex21 = (*(mydatac + width * (t0)+(s0 + 1))).x;
282-
283-
const uchar utex02 = (*(mydatac + width * (t0 + 1) + (s0 - 1))).x;
284-
const uchar utex12 = (*(mydatac + width * (t0 + 1) + (s0))).x;
285-
const uchar utex22 = (*(mydatac + width * (t0 + 1) + (s0 + 1))).x;
286-
287-
const float tex00 = (float)utex00 / 255.f;
288-
const float tex10 = (float)utex10 / 255.f;
289-
const float tex20 = (float)utex20 / 255.f;
290-
291-
const float tex01 = (float)utex01 / 255.f;
292-
const float tex21 = (float)utex21 / 255.f;
293-
294-
const float tex02 = (float)utex02 / 255.f;
295-
const float tex12 = (float)utex12 / 255.f;
296-
const float tex22 = (float)utex22 / 255.f;
358+
float3 n00 = TextureData_SampleNormalFromBump_uchar4(mydatac, width, height, t0, s0);
359+
float3 n01 = TextureData_SampleNormalFromBump_uchar4(mydatac, width, height, t0, s1);
360+
float3 n10 = TextureData_SampleNormalFromBump_uchar4(mydatac, width, height, t1, s0);
361+
float3 n11 = TextureData_SampleNormalFromBump_uchar4(mydatac, width, height, t1, s1);
297362

298-
const float Gx = tex00 - tex20 + 2.0f * tex01 - 2.0f * tex21 + tex02 - tex22;
299-
const float Gy = tex00 + 2.0f * tex10 + tex20 - tex02 - 2.0f * tex12 - tex22;
300-
const float3 n = make_float3(Gx, Gy, 1.f);
363+
float3 n = lerp3(lerp3(n00, n01, wx), lerp3(n10, n11, wx), wy);
301364

302-
return 0.5f * normalize(n) + make_float3(0.5f, 0.5f, 0.5f);
365+
return 0.5f * normalize(n) + make_float3(0.5f, 0.5f, 0.5f);
303366
}
304367

305368
default:

App/CL/utils.cl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,12 @@ float4 lerp(float4 a, float4 b, float w)
217217
return a + w*(b-a);
218218
}
219219

220+
/// Linearly interpolate between two values
221+
float3 lerp3(float3 a, float3 b, float w)
222+
{
223+
return a + w*(b - a);
224+
}
225+
220226
/// Translate cartesian coordinates to spherical system
221227
void CartesianToSpherical ( float3 cart, float* r, float* phi, float* theta )
222228
{

0 commit comments

Comments
 (0)