Noise-based Density Field
I'd start generating a "density-field", which would be a collection of points and the probability of your object occuring there. You can use a noise function such as Perlin noise to generate a "strength-field", which you can then modify using your own known parameters (elevation, normal direction, etc.)
Then for each cell in your density field, you can check if the value is high enough to place an object. You then place an object at a random point in that cell instead of at the exact center of that cell. You may have to do a cleanup pass to eliminate overlaps where two adjacent cells generate their objects directly next to the edge.
Cellular Rules
For many natural objects, there are certain rules that govern their occurrence. In the case of rocks, you could use a ruleset such as "pebbles get initially created in dried-out streams and rivers. Large rounded rock formations occur in areas where the soil gets worn down by erosion. large-scale stripes of rocks form from retreating glaciers." In the case of trees and bushes, they obey certain rulesets like "Trees will not grow within 3 feet of each other; bushes do not grow as well under trees; Old, aging forests have rich soil that promotes thick undergrowth". If you start with the randomized cell values from step 1 and iterate over a hundred generations of these rules, you will wind up with a more "natural distribution".