lygia
/space
/bracketing
)Bracketing technique maps a texture to a plane using any arbitrary 2D vector field to give orientation. From https://www.shadertoy.com/view/NddcDr
Dependencies:
Use:
sampleBracketing(<SAMPLER_TYPE> texture, <vec2> st, <vec2> direction [, <float> scale] )
// Parameter for bracketing - bracket size in radians. Large values create noticeable linear structure,
// small values prone to simply replicating the issues with the brute force approach. In my use cases it
// was quick and easy to find a sweet spot.
#ifndef BRACKETING_ANGLE_DELTA
#define BRACKETING_ANGLE_DELTA PI / 20.0
#endif
#ifndef FNC_BRACKETING
#define FNC_BRACKETING
// Vector field direction is used to drive UV coordinate frame, but instead
// of directly taking the vector directly, take two samples of the texture
// using coordinate frames at snapped angles, and then blend them based on
// the angle of the original vector.
void bracketing(vec2 dir, out vec2 vAxis0, out vec2 vAxis1, out float blendAlpha) {
// Heading angle of the original vector field direction
float angle = atan(dir.y, dir.x) + TWO_PI;
float AngleDelta = BRACKETING_ANGLE_DELTA;
// Snap to a first canonical direction by subtracting fractional angle
float fractional = mod(angle, AngleDelta);
float angle0 = angle - fractional;
// Compute one V axis of UV frame. Given angle0 is snapped, this could come from LUT, but would
// need testing on target platform to verify that a LUT is faster.
vAxis0 = vec2(cos(angle0), sin(angle0));
// Compute the next V axis by rotating by the snap angle size
mat2 RotateByAngleDelta = mat2( cos(AngleDelta), sin(AngleDelta),
-sin(AngleDelta), cos(AngleDelta));
vAxis1 = RotateByAngleDelta * vAxis0;
// Blend to get final result, based on how close the vector was to the first snapped angle
blendAlpha = fractional / AngleDelta;
}
#endif
Dependencies:
Use:
sampleBracketing(<SAMPLER_TYPE> texture, <float2> st, <float2> direction [, <float> scale] )
// Parameter for bracketing - bracket size in radians. Large values create noticeable linear structure,
// small values prone to simply replicating the issues with the brute force approach. In my use cases it
// was quick and easy to find a sweet spot.
#ifndef BRACKETING_ANGLE_DELTA
#define BRACKETING_ANGLE_DELTA PI / 20.0
#endif
#ifndef FNC_BRACKETING
#define FNC_BRACKETING
// Vector field direction is used to drive UV coordinate frame, but instead
// of directly taking the vector directly, take two samples of the texture
// using coordinate frames at snapped angles, and then blend them based on
// the angle of the original vector.
void bracketing(float2 dir, out float2 vAxis0, out float2 vAxis1, out float blendAlpha) {
// Heading angle of the original vector field direction
float angle = atan2(dir.y, dir.x) + TWO_PI;
float AngleDelta = BRACKETING_ANGLE_DELTA;
// Snap to a first canonical direction by subtracting fractional angle
float fractional = mod(angle, AngleDelta);
float angle0 = angle - fractional;
// Compute one V axis of UV frame. Given angle0 is snapped, this could come from LUT, but would
// need testing on target platform to verify that a LUT is faster.
vAxis0 = float2(cos(angle0), sin(angle0));
// Compute the next V axis by rotating by the snap angle size
float2x2 RotateByAngleDelta = float2x2( cos(AngleDelta), sin(AngleDelta),
-sin(AngleDelta), cos(AngleDelta));
vAxis1 = mul(RotateByAngleDelta, vAxis0);
// Blend to get final result, based on how close the vector was to the first snapped angle
blendAlpha = fractional / AngleDelta;
}
#endif
Dependencies:
Use:
sampleBracketing(<SAMPLER_TYPE> texture, <float2> st, <float2> direction [, <float> scale] )
// Parameter for bracketing - bracket size radians. Large values create noticeable linear structure,
// small values prone to simply replicating the issues with the brute force approach. my use cases it
// was quick and easy to find a sweet spot.
#ifndef BRACKETING_ANGLE_DELTA
#define BRACKETING_ANGLE_DELTA PI / 20.0
#endif
#ifndef FNC_BRACKETING
#define FNC_BRACKETING
// Vector field direction is used to drive UV coordinate frame, but instead
// of directly taking the vector directly, take two samples of the texture
// using coordinate frames at snapped angles, and then blend them based on
// the angle of the original vector.
void bracketing(float2 dir, out float2 vAxis0, out float2 vAxis1, out float blendAlpha) {
// Heading angle of the original vector field direction
float angle = atan(dir.y, dir.x) + TWO_PI;
float AngleDelta = BRACKETING_ANGLE_DELTA;
// Snap to a first canonical direction by subtracting fractional angle
float fractional = mod(angle, AngleDelta);
float angle0 = angle - fractional;
// Compute one V axis of UV frame. Given angle0 is snapped, this could come from LUT, but would
// need testing on target platform to verify that a LUT is faster.
vAxis0 = float2(cos(angle0), sin(angle0));
// Compute the next V axis by rotating by the snap angle size
mat2 RotateByAngleDelta = mat2( cos(AngleDelta), sin(AngleDelta),
-sin(AngleDelta), cos(AngleDelta));
vAxis1 = RotateByAngleDelta * vAxis0;
// Blend to get final result, based on how close the vector was to the first snapped angle
blendAlpha = fractional / AngleDelta;
}
#endif
MIT license (MIT) Copyright Huw Bowles May 2022
LYGIA is dual-licensed under the Prosperity License and the Patron License for sponsors and contributors.
Sponsors and contributors are automatically added to the Patron License and they can ignore the any non-commercial rule of the Prosperity Licensed software (please take a look to the exception).
It's also possible to get a permanent comercial license hook to a single and specific version of LYGIA.
Sign up for the news letter bellow, joing the LYGIA's channel on Discord or follow the Github repository