

uniform float vNoiseFactor;
uniform float vNoiseScale;
uniform float vNoiseShift;
uniform float vTerrainNoiseShift;

uniform sampler2D s_NoiseRGBA;

#define SC 2.0
//const mat3 m2 = mat3(0.8,-0.6,0.6,0.8, 0.4, -0.3, 0.3, 0.4, 0.2);
const mat3 m2 = mat3(0.8,-0.6,0.0,0.8, 0.4, 0.0, 0.0, 0.0, 1.0);

float noise_fast(in vec3 x)
{
    vec3 p = floor(x);
    vec3 f = fract(x);
	f = f*f*(3.0-2.0*f);
	#if 1
	vec2 uv = (p.xy+vec2(37.0,17.0)*p.z) + f.xy;
	vec2 rg = texture(s_NoiseRGBA, (uv+ 0.5)/256.0).yx;
	#else
	vec2 uv = (p.xy+vec2(37.0,17.0)*p.z);
	vec2 rg1 = texture( s_NoiseRGBA, (uv+ vec2(0.5,0.5))/256.0).yx;
	vec2 rg2 = texture( s_NoiseRGBA, (uv+ vec2(1.5,0.5))/256.0).yx;
	vec2 rg3 = texture( s_NoiseRGBA, (uv+ vec2(0.5,1.5))/256.0).yx;
	vec2 rg4 = texture( s_NoiseRGBA, (uv+ vec2(1.5,1.5))/256.0).yx;
	vec2 rg = mix( mix(rg1,rg2,f.x), mix(rg3,rg4,f.x), f.y );
	#endif
	return mix( rg.x, rg.y, f.z ) * 2.0 - 1.0;
}


vec3 deform_terrain(vec3 pos, vec3 normal, float strength)
{
	if (strength == 0.0)
		return pos;

	//strength = 0.0;

	vec3 x = (pos + vec3(0.0, 0.0, vTerrainNoiseShift)) * vNoiseScale;
	vec3  p = x;
    float a = 0.0;
    float b = 1.0;
	vec3  d = vec3(0.0);
	// NOTE: was 15 but it adds too much high freq detail which is amplified when moving....
    for( int i=0; i<8; i++ )
    {
	#if 0
        vec3 n = vec3(snoise(p), snoise(p + 0.1123), snoise(p - 0.01124));
	#else
		vec3 n = vec3(noise_fast(p), noise_fast(p + 0.1123), noise_fast(p - 0.01124));
	#endif
        d += n.yzx;
        a += b*n.x/(1.0+dot(d,d));
        b *= 0.5;
        p = p*2.0;
		//p = m2*p*2.0;
    }

	float noise = a;
	noise = smoothstep(0.0, 1.0, noise);

	pos = pos + normal * strength * (noise * vNoiseFactor); 

	return pos;
}
