obs-StreamFX/data/effects/lut.effect
Michael Fabian 'Xaymar' Dirks 5a3954ae0e project: Fix License, License headers and Copyright information
Fixes several files incorrectly stated a different license from the actual project, as well as the copyright headers included in all files. This change has no effect on the licensing terms, it should clear up a bit of confusion by contributors. Plus the files get a bit smaller, and we have less duplicated information across the entire project.

Overall the project is GPLv2 if not built with Qt, and GPLv3 if it is built with Qt. There are no parts licensed under a different license, all have been adapted from other compatible licenses into GPLv2 or GPLv3.
2023-04-05 18:59:08 +02:00

133 lines
4.1 KiB
Text

// AUTOGENERATED COPYRIGHT HEADER START
// Copyright (C) 2021-2023 Michael Fabian 'Xaymar' Dirks <info@xaymar.com>
// AUTOGENERATED COPYRIGHT HEADER END
sampler_state __LUTSampler {
Filter = Linear;
AddressU = Clamp;
AddressV = Clamp;
};
float4 generate_lut(uint bit_depth, float2 uv) {
uint size = pow(2, bit_depth);
uint z_size = pow(2, bit_depth / 2);
uint container_size = pow(2, bit_depth + (bit_depth / 2));
uint2 xy = uint2(floor(uv * container_size));
uint2 rg = xy % size;
uint2 bb = xy / size;
return float4(
rg.xy / float(size - 1),
((bb.y * z_size) + bb.x) / float(size - 1),
1.
);
};
float4 generate_lut2(float2 uv, uint4 params0) {
uint size = params0.r;
uint z_size = params0.g;
uint container_size = params0.b;
uint2 xy = uint2(floor(uv * container_size));
uint2 rg = xy % size;
uint2 bb = xy / size;
return float4(
rg.xy / float(size - 1),
((bb.y * z_size) + bb.x) / float(size - 1),
1.
);
};
float3 sample_lut(float3 color, uint bit_depth, texture2d lut_texture) {
uint size = pow(2, bit_depth);
uint z_size = pow(2, bit_depth / 2);
uint container_size = pow(2, bit_depth + (bit_depth / 2));
float inverse_size = 1. / size;
float inverse_z_size = 1. / z_size;
float inverse_container_size = 1. / container_size;
float half_texel = inverse_container_size / 2.; // Linear sampling is weird.
// Due to our LUT not actually being a cube but a plane pretending to be a cube,
// we have to do some conversion into the grid structure in order to be successful.
// 1. Clamp everything to a reasonable range.
color = saturate(color);
// 2. Rescale everything into 0..(size - 1)
color *= (size - 1);
// 3. Convert red and green into initial grid cell UVs.
float2 xy_uv = color.xy * inverse_container_size;
// 4. Figure out the high and low parts for interpolation.
uint z_lo = floor(color.z);
uint z_hi = z_lo + 1;
// 5. Figure out the X location of the cell in the grid.
uint z_lo_x = z_lo % z_size;
uint z_hi_x = z_hi % z_size;
// 6. Figure out the Y location of the cell in the grid.
uint z_lo_y = z_lo / z_size;
uint z_hi_y = z_hi / z_size;
// 7. Convert the X and Y locations into UV coordinates.
float2 z_lo_uv = float2(z_lo_x, z_lo_y) * inverse_z_size;
float2 z_hi_uv = float2(z_hi_x, z_hi_y) * inverse_z_size;
// 8. Sample both low and high points.
float3 c_lo = lut_texture.Sample(__LUTSampler, xy_uv + z_lo_uv + half_texel).rgb;
float3 c_hi = lut_texture.Sample(__LUTSampler, xy_uv + z_hi_uv + half_texel).rgb;
// 9. Return an interpolated version based on the fraction of Z.
return lerp(c_lo, c_hi, frac(color.z));
};
float3 sample_lut2(float3 color, texture2d lut_texture, int4 params0, float4 params1) {
uint size = params0.r;
uint z_size = params0.g;
uint container_size = params0.b;
float inverse_size = params1.r;
float inverse_z_size = params1.g;
float inverse_container_size = params1.b;
float half_texel = params1.a;
// Due to our LUT not actually being a cube but a plane pretending to be a cube,
// we have to do some conversion into the grid structure in order to be successful.
// 1. Clamp everything to a reasonable range.
color = saturate(color);
// 2. Rescale everything into 0..(size - 1)
color *= (size - 1);
// 3. Convert red and green into initial grid cell UVs.
float2 xy_uv = color.xy * inverse_container_size;
// 4. Figure out the high and low parts for interpolation.
uint z_lo = floor(color.z);
uint z_hi = z_lo + 1;
// 5. Figure out the X location of the cell in the grid.
uint z_lo_x = z_lo % z_size;
uint z_hi_x = z_hi % z_size;
// 6. Figure out the Y location of the cell in the grid.
uint z_lo_y = z_lo / z_size;
uint z_hi_y = z_hi / z_size;
// 7. Convert the X and Y locations into UV coordinates.
float2 z_lo_uv = float2(z_lo_x, z_lo_y) * inverse_z_size;
float2 z_hi_uv = float2(z_hi_x, z_hi_y) * inverse_z_size;
// 8. Sample both low and high points.
float3 c_lo = lut_texture.Sample(__LUTSampler, xy_uv + z_lo_uv + half_texel).rgb;
float3 c_hi = lut_texture.Sample(__LUTSampler, xy_uv + z_hi_uv + half_texel).rgb;
// 9. Return an interpolated version based on the fraction of Z.
return lerp(c_lo, c_hi, frac(color.z));
};