Search code examples
c++hlsl

Scaling issue in pixel and vertex shader


I have two shaders: pixel and vertex.
Both of them rotates picures.
One of the phases is scaling the picture. The scaling factor in both cases is 0.77328159.
Follow the shaders and results of the process.
The question is: why for pixel shader we devide by scaling factor and for vertex shader we multiply it?
As much the scaling factor bigger, smoller the result picture is.

Pixel shader

float fRadAngle = radians(fAngle);
float2 ptOrigin = input.Tex;
float2 ptPos = ptOrigin;
ptOrigin.x = (ptOrigin.x - 0.5) * fWidthSrc;
ptOrigin.y = (ptOrigin.y - 0.5) * fHeightSrc;
ptPos.x = ptOrigin.x * cos(fRadAngle) - ptOrigin.y * sin(fRadAngle);
ptPos.y = ptOrigin.x * sin(fRadAngle) + ptOrigin.y * cos(fRadAngle);
ptPos.x = ptPos.x / fWidthSrc;
ptPos.y = ptPos.y / fHeightSrc;
ptPos.x = ptPos.x / fScale + 0.5;
ptPos.y = ptPos.y / fScale + 0.5;
float4 pxRGB = float4( 0.0, 0.0, 0.0, 0.0 );
if( ptPos.x >= 0 && ptPos.x <= 1 && ptPos.y >= 0 && ptPos.y <= 1 )
    pxRGB = tx.Sample(sampler_in, ptPos);
return pxRGB;

Vertex shader

float2 ptPos = input.Pos.xy;
float2 ptOrigin = ptPos;
ptOrigin.x = (ptOrigin.x - 0.5) * fWidthSrc;
ptOrigin.y = (ptOrigin.y - 0.5) * fHeightSrc;
ptPos.x = ptOrigin.x * cos(fzRadAngle) - ptOrigin.y * sin(fzRadAngle);
ptPos.y = ptOrigin.x * sin(fzRadAngle) + ptOrigin.y * cos(fzRadAngle);
ptPos.x = ptPos.x / fWidthSrc;
ptPos.y = ptPos.y / fHeightSrc;
ptPos.x = ptPos.x * fScale + 0.5;
ptPos.y = ptPos.y * fScale + 0.5;

output.Pos.xy = ptPos.xy;
return output;

Put attantion to: ptPos.x / fScale and ptPos.x * fScale

Result of PS with scaling ~ 0.77:
(For VS is mostly the same)

0.7 scaling

Result of PS with scaling 0.1:
(For VS is mostly the same)

0.5 scaling

Again. PS have logical behaviour. Bigger scaling factor is, smaller image we gat, thus division for smaller number produces bigger number...
Why VS results the same with multipling?


Solution

  • In the pixel shader as written, the scaling factor is applied to a UV coordinate (ptPos.xy) in the range [0, 1] which is used to sample the texture. As you mentioned, dividing this UV by a decreasing value will scale the texture sampling down so that the image is scaled smaller. This happens because the UV coordinates are related to pixel position in this PS, and as the scaling factors increase, more pixels will get mapped into [0,1].

    The vertex shader outputs vertices which form the primitives on which the pixel shader is invoked per-pixel. Multiplying each vertex in the VS by an increasing scaling factor will effectively increase the screen space area over which the pixel shader is executed. This is why multiplying the output vertex position by an increasing scaling factor in the VS results in a larger scaled image.