I wanted to pass xyz as a colour to my image to use as world positions but that is obviously clamped between 0 and 1, and i also don’t get negative numbers in the image so i can’t use them as world positions.
If you’re rendering a mesh in the scene, then the world position is always calculated in the vertex shader as part of the UnityObjectToClipPos() function. There’s no need to output to a texture since the the world position is already known in this case, so there’s no issue with the value being clamped.
It’s just a matter of passing that value from the vertex to the fragment. If you’re using a surface shader it’s just a matter of adding float3 worldPos; to the Input struct.
If you’re doing this as a post process image effect, then the usual solution is to reconstruct the world position from the camera depth texture. See this for an example: https://github.com/keijiro/DepthInverseProjection
A similar technique is how several of Unity’s post process effects work.
If you’re really stuck on outputting the world position to a texture, then you’ll want to use a float texture format as your render texture instead of the usual default ARGB32. Specifically ARGBFloat. That has a full 32bit float per component, so isn’t limited to a “0 to 1” range, and can hold negative values.