Skip to content

Commit 88072a7

Browse files
committed
Earth shader rework, use passed height range for calc
Calculate the correct height range based on vertical exaggeration and pass to the shader. Rewrote the shader bathymetry colouring code.
1 parent b257fbb commit 88072a7

File tree

2 files changed

+53
-36
lines changed

2 files changed

+53
-36
lines changed

src/accessvis/earth.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,7 @@ def cubemap_sphere_vertices(radius=1.0, resolution=None, heightmaps=None, vertic
361361
os.makedirs(settings.DATA_PATH / 'sphere', exist_ok=True)
362362

363363
#For each cube face...
364+
minmax = []
364365
for f in ['F', 'R', 'B', 'L', 'U', 'D']:
365366
if f in cdata:
366367
verts = cdata[f]
@@ -391,11 +392,16 @@ def cubemap_sphere_vertices(radius=1.0, resolution=None, heightmaps=None, vertic
391392
if heightmaps:
392393
#Apply radius and heightmap
393394
verts *= (heightmaps[f] * vertical_exaggeration + radius)
395+
minmax += [heightmaps[f].min(), heightmaps[f].max()]
394396
else:
395397
#Apply radius only
396398
verts *= radius
397399
sdata[f] = verts
398400

401+
#Save height range
402+
minmax = np.array(minmax)
403+
sdata['range'] = (minmax.min(), minmax.max())
404+
399405
#Save compressed un-scaled vertex data
400406
if cache:
401407
np.savez_compressed(fn, **cdata)
@@ -639,6 +645,13 @@ def plot_earth(lv=None, radius=6.371, vertical_exaggeration=10, texture='bluemar
639645
uniforms["wavenormal"] = ""
640646
uniforms["waves"] = waves;
641647

648+
#Pass in height range of topography as this is dependent on vertical exaggeration
649+
#Convert metres to Mm and multiply by vertical exag
650+
#hrange = np.array([-10952, 8627]) * 1e-6 * vertical_exaggeration
651+
hrange = np.array(topo['range']) * vertical_exaggeration
652+
uniforms["heightmin"] = hrange[0];
653+
uniforms["heightmax"] = hrange[1];
654+
642655
if shaders is None:
643656
shaders = [f'{settings.INSTALL_PATH}/earth_shader.vert', f'{settings.INSTALL_PATH}/earth_shader.frag']
644657

src/accessvis/earth_shader.frag

Lines changed: 40 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,13 @@ uniform float blendFactor = -1.0;
3535
uniform sampler2D data;
3636
uniform int dataMode = -1; //-1 = don't plot, 0 = plot everywhere, 1 = plot on ocean, 2 = plot on land
3737
uniform float dataAlpha = 0.0;
38-
uniform vec4 ocean; //Ocean colour override
38+
uniform vec4 ocean = vec4(0.0, 0.0, 0.0, 1.0); //Ocean colour override
39+
uniform float depthColour = 2.0; //Power of bathymetry depth on ocean colour, 0=None, 1=linear, 2=^2 etc
3940
uniform bool waves = false;
4041
uniform bool bathymetry = false;
42+
//Topo/bathy range
43+
uniform float heightmin;
44+
uniform float heightmax;
4145

4246
//Allow differing brightness,contrast,saturation over ocean
4347
uniform float ocean_brightness = 0.0;
@@ -130,8 +134,6 @@ if (blendFactor >= 0.0)
130134
//if ((fColour.z > 0.5 && fColour.x < 0.3 && fColour.y > 0.3)) // || (fColour.x * fColour.y * fColour.z > 0.25))
131135

132136
//Ocean/land mask, baked into colour texture alpha channel
133-
//vec4 Colour = texture(uTexture, vTexCoord);
134-
//mask = Colour.a;
135137
bool water = mask <= 0.7;
136138
//bool water = mask >= 0.85 && depth <= 1.0;
137139
//Water calc for shaded relief textures
@@ -151,38 +153,56 @@ if (blendFactor >= 0.0)
151153
//N = normalize(vVertex);
152154
//Flatten normal
153155
N = normalize(mat3(uNMatrix) * normalize(vVertex));
154-
//outColour = vec3(1.0, 0.0, 0.0, 1.0);
155-
//return;
156156
}
157157

158158
if (water && !snow) //Sea-level ice fix, don't apply water shading
159159
{
160160
//Bathymetry is included in topo data
161-
//With x10 vertical exaggeration, bathymetry max is -10952M in Mm range [-0.10952,0]
162-
//TODO: FIX THIS, V_EXAG IS NOT HARD CODED, PASS IN HEIGHT MIN/MAX AS UNIFORM !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
163-
float DMIN = -0.104809;
164-
float depth = 1.0 - ((vlen - radius) / DMIN);
161+
//Normalised depth [0,1] where 0 is sea level
162+
float depth = ((vlen - radius) / (heightmin));
163+
164+
//Calculate the ocean colour
165+
//if (bluemarble)
165166
if (!bathymetry)
166167
{
167-
//Plotting ocean as surface, blend bathymetry with earth texture based on depth to
168-
//show sense of water depth and some blurred bathymetry detail only
168+
//blend bathymetry with earth texture based on depth to
169+
//show sense of water depth and some blurred bathymetry detail
169170

170-
//Remove detail of lower depths by clamping to upper range
171-
float depth2 = clamp(depth, 0.6, 1.0) - 0.4;
171+
//Remove detail of lower depths by clamping to upper range
172+
float depth2 = clamp(pow(1.0-depth, depthColour), 0.6, 1.0) - 0.4;
173+
//float depth2 = pow(1.0-depth, 2*depthColour);
172174

173-
//Default ocean colour
175+
//Default ocean colour, not used unless explicitly set
174176
vec3 c3 = ocean.rgb;
175177
float blend = ocean.a;
176-
if (blend == 0.0)
178+
if (blend == 0.0 || ocean.rgb == vec3(0.0, 0.0, 0.0))
177179
{
180+
//Ignore flat colour
178181
c3 = vec3(40/255.0, 0.4 + min(depth2, 0.6), 255/255.0);
179182
blend = 0.2 * depth2;
180183
if (!waves)
181184
blend = 0.15 * depth2;
182185
}
183-
//c3 = clamp(c3, 0.0, 1.0);
186+
else
187+
{
188+
//Blend bathymetry with fixed ocean colour
189+
c3 = mix(fColour.rgb*depth2, ocean.rgb, depth2);
190+
}
191+
184192
fColour.rgb = mix(fColour.rgb, c3, blend);
193+
}
194+
else
195+
{
196+
//Flat ocean colour
197+
float depth2 = pow(1.0-depth, depthColour);
198+
vec3 c3 = ocean.rgb * pow(1.0-depth, depthColour);
199+
float blend = clamp(ocean.a*sqrt(depth), 0.0, 1.0); //1.0; //depth; //ocean.a * depth;
200+
fColour.rgb = mix(fColour.rgb, c3, blend);
201+
}
185202

203+
//Plotting ocean as surface
204+
if (!bathymetry && waves)
205+
{
186206
//Apply ocean texture
187207
if (waves)
188208
{
@@ -203,7 +223,7 @@ if (blendFactor >= 0.0)
203223

204224
//vec2 uv = vTexCoord;
205225
//Repeated tiling
206-
uv = fract(uv * 15.0 + float(uFrame) * 0.005);
226+
uv = fract(uv * 25.0 + float(uFrame) * 0.005);
207227
vec4 wavetex = texture(wavetex, uv);
208228
//Apply normal map in tangent space with TBN matrix
209229
//vec3 waveN = texture(wavenormal, uv).xyz;
@@ -226,42 +246,26 @@ if (blendFactor >= 0.0)
226246
if (mask < 0.55)
227247
{
228248
//As depth increases, show higher waves
229-
float wavesize = 0.5 * (1.0-depth);
249+
float wavesize = 0.5 * (depth);
230250
//N = mix(N3, N, min(1.25*depth, 1.0));
231251
N = normalize(mix(N, N3, wavesize));
232252
//N = mix(N3, N, depth);
233253
//fColour.rgb = N;
234254
}
235-
236-
237255
}
238256

239257
//Enhance ocean when using darker texture
240258
if (bluemarble)
241259
{
242260
float mul = waves ? 1.0 : 0.5;
243-
saturation = 1.0 + pow(mul*clamp(depth, 0.0, 1.0), 3.0);
261+
saturation = 1.0 + pow(mul*clamp(1.0-depth, 0.0, 1.0), 3.0);
244262
contrast *= 1.05;
245263
}
246264

247265
brightness = ocean_brightness > 0.0 ? ocean_brightness : brightness;
248266
contrast = ocean_contrast > 0.0 ? ocean_contrast : contrast;
249267
saturation = ocean_saturation > 0.0 ? ocean_saturation : saturation;
250268
}
251-
else
252-
{
253-
//Default ocean colour
254-
vec3 c3 = ocean.rgb;
255-
float blend = ocean.a;
256-
if (blend == 0.0)
257-
{
258-
c3 = vec3(40/255.0, 0.4 + 0.5*depth, 255/255.0);
259-
blend = depth;
260-
}
261-
else
262-
blend = depth * blend;
263-
fColour.rgb = mix(fColour.rgb, c3, blend);
264-
}
265269
}
266270

267271
#define PI 3.1415926
@@ -319,7 +323,7 @@ if (blendFactor >= 0.0)
319323
//(Single sided lighting only)
320324
float diffuse = max(dot(N, lightDir), 0.0);
321325

322-
if (water) // && waves)
326+
if (water && !bathymetry) // && waves)
323327
{
324328
//Increase specular highlights over water
325329
//TODO: uniform variable for this factor

0 commit comments

Comments
 (0)