dwadwad

wdww

Shader code
/*
	Original shader by mrange (https://www.shadertoy.com/view/csfXzN)
	Godot 3.5 port with customizable parameters by PmkExpert
	As much as possible of the original has been kept, including comments
	
	MIT License

*/

// License CC0: Sea and moon
//  Tinkering with the colors of an old shaders to make it a better fit for windows terminal

shader_type canvas_item;

const float PI = 3.141592654;
//const float TAU = 6.283185308;

//Kept the original names, but they mostly change the waves' speed
uniform float gravity : hint_range(0.0,25.0) = 1.0;
uniform float waterTension : hint_range(0.0,10.0) = 0.01;

//Generally, the shader is dark, so some colors have less effect than others overall
uniform vec4 skyCol1 : hint_color = vec4(0.6, 0.35, 0.3, 1.0);
uniform vec4 skyCol2 : hint_color = vec4(1.0, 0.3, 0.3, 1.0);
uniform vec4 sunCol1 : hint_color = vec4(1.0, 0.5, 0.4, 1.0);
uniform vec4 sunCol2 : hint_color = vec4(1.0, 0.8, 0.8, 1.0);
uniform vec4 seaCol1 : hint_color = vec4(0.1, 0.2, 0.2, 1.0);
uniform vec4 seaCol2 : hint_color = vec4(0.2, 0.9, 0.6, 1.0);

//New uniforms made of values from the code for easier customization
uniform float sunPosX : hint_range(-1.5,1.5) = 0.0; //The celestial body's position
uniform float sunPosY : hint_range(-0.6,0.4) = 0.06; //The celestial body's altitude
uniform float Zoom : hint_range(0.5,20.0) = 2.5; //How much close is the horizon
uniform float sunShine : hint_range(0.1,100.0) = 1.0; //The amount of light emitted
uniform float sunSize : hint_range(0.1,100.0) = 1.0; //Can make it appear better under sea level than sunPos
uniform int seaNoise : hint_range(1,20) = 8; //Makes the sea appear differently
uniform int crestSize : hint_range(1,20) = 4; //How big the waves' crests look
uniform float seaLevel : hint_range(-0.5,0.5) = -0.1; //The horizon's level
//Some other values in the code can be changed for different effects, but their behavior is less predictable

// License: Unknown, author: Unknown, found: don't remember
float tanh_approx(float x) {
  //  Found this somewhere on the interwebs
  //  return tanh(x);
  float x2 = x*x;
  return clamp(x*(27.0 + x2)/(27.0+9.0*x2), -1.0, 1.0);
}

vec2 wave(in float t, in float a, in float w, in float p) {
  float x = t;
  float y = a*sin(t*w + p);
  return vec2(x, y);
}

vec2 dwave(in float t, in float a, in float w, in float p) {
  float dx = 1.0;
  float dy = a*w*cos(t*w + p);
  return vec2(dx, dy);
}

vec2 gravityWave(in float t, in float a, in float k, in float h) {
  float w = sqrt(gravity*k*tanh_approx(k*h));
  return wave(t, a ,k, w*TIME);
}

vec2 capillaryWave(in float t, in float a, in float k, in float h) {
  float w = sqrt((gravity*k + waterTension*k*k*k)*tanh_approx(k*h));
  return wave(t, a, k, w*TIME);
}

vec2 gravityWaveD(in float t, in float a, in float k, in float h) {
  float w = sqrt(gravity*k*tanh_approx(k*h));
  return dwave(t, a, k, w*TIME);
}

vec2 capillaryWaveD(in float t, in float a, in float k, in float h) {
  float w = sqrt((gravity*k + waterTension*k*k*k)*tanh_approx(k*h));
  return dwave(t, a, k, w*TIME);
}

void mrot(inout vec2 p, in float a) {
  float c = cos(a);
  float s = sin(a);
  p = vec2(c*p.x + s*p.y, -s*p.x + c*p.y);
}

