1
0
Fork 0

WS30 : terrain shaders from vs

Squashed commit of the following:

commit e7c89ffb600d1bf5cee2936b7dbff31089452745
Author: vs <vs2009@mail.com>
Date:   Fri Nov 5 23:44:35 2021 +1000

    WS30 shaders:

    - WS30-ALS and WS30-ALS-ultra fargment and vertex shaders: Fix NDotL being used before it is initialised. Rename varying diffuse_term from WS2 terrain shaders to light_diffuse_comp as the full diffuse term is not calculated until the fragment shader.
    - WS30-ALS-ultra.frag: Enable haze and lighting by default.

commit 9b55ad051a8d7f3568dfdcd6890655942999e8d0
Author: vs <vs2009@mail.com>
Date:   Wed Nov 3 22:50:29 2021 +1000

    WS30 terrain shaders: ws30-ALS-ultra.frag

    - For power users looking to profile transitions on different GPUs: The test phase toggles and settings for different transition options are available at the start of ws30-ALS-ultra.frag, along with explanations, and how to get accurate profile results on different GPUs. Just need to change a few numbers, save, and debug menu > configure dev extensions > reload shaders to activate.

    - Note: at a minimum, small scale transitions to remove the 'squareness' due to the landclass texture need to be used even on old GPUs.

    - All transition options are off by default. ws30-ALS-ultra.frag is active when the terrain quality slider is set to Ultra. Start by turning one of small or large scale transitions.

    - Texture mixing for small and large scale transitions don't work together, to reduce texture lookups. Turn one off when using the other.

    - Landclasses with contrasting colours make transition issues more visble. The driver control panel texture filtering settings reduces issues with seams at landclass borders.

    - ws30-ALS.frag is left untouched in this commit, for comparison and reviewing. ws30-ALS.frag is active when terrain quality slider is set High to Low.

    Changes:

    - Implement large scale transitions and small scale de-pixelisation of landclasses by searching the landclass texture. Several options and quality levels are available for profiling on different GPUs.
    - There are fixes for multiple issues dealing with texture rendering.

    Changelog:

    1.0 - Small-scale transitions:
    -- a) Remove squareness due to landclass texture by growing neighbour landclasses onto others depending on a growth priority. This feature uses 2 landclass texture lookups, 1 noise lookup, and only 1 ground texture lookup per point. For now the growth priority is simply the landclass id number. If this approach is used, growth priority would be a materials parameter. A way to set default growth priority by landclass via an xml file would be needed. There is flickering noise at long ranges due to small scale detail in the noise function used for growing landclasses. Partial derivative are used to turn off the feature, but turning off the feature too quickly still shows some square ness in distant landclasses.
    -- b) Reduce squareness due to landclass texture by mixing base textures of neighbouring landclasses. This is not perfect, as perfectly square shapes turn into perfectly square shapes with perfectly smudged edges. This uses 2 landclass texture lookups, and 2-3 ground texture lookups.
    -- c) - a) and b) can be run at once. This option will also fade the growths  gradually with distance. This uses 2 landclass texture lookups, 1 noise lookup, and 2-3 ground texture lookups.

    2.0 - Large scale transitions:
    -- a) Implemented by searching the landclass texture. The search pattern is current landlcass for the fragment at the center, and n search points in four directions along the s and t axes forming a cross. The search directions are configurable in the code, adn a minimum of 3 directions are needed. The step size is configurable. The fewer the steps, the larger the bands formed in the transitions. There are 1+4*n landclass lookups per n search points. e.g. 1 search point: 5 lookups, 4 search points:17 lookups, 10 search points: 41 lookups.
    -- b) An option to dither the transition bands by adding mixing noise is availble. This breaks up the visual impact of bands.
    -- c) There is some functionality to grow neighbours on a large scale. No growth priority is used - bothe neighbours will lose definition. A more advanced implementation can use several material parameters to define the nature of the transition: some transitions are very sharp in nature like with agriculture, other transitions can be very gradual, some transitions are patchy. Materials can have competing parameters, to determine which neighbour grows or has a shorter transition on one side. These parameters will need a way of specifying defaults by landclass.

    3.0 - Fixes
    -- a) - Fix seams at landclass borders. These are caused by different ground textures being stretched by different amounts. At the border, an incorrect mip-map level is looked up, causing a colour disontinuity in addition to the difference between landclasses. The reason the mip-map LoD is incorrect is because GPUs use 4 neighbouring pixels to figure out how fast texture coordinates change with respect to screenspace x and y (i.e. partial derivaitves), and use that information to pick a mip-map level. At a landlcass border, this calculation is incorrect.
    -- b) Fix seams at borders caused by the current detiling function. This is due to the detiling function changing the amount textures are stretched, as well as messing with coordinates.
    -- c) The solution to a) and b) is to use textureGrad() to lookup textures. It allows specifying partial derivatives. The partial derivatives for the normal texture coordinates are obtained by built-in funcions, and these need to be multiplied by each stretching factor, including different stretching inside conditionals. All future texture lookups that use custom coordinate scaling/manipulation need to use textureGrad. This fixes various signs of incorrect mip-map lod with distance and view angle (textures look stable/solid).
    -- d) Fix ground textures being stretched out of proportion in the detiling function. This is caused by tile dimensions not being unequal and texture stretching.
