ggplot 3.0+ demystifies the calculation of summary metrics via the new stat() internal function. This makes it easier to modify the statistic being used to create the fill for the hexes. So for example:
Default count statistic
df <- data.frame(
x = rnorm(1000),
y = rnorm(1000)
)
plot.df <- ggplot(data = df, aes(x = x, y = y)) +
geom_hex(aes(fill = stat(count)))
print(plot.df)

Log count statistic
plot.df.log <- ggplot(data = df, aes(x = x, y = y)) +
geom_hex(aes(fill = stat(log(count))))
print(plot.df.log)

In place of log, you could do any arbitrary transformation you want, like cube root, etc.
Using cut
To avoid creating a scale with confusing values, you could use cut to establish sensible category boundaries, and convert these to a numeric scale which is labeled with the original count values:
plot.df.log.cut <- ggplot(data = df, aes(x = x, y = y)) +
geom_hex(aes(fill = stat(cut(log(count), breaks = log(c(0, 1, 2, 4, Inf)), labels = F, right = T, include.lowest = T)))) +
scale_fill_continuous(name = 'count', labels = c('1', '2', '4', '8+'))
print(plot.df.log.cut)
