Try this:
m = tcrossprod(sin(seq(0,pi,length=1e2)), cos(seq(0, 3*pi, length=1e2)))
cols = matrix(hcl(h=scales::rescale(m, c(0, 360))), nrow(m))
grid::grid.raster(cols)
You'll need to find which function describes the colour gradient that you want (I used sine waves for illustration).
Edit: linear interpolation between 4 corners
library(grid)
library(scales)
m = tcrossprod(seq(1,2,length=1e2), seq(2, 3, length=1e2))
pal <- gradient_n_pal(c("red","green","yellow","blue"), values = c(2, 3, 4, 6), space = "Lab")
cols = matrix(pal(m), nrow(m))
grid.raster(cols)
Edit 2: When the function is not separable, use outer,
fun_xy <- function(x, y){
abs(y-x) * abs(y+x)
}
z <- outer(seq(-1,1,length=100), seq(-1,1,length=100), FUN = fun_xy)
cols = matrix(hcl(h=scales::rescale(z, c(0, 200))), nrow(z))
grid::grid.raster(cols)
You can also do the colour mixing directly inside the function instead of mapping values to a colour scale afterwards,
fun_xy <- function(x, y){
R <- (x+1)/2
G <- (1-x)/2
B <- (y+1)/2
A <- 1- 0.5*exp(-(x^2+y^2)/0.2)
rgb(R, G, B, A)
}
z <- outer(seq(-1,1,length=100), seq(-1,1,length=100), FUN = fun_xy)
library(grid)
grid.newpage()
grid::grid.raster(z)