ah ben le non-rayon c'est mon-linéaire

pour une normal d'un terrain 2D y a dans la même boucle qu'une convolution mais en plus couteux, un calcule de moyenne en cercle , c'est pas comme un blur mais presque ça devrait brisé les verticales et horizontales comme des métaballes qui font l'amours,
même un calcule d'intégrale pour les profondeurs hypothétique est assez linéaire,
Les normals de mes maps chaos en relief j'avais fait simple , juste un plant par un triangle vectoriel, ce qui est déjà
très bonvar pic = relief*this.M[r][u][0];
var v1 = v3_( 1, 0, relief*this.M[r+1][u][0] - pic );
var v2 = v3_( 0, 1, relief*this.M[r][u+1][0] - pic );
var vn = v1.VN(v2);
var pp = v3_( r-this.wd, u-this.hd, pic );
var g = vn.produit( lig.Nc(pp) );
avec :
N: function(){//normalise
var g = Math.sqrt( this.x*this.x + this.y*this.y + this.z*this.z );//this.d(v3_(0,0,0));
if( g != 0 ){ [this.x,this.y,this.z] = [this.x/g,this.y/g,this.z/g] }
},
VN: function(b){// calcule de la Normal d'un plan défini par 2 vect3, soit une face
//var [X1,Y1,Z1, X2,Y2,Z2, X3,Y3,Z3] =
//[0,0,0, this.x,this.y,this.z, b.x,b.y,b.z];
//[a.x,a.y,a.z,b.x,b.y,b.z,c.x,c.y,c.z];
/*var v1 = this.new(),//v3_( X2-X1 , Y2-Y1 , Z2-Z1 );
v2 = b.new();//v3_( X3-X1 , Y3-Y1 , Z3-Z1 );
var asx = v1.y*v2.z - v1.z*v2.y;
var bsx = v1.z*v2.x - v1.x*v2.z;
var csx = v1.x*v2.y - v1.y*v2.x;
//dsx = -v1.y*v2.z*X1 -v1.z*v2.x*Y1 -v1.x*v2.y*Z1 +v1.y*v2.x*Z1 +v1.z*v2.y*X1 +v1.x*v2.z*Y1;
var vn = v3_(asx ,bsx ,csx);*/
var vn = new vect3(
this.y*b.z - this.z*b.y ,
this.z*b.x - this.x*b.z ,
this.x*b.y - this.y*b.x );
vn.N();
return vn
},
améliorable selon moi ( pas testé encore )

avec un algo comme décrit plus haut
vec4 moyen_img(vec2 v){
float t,r;
vec4 s,k;
vec2 a;
for(int i=0; i<5; i++){
t = float(i)/5.*PI2;
for(int u=1; u<=5; u++){
r = float(u)/5.;
a = vec2(v.x+cos(t)*r/textureSize.x,
v.y+sin(t)*r/textureSize.y);
s = texture2D(img, a);
k.xyz+=s.xyz*r;
}
}// k/(iter*(iter+1)/2)
return vec4(k.xyz/15.,s.w);
}
en prenant des points dans la zone interne du pixel, .5 pr être rapide
ou encore en faisant un bouquet(randomisation) de triangle qui donne un ensemble de normal approximative , puis reste juste à faire la moyenne de toute ces normals... ça peut soigné l'apparence dérivative de la surface ,
évidement texture2D( shader return des valeurs déjà interpoler vite fait ce qui améliore l’efficacité ,
sur CPU je passais aussi par une sous interpolation seulement linéaire c'était potable ,
moyen_carre: function(v,M,iter){
var t,k = 0,r,vi, a,x,y,x2,y2,x1;
var li = v_(M.length-1,M[0].length-1);
for(var i=0; i<iter; i++){//calcule un cercle de point de brouillar
t = i/iter*PI2;
for(var u=1; u<=iter; u++){
r = u/iter;
//k += this.carre( v_( v.x+Math.cos(t)*r , v.y+Math.sin(t)*r ) ,M)*r;
a = new vect2(cadr(v.x+Math.cos(t)*r,0,li.x),//encadrement
cadr(v.y+Math.sin(t)*r,0,li.y));
x = Math.floor(a.x); x2 = Math.min(x+1,li.x);
y = Math.floor(a.y); y2 = Math.min(y+1,li.y);
a.x-=x; a.y-=y;
x1= 1-a.x;
k += ((M[x][y] *x1 + M[x2][y] *a.x)*(1-a.y) +
(M[x][y2]*x1 + M[x2][y2]*a.x)*a.y )*r;
}
}
return k/(iter*(iter+1)/2)
},
que des barycentres à la tarzan ,
si c'est bien là ce que tu cherchais , par ce que pour ça faut partir d'une map de profondeur ,