#Formula to offset dither pattern UVs opposite camera's world movement?

1 messages · Page 1 of 1 (latest)

unique knot
#

I am trying to cancel out the shimmer you see when the camera moves when using a screen-space dither pattern.
https://forums.tigsource.com/index.php?topic=40832.msg1363742#msg1363742 Lucas Pope mentions counter-moving the camera against the pattern.

I am trying to implement that but I am not sure what the formula/relationship is between the camera's worldspace unit movements and the dither texture screen space position.

This doesn't solve camera rotation but that's okay, my camera is orthographic and so I only really need to counter 2d non-rotational movements.

#

Hm I think what I need to know is to figure out the relationship size between 1 camera pixel and X world units?

summer terrace
#

There's also Pixel screen position mode, maybe that can simplify the math

unique knot
#

Hm I dont see a pixel screen position node, maybe its from a newer SG? There are no nodes with 'pixel' in the name unless its named something else. I am getting screen size from the screen node, which for reference right now my screen size is 160x90

#

At a future point I also need to snap my camera's movements to exactly 1px movements to reduce shimmer, so I will need to figure that out, what world units are 1 screen pixel

summer terrace
summer terrace
unique knot
#

Oh in screen position, I see now 👀

summer terrace
# unique knot Oh in screen position, I see now 👀

Tiled mode maps 0 to 1 UV space from center to top which would match the ortho size variable, and then fills the rest of the space with a UVs by repeating squares accordingly
So maybe that's even better as it isn't stretched vertically and is always the same relative to camera size

unique knot
#

Okay got basic camera snap, based on what you just said I think the answer is:
float pixelSize = (_camera.orthographicSize * 2) / renderTextureSize.y;

#

I havent implemented that yet (You can still see the dither shimmer), just camera snap

summer terrace
#

Looks solid!

unique knot
#

Hmm I hit an issue/wall, when I move the camera even though its being snapped to pixel increments, its 'true' unsnapped position is being sent/got in the shader

#

so even though the camera isnt moving because its being snapped, the world position is still updating as I attempt to move it, and shader still offsets from that world pos

#

I might need to create a global variable in C# and update that and sample that instead of trying to calculate the camera pixel offset in shader?

summer terrace
#

In this case how are you snapping the camera's position technically?

unique knot
#

PixelSnapper monobehaviour that runs OnDrawGizmos

#

eg its me literally dragging it with my mouse, not driven by code yet

summer terrace
#

Is it snapping the camera transform nonetheless?

unique knot
#

Yeah the code works, I was just noticing the shader 'moves' when the camera doesn't

summer terrace
#

I'd assume if the camera's transform is overwritten in a monobehaviour, that can't be different from any "true" camera position by the time the frame is rendered using that camera

#

Everything that's rendered by all shaders is working off of the same global camera state and transform

#

But I'm not sure what else it could be

#

Probably has to be related to whatever coordinate space the dithering is using

unique knot
#

currently its a bit of a mess

#

I am confident in the mapping of the dither to the screen

#

but I am not confident in the code trying to compensate for camera movements

summer terrace
# unique knot

If the C# code snaps the camera position, doesn't the shader implicitly know from the distance how much the dither needs to be offset? If it's the exact same increment anyway for pixel perfect camera snapping and dither snapping

unique knot
#

    private void SnapCameraToPixelGrid()
    {
        float pixelSize = (_camera.orthographicSize * 2) / renderTextureSize.y;

        Transform cameraTransform = transform;
        Vector3 currentPosition = cameraTransform.position;
        Quaternion cameraRotation = cameraTransform.rotation;

        Quaternion inverseRotation = Quaternion.Inverse(cameraRotation);
        Vector3 unrotatedPosition = inverseRotation * currentPosition;

        float snappedX = Mathf.Round(unrotatedPosition.x / pixelSize) * pixelSize;
        float snappedY = Mathf.Round(unrotatedPosition.y / pixelSize) * pixelSize;

        Vector3 snappedUnrotatedPosition = new Vector3(snappedX, snappedY, unrotatedPosition.z);

        transform.position = cameraRotation * snappedUnrotatedPosition;
    }```
#

snap code for posterity

unique knot
#

I thought I would have to pan the dither texture by 1px on x/y as the camera moves UnityChanThink

summer terrace
#

Meaning if the script moves the camera in world space precisely in the right pixel increments along its local axis, wouldn't that be known to the shader
Or could be passed a property

#

Unless the camera's "pixel movement" doesn't match the dither pattern's pixel movement for some reason I don't notice?

#

Should probably test my own assumptions before speculating too much

unique knot
#

yeah that was my next guess to make this work would be to make a global property and pass into it for the shader from the code that snaps the camera

#

its late today so Ill be back at this again fresh tomorrow

unique knot
#

I kept working on this but I got stuck

#

the camera pixel snap code doesnt work right

#

it works to snap to pixel but it lets the camera slide backward on its local axis

#

which "doesnt" change the pixel

#

but it does fuck up the dithering shader

#

and I cannot for the life of me fix the snap code to prevent this from occuring because technically the snap code isnt bugging out, the positions its being snapped to ARE valid

#

they just arent what I want

#

crossposted to the code sub because I hit a wall with this

unique knot
#

10pm finally got it working

#

look ma, no movement

#

ive never been so happy to see nothing happen