vec4 sea(in vec2 p, in float ia) {
  float y = 0.0;
  vec3 d = vec3(0.0);

  int maxIter = seaNoise;
  int midIter = crestSize;

  float kk = 1.0/1.3;
  float aa = 1.0/(kk*kk);
  float k = 1.0*pow(kk, -float(maxIter) + 1.0);
  float a = ia*0.25*pow(aa, -float(maxIter) + 1.0);

  float h = 25.0;
  p *= 0.5;
  
  vec2 waveDir = vec2(0.0, 1.0);

  for (int i = midIter; i < maxIter; ++i) {
    float t = dot(-waveDir, p) + float(i);
    y += capillaryWave(t, a, k, h).y;
    vec2 dw = capillaryWaveD(-t, a, k, h);
    
    d += vec3(waveDir.x, dw.y, waveDir.y);

    mrot(waveDir, PI/3.0);

    k *= kk;
    a *= aa;
  }
  
  waveDir = vec2(0.0, 1.0);

  for (int i = 0; i < midIter; ++i) {
    float t = dot(waveDir, p) + float(i);
    y += gravityWave(t, a, k, h).y;
    vec2 dw = gravityWaveD(t, a, k, h);
    
    vec2 d2 = vec2(0.0, dw.x);
    
    d += vec3(waveDir.x, dw.y, waveDir.y);

    mrot(waveDir, -step(2.0, float(i)));

    k *= kk;
    a *= aa;
  }

  vec3 t = normalize(d);
  vec3 nxz = normalize(vec3(t.z, 0.0, -t.x));
  vec3 nor = cross(t, nxz);

  return vec4(y, nor);
}

vec3 sunDirection() {
  vec3 dir = normalize(vec3(sunPosX, sunPosY, 1));
  return dir;
}

vec3 skyColor(in vec3 rd) {
  //Added code to change the colors to be modifiable shader params
  vec3 skyCol1_ = skyCol1.xyz * 0.5;
  vec3 skyCol2_ = skyCol2.xyz * 0.5;
  
  vec3 sunDir = sunDirection();
  float sunDot = max(dot(rd, sunDir), 0.0);
  vec3 final = vec3(0.0);
  final += mix(skyCol1_, skyCol2_, rd.y);
  final += 0.5*sunCol1.rgb*pow(sunDot, 90.0 / sunShine);
  final += 4.0*sunCol2.rgb*pow(sunDot, 900.0 / sunSize);
  return final;
}

vec3 render(in vec3 ro, in vec3 rd) {
  //Added code to change the colors to be modifiable shader params
  vec3 seaCol1_ = seaCol1.rgb * 0.2;
  vec3 seaCol2_ = seaCol2.rgb * 0.5;
  
  vec3 col = vec3(0.0);

  float dsea = (0.0 - ro.y)/rd.y;
  
  vec3 sunDir = sunDirection();
  
  vec3 sky = skyColor(rd);
  
  if (dsea > 0.0) {
    vec3 p = ro + dsea*rd;
    vec4 s = sea(p.xz, 1.0);
    float h = s.x;    
    vec3 nor = s.yzw;
    nor = mix(nor, vec3(0.0, 1.0, 0.0), smoothstep(0.0, 200.0, dsea));

    float fre = clamp(1.0 - dot(-nor,rd), 0.0, 1.0);
    fre = fre*fre*fre;
    float dif = mix(0.25, 1.0, max(dot(nor,sunDir), 0.0));
    
    vec3 refl = skyColor(reflect(rd, nor));
    vec3 refr = seaCol1_ + dif*sunCol1.rgb*seaCol2_*0.1; 
    
    col = mix(refr, 0.9*refl, fre);
    
    float atten = max(1.0 - dot(vec2(dsea),vec2(dsea)) * 0.001, 0.0);
    col += seaCol2_*(p.y - h) * 2.0 * atten;
    
    col = mix(col, sky, 1.0 - exp(-0.01*dsea));
    
  } else {
    col = sky;
  }
  
  return col;
}

void fragment() {
  vec2 q = FRAGCOORD.xy/(1.0 / SCREEN_PIXEL_SIZE).xy;
  vec2 p = -1. + 2. * q;
  p.x *= (1.0 / SCREEN_PIXEL_SIZE).x/(1.0 / SCREEN_PIXEL_SIZE).y;

  vec3 ro = vec3(0.0, 10.0, 0.0);
  vec3 ww = normalize(vec3(0.0, seaLevel, 1.0));
  vec3 uu = normalize(cross( vec3(0.0,1.0,0.0), ww));
  vec3 vv = normalize(cross(ww,uu));
  vec3 rd = normalize(p.x*uu + p.y*vv + Zoom*ww);

  vec3 col = render(ro, rd);

  COLOR.rgb = vec3(col);
  COLOR.a = texture(TEXTURE, UV).a;
}
Tags
Moon shader
The shader code and all code snippets in this post are under CC0 license and can be used freely without the author's permission. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments