sstelkar You could probably do it by fudging screen UVs but it's better to use object's UV for multiple reasons, one being a nice zoom independent preview in editor and the other is that tilting the bottle may hide considerable parts of the screen space gradient at the top/bottom. Instead, better to transform local uv space to stretch between top and bottom of bottle's rotated bounding box.
Easiest way is to construct a shear matrix that shears the uv space around uv center (.5,.5) for a certain angle, to compensate for the tilt caused by rotation. Calculating this angle is the trickiest part, but here's the recipe:
float scaleRatio = length(MODEL_MATRIX[0]) / length(MODEL_MATRIX[1]);
float imageRatio = TEXTURE_PIXEL_SIZE.y / TEXTURE_PIXEL_SIZE.x;
float shearAngle = atan(MODEL_MATRIX[0].y * scaleRatio * imageRatio, MODEL_MATRIX[0].x );
If you don't have non-proportional scaling on the bottle sprite, simply remove scaleRatio from calculation.
Once you have the angle, construct the shearMatrix with following basis vectors:
shearMatrix = mat4(
vec4(1.0, sin(shearAngle), 0.0, 0.0),
vec4(0.0, cos(shearAngle), 0.0, 0.0),
vec4(0.0, 0.0, 1.0, 0.0),
vec4(0.0, 0.5, 0.0, 0.0)
);
The above should be done in vertex function and the shearMatrix passed to fragment function as a varying.
In fragment shader, subtract the object space UV from (.5,.5) to bring it to center and then multiply it with the shearMatrix. Use resulting V to drive your gradients.
