11
\$\begingroup\$

I needed a Minecraft-like stone texture, instead of creating it using image editing software I decided to generate one using R.

The idea is to create some noise and stretch it horizontally so the texture tends to have some horizontal lines.

Example output (this example is upscaled, the original file is 32x32 pixels):

enter image description here

My questions are: What do you dislike about this code? Are the libraries 'ambient' and 'png' necessary, or does R have appropriate functionality builtin?

I'm also wondering if there are ways to improve the output. One issue I have with my current approach is that the resolution on the x-axis is effectively halved. Is there a way to get the horizontal highlights without doing that.

The package ambient is used to create the Perlin noise, and the package png is used to create a low resolution PNG image.

library(ambient)
library(png)

size <- 32

# data is in a 1:2 ratio.
data <- noise_perlin(dim=c(size, size / 2), frequency=0.9)

min <- 0.1
max <- 0.6

# data's bound is -1 to 1, transform that into a bound of min to max.
inrange <- min + ((data + 1) / 2) * (max - min)

# turn into 1:1 ratio by repeating columns.
stretched <- inrange[, rep(1:(ncol(inrange)), each=2)]

writePNG(target="stone.png", image=stretched)
\$\endgroup\$
1
  • \$\begingroup\$ Can you elaborate what you mean by highlights? \$\endgroup\$
    – Roman
    Commented Nov 21, 2021 at 2:47

1 Answer 1

1
\$\begingroup\$

If I understand you correctly: Maybe you could just add a finer layer on top?

1

size <- 32

# data is in a 1:2 ratio.
data <- noise_perlin(dim=c(size, size / 2), frequency = 0.9)
# data is in a 1:1 ratio.
data2 <- noise_perlin(dim=c(size, size), frequency = 0.9)

min <- 0.1
max <- 0.6
# a bit less variance
min2 <- 0.0
max2 <- 0.2

# data's bound is -1 to 1, transform that into a bound of min to max.
inrange <- min + ((data + 1) / 2) * (max - min)
inrange2 <- min2 + ((data2 + 1) / 2) * (max2 - min2)

# turn into 1:1 ratio by repeating columns.
stretched <- inrange[, rep(1:(ncol(inrange)), each = 2)]
# combine native 1:1 and stretched 1:2 data
combined <- inrange2 + stretched  

# write PNG
writePNG(target="stone.png", image = combined)
\$\endgroup\$
1
  • \$\begingroup\$ You have presented an alternative solution, but haven't reviewed the code. Please edit to show what aspects of the question code prompted you to write this version, and in what ways it's an improvement over the original. It may be worth (re-)reading How to Answer. \$\endgroup\$ Commented Nov 21, 2021 at 13:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.