Seascape Skybox Hang Ten in HiFi


#1

** update **
v4 is live and tested.

{
	"ProceduralEntity": {
	"shaderUrl":"http://metaversecafe.com/HighFidelity/QueenCity/shaders/oceanSkybox_v4.fs"
	}

}

For those of you using the shader, v3 I have corrected the “horizon” angle so it is flat. This will be released early tomorrow EST/EDT as v4. Those of you that happen to have the source shader, replace the following:

vec3 ang = vec3(sin(time*3.0)*0.1,sin(time)*0.2+0.3,time);    

with this:

vec3 ang = vec3(0.0, 0.0, .5);

and you’ll get this…


note

// “Seascape” by Alexander Alekseev aka TDM - 2014
// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
https://creativecommons.org/licenses/by-nc-sa/3.0/

** this has been a “port” of a shader found on shadertoy **


Sea/Water rendering
#2

Looking at that image makes me sea sick. Its probably gonna be even worse with a rift. Maybe if you could stabilize that shader from shadertoy (aka, remove the camera movement) it would work fantastically.


#3

Infact, if you set the time to only use global time and remove the input, it should remain still :slight_smile:


#4

Better?

[quote=“Menithal”]Looking at that image makes me sea sick. [/quote] So you’ll admit that the original creator of the shader did a good job on realism. :wink:


#5

Yeah, definitely gotta add this to my domain!


#6

Well with the camera rotation in the original it was fine, it was just sped up like crazy in your version :smiley:


#7

Wuao, I was not expecting to see the ocean so early, looking amazing, just perfect.


#8

I did manipulate the code for this directly in shadertoy

// "Seascape" by Alexander Alekseev aka TDM - 2014 // License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.

const int NUM_STEPS = 16;
const float PI = 3.1415;
const float EPSILON = 1e-3;
float EPSILON_NRM = 0.8 / iResolution.x;

// sea
const int ITER_GEOMETRY = 1;
const int ITER_FRAGMENT = 5;
const float SEA_HEIGHT = 0.05;
const float SEA_CHOPPY = 1.6;
const float SEA_SPEED = 0.8;
const float SEA_FREQ = 0.16;
const vec3 SEA_BASE = vec3(0.21,0.81,0.81);
const vec3 SEA_WATER_COLOR = vec3(1.,1.3,1.0);
float SEA_TIME = iGlobalTime * SEA_SPEED;
mat2 octave_m = mat2(2.0,1.7,-1.7,2.0);

// math
mat3 fromEuler(vec3 ang) {
vec2 a1 = vec2(sin(ang.x),cos(ang.x));
vec2 a2 = vec2(sin(ang.y),cos(ang.y));
vec2 a3 = vec2(sin(ang.z),cos(ang.z));
mat3 m;
m[0] = vec3(a1.ya3.y+a1.xa2.xa3.x,a1.ya2.xa3.x+a3.ya1.x,-a2.ya3.x);
m[1] = vec3(-a2.y
a1.x,a1.ya2.y,a2.x);
m[2] = vec3(a3.y
a1.xa2.x+a1.ya3.x,a1.xa3.x-a1.ya3.ya2.x,a2.ya3.y);
return m;
}
float hash( vec2 p ) {
float h = dot(p,vec2(127.1,311.7));
return fract(sin(h)43758.5453123);
}
float noise( in vec2 p ) {
vec2 i = floor( p );
vec2 f = fract( p );
vec2 u = f
f*(3.0-2.0f);
return -1.0+2.0
mix( mix( hash( i + vec2(0.0,0.0) ),
hash( i + vec2(1.0,0.0) ), u.x),
mix( hash( i + vec2(0.0,1.0) ),
hash( i + vec2(1.0,1.0) ), u.x), u.y);
}

// lighting
float diffuse(vec3 n,vec3 l,float p) {
return pow(dot(n,l) * 0.4 + 0.6,p);
}
float specular(vec3 n,vec3 l,vec3 e,float s) {
float nrm = (s + 0.3) / (3.1415 * 0.3);
return pow(max(dot(reflect(e,n),l),0.0),s) * nrm;
}

