Yup, changing the viewport needs adjusted transformations, as Hodgman shows.
You could use scissors (ID3D11DeviceContext::RSSetScissorRects) for axis aligned clipping and keep the viewport as is. Probably the simplest to implement.
For completeness: There are other ways to clip:
- Look into SV_ClipDistance semantic (VS output)
- Similarily: Manually clip in the pixel shader with clip/discard
- For rectangles you could "clip" in the vertex shader (rect intersection calculation, adjusting tex coords, too) (*)
- Hint: SV_Position as input to the pixel shader delivers pixel coordinates (with a 0.5 offset), this can come in handy.
Edit: (*) Can be even a good idea to do this CPU-side. Instead of lots of pipeline state changes, one can batch everything.