This commit is contained in:
Stuart Buchanan 2021-11-05 19:59:32 +00:00
parent bf55997a56
commit e5123eeb46
4 changed files with 1235 additions and 222 deletions

File diff suppressed because it is too large Load diff

View file

@ -22,7 +22,7 @@ attribute vec2 orthophotoTexCoord;
// the surface normal is passed in gl_{Front,Back}Color. The alpha
// component is set to 1 for front, 0 for back in order to work around
// bugs with gl_FrontFacing in the fragment shader.
varying vec4 diffuse_term;
varying vec4 light_diffuse_comp;
varying vec3 normal;
varying vec3 relPos;
varying vec2 orthoTexCoord;
@ -219,7 +219,7 @@ else // the faster, full-day version without lightfields
// default lighting based on texture and material using the light we have just computed
diffuse_term = light_diffuse;
light_diffuse_comp = light_diffuse;
vec4 constant_term = (gl_LightModel.ambient + light_ambient);
// Another hack for supporting two-sided lighting without using
// gl_FrontFacing in the fragment shader.

View file

@ -6,7 +6,7 @@
// written by Thorsten Renk, Oct 2011, based on default.frag
// Ambient term comes in gl_Color.rgb.
varying vec4 diffuse_term;
varying vec4 light_diffuse_comp;
varying vec3 normal;
varying vec3 relPos;
@ -119,7 +119,11 @@ void main()
vec4 mat_diffuse = texture(diffuseArray, index);
vec4 mat_specular = texture(specularArray, index);
<<<<<<< HEAD
vec4 color = mat_diffuse * (gl_Color + NdotL * gl_LightSource[0].diffuse);
=======
vec4 color = gl_Color;
>>>>>>> e7c89ffb600d1bf5cee2936b7dbff31089452745
// Testing code:
// Use rlc even when looking up textures to recreate the extra performance hit
@ -139,7 +143,7 @@ void main()
NdotL = dot(n, lightDir);
if (NdotL > 0.0) {
float shadowmap = getShadowing();
color += diffuse_term * NdotL * shadowmap;
color += (light_diffuse_comp * mat_diffuse) * NdotL * shadowmap;
NdotHV = max(dot(n, halfVector), 0.0);
if (mat_shininess > 0.0)
specular.rgb = (mat_specular.rgb
@ -147,7 +151,7 @@ void main()
* pow(NdotHV, gl_FrontMaterial.shininess)
* shadowmap);
}
color.a = diffuse_term.a;
color.a = light_diffuse_comp.a;
// This shouldn't be necessary, but our lighting becomes very
// saturated. Clamping the color before modulating by the texture
// is closer to what the OpenGL fixed function pipeline does.

View file

@ -22,7 +22,7 @@ attribute vec2 orthophotoTexCoord;
// the surface normal is passed in gl_{Front,Back}Color. The alpha
// component is set to 1 for front, 0 for back in order to work around
// bugs with gl_FrontFacing in the fragment shader.
varying vec4 diffuse_term;
varying vec4 light_diffuse_comp;
varying vec3 normal;
varying vec3 relPos;
varying vec2 orthoTexCoord;
@ -219,7 +219,7 @@ else // the faster, full-day version without lightfields
// default lighting based on texture and material using the light we have just computed
diffuse_term = light_diffuse;
light_diffuse_comp = light_diffuse;
vec4 constant_term = (gl_LightModel.ambient + light_ambient);
// Another hack for supporting two-sided lighting without using
// gl_FrontFacing in the fragment shader.