// sky
vec3 getSkyColor(vec3 e) {
e.y = max(e.y,0.0);
vec3 ret;
ret.x = pow(1.0-e.y,2.0);
ret.y = 1.0-e.y;
ret.z = 0.6+(1.0-e.y)*0.4;
return ret;
}

// sea
float sea_octave(vec2 uv, float choppy) {
uv += noise(uv);
vec2 wv = 1.0-abs(sin(uv));
vec2 swv = abs(cos(uv));
wv = mix(wv,swv,wv);
return pow(1.0-pow(wv.x * wv.y,0.65),choppy);
}

float map(vec3 p) {
float freq = SEA_FREQ;
float amp = SEA_HEIGHT;
float choppy = SEA_CHOPPY;
vec2 uv = p.xz; uv.x *= 0.55;

float d, h = 0.0;    
for(int i = 0; i < ITER_GEOMETRY; i++) {        
	d = sea_octave((uv+SEA_TIME)*freq,choppy);
	d += sea_octave((uv-SEA_TIME)*freq,choppy);
    h += d * amp;        
	uv *= octave_m; freq *= 1.9; amp *= 0.22;
    choppy = mix(choppy,1.0,0.2);
}
return p.y - h;

}

float map_detailed(vec3 p) {
float freq = SEA_FREQ;
float amp = SEA_HEIGHT;
float choppy = SEA_CHOPPY;
vec2 uv = p.xz; uv.x *= 0.55;

float d, h = 0.0;    
for(int i = 0; i < ITER_FRAGMENT; i++) {        
	d = sea_octave((uv+SEA_TIME)*freq,choppy);
	d += sea_octave((uv-SEA_TIME)*freq,choppy);
    h += d * amp;        
	uv *= octave_m; freq *= 1.9; amp *= 0.22;
    choppy = mix(choppy,1.0,0.2);
}
return p.y - h;

}

vec3 getSeaColor(vec3 p, vec3 n, vec3 l, vec3 eye, vec3 dist) {
float fresnel = 1.0 - max(dot(n,-eye),0.0);
fresnel = pow(fresnel,1.0) * 0.65;

vec3 reflected = getSkyColor(reflect(eye,n));    
vec3 refracted = SEA_BASE + diffuse(n,l,80.0) * SEA_WATER_COLOR * 0.52; 

vec3 color = mix(refracted,reflected,fresnel);

float atten = max(1.0 - dot(dist,dist) * 0.001, 0.0);
color += SEA_WATER_COLOR * (p.y - SEA_HEIGHT) * 0.18 * atten;

color += vec3(specular(n,l,eye,0.50));

return color;

}

// tracing
vec3 getNormal(vec3 p, float eps) {
vec3 n;
n.y = map_detailed§;
n.x = map_detailed(vec3(p.x+eps,p.y,p.z)) - n.y;
n.z = map_detailed(vec3(p.x,p.y,p.z+eps)) - n.y;
n.y = eps;
return normalize(n);
}

float heightMapTracing(vec3 ori, vec3 dir, out vec3 p) {
float tm = 0.0;
float tx = 1000.0;
float hx = map(ori + dir * tx);
if(hx > 0.0) return tx;
float hm = map(ori + dir * tm);
float tmid = 0.0;
for(int i = 0; i < NUM_STEPS; i++) {
tmid = mix(tm,tx, hm/(hm-hx));
p = ori + dir * tmid;
float hmid = map§;
if(hmid < 0.0) {
tx = tmid;
hx = hmid;
} else {
tm = tmid;
hm = hmid;
}
}
return tmid;
}

// main
void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
vec2 uv = fragCoord.xy / iResolution.xy;
uv = uv * 2.0 - 1.0;
uv.x = iResolution.x / iResolution.y;
float time = iGlobalTime * 0.01 + iMouse.x
0.01;

// ray
vec3 ang = vec3(sin(time*3.0)*0.1,sin(time)*0.2+0.3,time);    
vec3 ori = vec3(0.0,3.5,time*5.0);
vec3 dir = normalize(vec3(uv.xy,-2.0)); dir.z += length(uv) * 0.15;
dir = normalize(dir) * fromEuler(ang);

// tracing
vec3 p;
heightMapTracing(ori,dir,p);
vec3 dist = p - ori;
vec3 n = getNormal(p, dot(dist,dist) * EPSILON_NRM);
vec3 light = normalize(vec3(0.0,1.0,0.8)); 
         
// color
vec3 color = mix(
    getSkyColor(dir),
    getSeaColor(p,n,light,dir,dist),
	pow(smoothstep(0.0,-0.08,dir.y),0.3));
    
// post
fragColor = vec4(pow(color,vec3(0.75)), 1.0);

}

This gives the following result which should increase FPS because I get to 12 to 14 FPS in interface loading the skybox on a fast pc.

When you go to the bottom of the skybox at -15000 metres you never meet the actual bottom or touch the ocean with your avatar so the skybox system is not a real solution.

But this is positive it shows decent water is close. Keep up the good job. I would like to see something on a cube surface as it would be more manageable instead of the bottom of a skybox. The FPS drop should be 0 or near zero as it is only water. I think the desire to have real looking sea with high waves is not for the near distance it drains resources in a huge manner.


#9

In interface skybox + ocean + avatar + build 17 FPS Sim rate 11 to 15 FPS substandard performance on localhost

In sandbox domain

performance 59 - 60 FPS stable same for sim rate and avatar simrate

I do have 60 FPS stable on using Google Chrome browser on the shadertoy website for this particular shaders. Many of the ocean shaders do cause significant frame drops on the shadertoy website so these can be described as resource consuming.


#10

If I put this shader into / onto an Entity will anybody use it?


#11

This might be more practical for having objects such as boats and whatnot sitting on a platform with this shader.


#12

I have a theoretical suggestion,

Instead of generating the noise maps, 3 or 4 of them pregenerated, This way you probably use less cpu, but more ram. should overall be faster.


#13

When you want to create a water shader on an entity it might be better to focus on something that people will be able to actually use. I think you will find better inspiration with minecraft GLSL shader mods compared to these experiments on the shadertoy website.

Also any ocean shader will require plenty of tests with all kinds of graphic cards to become something stable for people to use in their domains.

Take a look here https://www.shadertoy.com/view/ltsGWX#

Adjust Ichannel1 with some of the textures offered on the shadertoy site (this is water that might provide good results in terms of performance). Then put the code for the water on an entity and experiment with a water normal texture instead of Ichannel1 and some colors. I think you will be able to produce some good looking water which will keep frames up and people can use in their domains.


#14

Starting to experiment with the sample

This is the code

float noise(in vec2 p) {
return texture2D(iChannel1, p / 256.0, -50.0).x;
}

float fBm(in vec2 p) {
float sum = 0.0;
float amp = 0.5;
for(int i = 0; i < 5; i++) {
sum += amp * noise§;
amp *= 0.5;
p *= 2.0;
}
return sum * 0.06;
}

float raymarchWater(in vec3 ro, in vec3 rd, in float tmin, in float tmax) {
float t = tmin;
for (int i = 0; i < 70; i++) {
vec3 p = ro + rd * t;
float d = p.y - fBm(vec2(p.xz + iGlobalTime));
if (d < (0.001 * t) || t > tmax)
break;
t += 0.2 * d;
}
return t;
}

vec3 getWaterNormal(in vec3 p, float t) {
float eps = 0.012;
return normalize(vec3(fBm(vec2(p.x - eps, p.z)) - fBm(vec2(p.x + eps, p.z)),
3.0 * eps,
fBm(vec2(p.x, p.z - eps)) - fBm(vec2(p.x, p.z + eps))));
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 p = (-iResolution.xy + 1.0 * fragCoord.xy) / iResolution.xy;

vec3 eye = vec3(0.0, 2.0, -1.0);
vec2 rot = 5.2831 * (vec2(0.0, 0.0) + vec2(1.0, 0.0) * (iMouse.xy - iResolution.xy * 0.25) / iResolution.x);
eye.yz = cos(rot.y) * eye.yz + sin(rot.y) * eye.zy * vec2(-1.0, 1.0);
eye.xz = cos(rot.x) * eye.xz + sin(rot.x) * eye.zx * vec2(1.0, -1.0);

vec3 ro = eye;
vec3 ta = vec3(0.5, 2.3, 0.0);

vec3 cw = normalize(ta - eye);
vec3 cu = normalize(cross(vec3(0.0, 1.0, 0.0), cw));
vec3 cv = normalize(cross(cw, cu));
mat3 cam = mat3(cu, cv, cw);

vec3 rd = cam * normalize(vec3(p.xy, 1.0));

vec3 col = textureCube(iChannel0, rd).xyz;
float tmin = 0.1;
float tmax = 24.0;
float t = raymarchWater(ro, rd, tmin, tmax);
if (t > tmin && t < tmax) {
    vec3 pos = ro + rd * t;
    pos += iGlobalTime * 0.18;

    vec3 nor = getWaterNormal(pos, t);

    float F = 0.86;
    float fre = F + (0.30 - F) * pow(1.04 - dot(nor, -rd), 8.0);
    vec3 refl = reflect(rd, nor);
    vec3 refr = refract(rd, nor, 0.22);
    vec3 rgb = textureCube(iChannel0, refl).xyz;
    col = mix(vec3(0.28,1.7,1.2), (0.77 - fre) + rgb * fre, fre);
    rgb = textureCube(iChannel0, refr).xyz;
    col = mix(col, rgb, 0.08);
    col = mix(col, smoothstep(0.0, 1.0, col), 0.8);
}

fragColor = vec4(col,0.2);

}

Running this in shadertoy is 60 FPS and full screen also does not display a noticeable reduction in frames. I would be interested to see this on an entity and in combination with a water normal map instead of the noise texture, that would improve this water a lot I think.


#15

Question: Are you placing this on a actual entity or is this still skybox linked?


#16

Mine is still tied to a skybox. I haven’t integrated to a normal box entity yet. I have no “ownership” to that assignment and if someone wants to get to it first; be my guest. :wink: :smiley:


#17

I like the water you provided in the link above.

https://www.shadertoy.com/view/ltsGWX#

I will see what can be done. Thanks.


#18

I am not a programmer but from what I see in the code this should provide you with good code to make a functional ocean shader. What lacks from what I could tell is an opacity setting and the normal map.

Once it is working on an entity I think more work will be needed to make this function smooth with several graphic cards inside of interface.

What would also be interesting later is to add ocean fog below the surface using the entity but for now the water is the main.

I did notice this in the code:

vec3 refl = reflect(rd, nor);
vec3 refr = refract(rd, nor, 0.22);

Reflect does not allow you to put in a setting, has this been left out or is it supposed to be like that? What if you could turn off reflection would that make it more easy on a system in terms of rendering?

When you adjust these kinds of settings in the Second Life viewer it is more easy on your graphics card. Based on that it would be interesting when you could tweak how resource consuming you want your shader to be in your scene.

I will test when you have this working on an entity.

Thanks


#19

Can anybody please offer a current fix for these scripts, they are all throwing “one of the shaders is not compiled” error

I would like to get some water happening but not sure where its going wrong.

I have one working procedural water script but it looks very cartoony and some of these pictured here look really good and I would like to get them working.

Thanks


#20

I noticed this yesterday. You might be running an older version of the domain Console. Here is a shot using latest Interface on latest Console:

Oddly enough: you have to have an asset assigned to the “Skybox URL” even if you are using a procedural shader.