1
0
Fork 0

WS30 - Uniform Arrays and lighting model

Use Uniform Arrays instead of Texture1D.

Use ambient/diffuse/specular/shininess material
properties consistently across all WS30 shaders.

Use consistent shading model for photoscenery vs.
landclass to minimize visual difference.
This commit is contained in:
Stuart Buchanan 2021-11-10 22:58:44 +00:00
parent 6b943c5e5c
commit d723b0b518
10 changed files with 327 additions and 282 deletions

View file

@ -779,21 +779,6 @@
<type>sampler-2d</type> <type>sampler-2d</type>
<value type="int">1</value> <value type="int">1</value>
</uniform> </uniform>
<uniform>
<name>dimensionsArray</name>
<type>sampler-1d</type>
<value type="int">2</value>
</uniform>
<uniform>
<name>diffuseArray</name>
<type>sampler-1d</type>
<value type="int">3</value>
</uniform>
<uniform>
<name>specularArray</name>
<type>sampler-1d</type>
<value type="int">4</value>
</uniform>
<uniform> <uniform>
<name>perlin</name> <name>perlin</name>
<type>sampler-2d</type> <type>sampler-2d</type>
@ -1127,21 +1112,6 @@
<type>sampler-2d</type> <type>sampler-2d</type>
<value type="int">1</value> <value type="int">1</value>
</uniform> </uniform>
<uniform>
<name>dimensionsArray</name>
<type>sampler-1d</type>
<value type="int">2</value>
</uniform>
<uniform>
<name>diffuseArray</name>
<type>sampler-1d</type>
<value type="int">3</value>
</uniform>
<uniform>
<name>specularArray</name>
<type>sampler-1d</type>
<value type="int">4</value>
</uniform>
<uniform> <uniform>
<name>perlin</name> <name>perlin</name>
<type>sampler-2d</type> <type>sampler-2d</type>
@ -1152,12 +1122,6 @@
<type>int</type> <type>int</type>
<value><use>xsize</use></value> <value><use>xsize</use></value>
</uniform> </uniform>
<uniform>
<name>colorMode</name>
<type>int</type>
<value>2</value>
<!-- AMBIENT_AND_DIFFUSE -->
</uniform>
<!-- BEGIN shadows include --> <!-- BEGIN shadows include -->
<uniform> <uniform>
<name>shadow_tex</name> <name>shadow_tex</name>
@ -1403,33 +1367,7 @@
<type>sampler-2d</type> <type>sampler-2d</type>
<value type="int">1</value> <value type="int">1</value>
</uniform> </uniform>
<uniform>
<name>dimensionsArray</name>
<type>sampler-1d</type>
<value type="int">2</value>
</uniform>
<uniform>
<name>diffuseArray</name>
<type>sampler-1d</type>
<value type="int">3</value>
</uniform>
<uniform>
<name>specularArray</name>
<type>sampler-1d</type>
<value type="int">4</value>
</uniform>
<uniform>
<name>perlin</name>
<type>sampler-2d</type>
<value type="int">6</value>
</uniform>
<uniform>
<name>colorMode</name>
<type>int</type>
<value>2</value>
<!-- AMBIENT_AND_DIFFUSE -->
</uniform>
<!-- BEGIN shadows include --> <!-- BEGIN shadows include -->
<uniform> <uniform>
<name>shadow_tex</name> <name>shadow_tex</name>
@ -1538,9 +1476,13 @@
</texture-unit> </texture-unit>
<program> <program>
<vertex-shader>Shaders/include_fog.vert</vertex-shader>
<vertex-shader>Shaders/shadows-include.vert</vertex-shader>
<vertex-shader>Shaders/ws30.vert</vertex-shader> <vertex-shader>Shaders/ws30.vert</vertex-shader>
<fragment-shader n="0">Shaders/include_fog.frag</fragment-shader> <fragment-shader n="0">Shaders/include_fog.frag</fragment-shader>
<fragment-shader n="1">Shaders/ws30-q1.frag</fragment-shader> <fragment-shader n="1">Shaders/ws30-q1.frag</fragment-shader>
<fragment-shader>Shaders/shadows-include.frag</fragment-shader>
<fragment-shader>Shaders/clustered-include.frag</fragment-shader>
</program> </program>
<uniform> <uniform>
@ -1554,25 +1496,16 @@
<value type="int">1</value> <value type="int">1</value>
</uniform> </uniform>
<uniform> <uniform>
<name>dimensionsArray</name> <name>perlin</name>
<type>sampler-1d</type> <type>sampler-2d</type>
<value type="int">2</value> <value type="int">6</value>
</uniform> </uniform>
<uniform> <uniform>
<name>diffuseArray</name> <name>colorMode</name>
<type>sampler-1d</type> <type>int</type>
<value type="int">3</value> <value>2</value>
<!-- AMBIENT_AND_DIFFUSE -->
</uniform> </uniform>
<uniform>
<name>specularArray</name>
<type>sampler-1d</type>
<value type="int">4</value>
</uniform>
<uniform>
<name>perlin</name>
<type>sampler-2d</type>
<value type="int">6</value>
</uniform>
</pass> </pass>
</technique> </technique>
@ -1637,9 +1570,13 @@
</texture-unit> </texture-unit>
<program> <program>
<vertex-shader>Shaders/include_fog.vert</vertex-shader>
<vertex-shader>Shaders/shadows-include.vert</vertex-shader>
<vertex-shader>Shaders/ws30.vert</vertex-shader> <vertex-shader>Shaders/ws30.vert</vertex-shader>
<fragment-shader n="0">Shaders/include_fog.frag</fragment-shader> <fragment-shader n="0">Shaders/include_fog.frag</fragment-shader>
<fragment-shader n="1">Shaders/ws30.frag</fragment-shader> <fragment-shader n="1">Shaders/ws30.frag</fragment-shader>
<fragment-shader>Shaders/shadows-include.frag</fragment-shader>
<fragment-shader>Shaders/clustered-include.frag</fragment-shader>
</program> </program>
<uniform> <uniform>
@ -1653,19 +1590,10 @@
<value type="int">1</value> <value type="int">1</value>
</uniform> </uniform>
<uniform> <uniform>
<name>dimensionsArray</name> <name>colorMode</name>
<type>sampler-1d</type> <type>int</type>
<value type="int">2</value> <value>2</value>
</uniform> <!-- AMBIENT_AND_DIFFUSE -->
<uniform>
<name>diffuseArray</name>
<type>sampler-1d</type>
<value type="int">3</value>
</uniform>
<uniform>
<name>specularArray</name>
<type>sampler-1d</type>
<value type="int">4</value>
</uniform> </uniform>
</pass> </pass>
</technique> </technique>
@ -1758,21 +1686,6 @@
<type>sampler-2d</type> <type>sampler-2d</type>
<value type="int">1</value> <value type="int">1</value>
</uniform> </uniform>
<uniform>
<name>dimensionsArray</name>
<type>sampler-1d</type>
<value type="int">2</value>
</uniform>
<uniform>
<name>diffuseArray</name>
<type>sampler-1d</type>
<value type="int">3</value>
</uniform>
<uniform>
<name>specularArray</name>
<type>sampler-1d</type>
<value type="int">4</value>
</uniform>
<uniform> <uniform>
<name>perlin</name> <name>perlin</name>
<type>sampler-2d</type> <type>sampler-2d</type>

View file

@ -9,42 +9,52 @@ in vec2 texCoord;
uniform sampler2D landclass; uniform sampler2D landclass;
uniform sampler2DArray atlas; uniform sampler2DArray atlas;
uniform sampler1D dimensionsArray;
uniform sampler1D diffuseArray;
uniform sampler1D specularArray;
uniform sampler2D perlin; uniform sampler2D perlin;
// Passed from VPBTechnique, not the Effect // Passed from VPBTechnique, not the Effect
uniform float tile_width; uniform float tile_width;
uniform float tile_height; uniform float tile_height;
uniform vec4 dimensionsArray[128];
uniform vec4 ambientArray[128];
uniform vec4 diffuseArray[128];
uniform vec4 specularArray[128];
vec2 encodeNormal(vec3 n); vec2 encodeNormal(vec3 n);
vec3 decodeSRGB(vec3 screenRGB); vec3 decodeSRGB(vec3 screenRGB);
void main() void main()
{ {
// The Landclass for this particular fragment. This can be used to vec3 texel;
// index into the atlas textures.
int lc = int(texture(landclass, texCoord).g * 255.0 + 0.5);
// Different textures have different have different dimensions. if (photoScenery) {
// Dimensions array is scaled to fit in [0...1.0] in the texture1D, so has to be scaled back up here. texel = decodeSRGB(texture(landclass, vec2(gl_TexCoord[0].s, 1.0 - gl_TexCoord[0].t)).rgb);
vec4 color = texture(diffuseArray, float(lc)/512.0); } else {
vec4 specular = texture(specularArray, float(lc)/512.0);
vec2 atlas_dimensions = 10000.0 * texture(dimensionsArray, float(lc)/512.0).st;
vec2 atlas_scale = vec2(tile_width / atlas_dimensions.s, tile_height / atlas_dimensions.t );
vec2 st = atlas_scale * texCoord;
// Rotate texture using the perlin texture as a mask to reduce tiling // The Landclass for this particular fragment. This can be used to
if (step(0.5, texture(perlin, atlas_scale * texCoord / 8.0).r) == 1.0) { // index into the atlas textures.
st = vec2(atlas_scale.s * texCoord.t, atlas_scale.t * texCoord.s); int lc = int(texture2D(landclass, gl_TexCoord[0].st).g * 255.0 + 0.5);
color = ambientArray[lc] + diffuseArray[lc] * NdotL * gl_LightSource[0].diffuse;
specular = specularArray[lc];
// Different textures have different have different dimensions.
vec2 atlas_dimensions = dimensionsArray[lc].st;
vec2 atlas_scale = vec2(tile_width / atlas_dimensions.s, tile_height / atlas_dimensions.t );
vec2 st = atlas_scale * gl_TexCoord[0].st;
// Rotate texture using the perlin texture as a mask to reduce tiling
if (step(0.5, texture(perlin, atlas_scale * gl_TexCoord[0].st / 8.0).r) == 1.0) {
st = vec2(atlas_scale.s * gl_TexCoord[0].t, atlas_scale.t * gl_TexCoord[0].s);
}
if (step(0.5, texture(perlin, - atlas_scale * gl_TexCoord[0].st / 16.0).r) == 1.0) {
st = -st;
}
texel = decodeSRGB(texture(atlas, vec3(st, lc)).rgb);
} }
if (step(0.5, texture(perlin, - atlas_scale * texCoord / 16.0).r) == 1.0) {
st = -st;
}
vec3 texel = decodeSRGB(texture(atlas, vec3(st, lc)).rgb);
float specularity = clamp(dot(specular.rgb, vec3(0.333)), 0.0, 1.0); float specularity = clamp(dot(specular.rgb, vec3(0.333)), 0.0, 1.0);
outGBuffer0.rg = encodeNormal(normalVS); outGBuffer0.rg = encodeNormal(normalVS);

View file

@ -53,9 +53,6 @@ varying vec4 eyePos;
uniform sampler2D landclass; uniform sampler2D landclass;
uniform sampler2DArray textureArray; uniform sampler2DArray textureArray;
uniform sampler1D dimensionsArray;
uniform sampler1D diffuseArray;
uniform sampler1D specularArray;
uniform sampler2D perlin; uniform sampler2D perlin;
//varying float yprime_alt; //varying float yprime_alt;
@ -88,6 +85,10 @@ uniform int tquality_level;
// Passed from VPBTechnique, not the Effect // Passed from VPBTechnique, not the Effect
uniform bool photoScenery; uniform bool photoScenery;
uniform vec4 dimensionsArray[128];
uniform vec4 ambientArray[128];
uniform vec4 diffuseArray[128];
uniform vec4 specularArray[128];
const float EarthRadius = 5800000.0; const float EarthRadius = 5800000.0;
const float terminator_width = 200000.0; const float terminator_width = 200000.0;
@ -153,8 +154,7 @@ int get_random_landclass(in vec2 co, in vec2 tile_size);
// the stretching of different textures, so that the correct mip-map level is looked // the stretching of different textures, so that the correct mip-map level is looked
// up and there are no seams. // up and there are no seams.
vec4 lookup_ground_texture_array(in float index, in vec2 tile_coord, in int landclass_id, vec4 lookup_ground_texture_array(in vec2 tile_coord, in int landclass_id, in vec2 dx, in vec2 dy);
in vec2 dx, in vec2 dy);
// Look up the landclass id [0 .. 255] for this particular fragment. // Look up the landclass id [0 .. 255] for this particular fragment.
@ -283,12 +283,11 @@ float noise_2000m = Noise3D(worldPos.xyz, 2000.0);
float index = float(lc)/512.0; float index = float(lc)/512.0;
vec4 index_n = vec4(lc_n)/512.0; vec4 index_n = vec4(lc_n)/512.0;
float mat_shininess = texture(dimensionsArray, index).z; float mat_shininess = dimensionsArray[lc].z;
vec4 mat_diffuse = texture(diffuseArray, index); vec4 mat_ambient = ambientArray[lc];
vec4 mat_specular = texture(specularArray, index); vec4 mat_diffuse = diffuseArray[lc];
vec4 mat_specular = specularArray[lc];
vec4 color = gl_Color;
color.a = 1.0;
@ -298,26 +297,37 @@ float noise_2000m = Noise3D(worldPos.xyz, 2000.0);
// color.rgb = color.rgb+0.00001*float(get_random_landclass(tile_coord.st, tile_size)); // color.rgb = color.rgb+0.00001*float(get_random_landclass(tile_coord.st, tile_size));
// Look up ground textures by indexing into the texture array.
// Different textures are stretched along the ground to different
// lengths along each axes as set by <xsize> and <ysize>
// regional definitions parameters
// Look up texture coordinates and scale of ground textures
// Landclass for this fragment
if (photoScenery) { if (photoScenery) {
// In the photoscenery case we don't have landclass or materials available, so we
// just use constants for the material properties.
mat_ambient = vec4(0.2,0.2,0.2,1.0);
mat_diffuse = vec4(0.8,0.8,0.8,1.0);
mat_specular = vec4(0.0,0.0,0.0,1.0);
texel = texture(landclass, vec2(gl_TexCoord[0].s, 1.0 - gl_TexCoord[0].t)); texel = texture(landclass, vec2(gl_TexCoord[0].s, 1.0 - gl_TexCoord[0].t));
} else { } else {
texel = lookup_ground_texture_array(index, tile_coord, lc, dx, dy); // Color Mode is always AMBIENT_AND_DIFFUSE, which means
// using a base colour of white for ambient/diffuse,
// rather than the material color from ambientArray/diffuseArray.
mat_ambient = vec4(1.0,1.0,1.0,1.0);
mat_diffuse = vec4(1.0,1.0,1.0,1.0);
mat_specular = specularArray[lc];
mat_shininess = dimensionsArray[lc].z;
// Look up ground textures by indexing into the texture array.
// Different textures are stretched along the ground to different
// lengths along each axes as set by <xsize> and <ysize>
// regional definitions parameters
// Look up texture coordinates and scale of ground textures
// Landclass for this fragment
texel = lookup_ground_texture_array(tile_coord, lc, dx, dy);
// Mix texels - to work consistently it needs a more preceptual interpolation than mix() // Mix texels - to work consistently it needs a more preceptual interpolation than mix()
if (num_unique_neighbors != 0) if (num_unique_neighbors != 0)
{ {
// Closest neighbor landclass // Closest neighbor landclass
vec4 texel_closest = lookup_ground_texture_array(index_n[0], tile_coord, lc_n[0], dx, dy); vec4 texel_closest = lookup_ground_texture_array(tile_coord, lc_n[0], dx, dy);
// Neighbor contributions // Neighbor contributions
vec4 texel_nc=texel_closest; vec4 texel_nc=texel_closest;
@ -325,7 +335,7 @@ float noise_2000m = Noise3D(worldPos.xyz, 2000.0);
if (num_unique_neighbors > 1) if (num_unique_neighbors > 1)
{ {
// 2nd Closest neighbor landclass // 2nd Closest neighbor landclass
vec4 texel_2nd_closest = lookup_ground_texture_array(index_n[1], tile_coord, lc_n[1], vec4 texel_2nd_closest = lookup_ground_texture_array(tile_coord, lc_n[1],
dx, dy); dx, dy);
texel_nc = mix(texel_closest, texel_2nd_closest, mfact[1]); texel_nc = mix(texel_closest, texel_2nd_closest, mfact[1]);
@ -335,6 +345,9 @@ float noise_2000m = Noise3D(worldPos.xyz, 2000.0);
} }
} }
vec4 color = gl_Color * mat_ambient;
color.a = 1.0;
// Testing code: mix with green to show values of variables at each point // Testing code: mix with green to show values of variables at each point
//vec4 green = vec4(0.0, 0.5, 0.0, 0.0); //vec4 green = vec4(0.0, 0.5, 0.0, 0.0);
//texel = mix(texel, green, (mfact[2])); //texel = mix(texel, green, (mfact[2]));
@ -348,16 +361,12 @@ float noise_2000m = Noise3D(worldPos.xyz, 2000.0);
float local_autumn_factor = texel.a; float local_autumn_factor = texel.a;
/*
if (orthophotoAvailable) { if (photoScenery) {
vec4 sat_texel = texture2D(orthophotoTexture, orthoTexCoord); flag = 0;
if (sat_texel.a > 0) { mix_flag = 0;
texel.rgb = sat_texel.rgb; }
flag = 0;
mix_flag = 0;
}
}
*/
float distortion_factor = 1.0; float distortion_factor = 1.0;
vec2 stprime; vec2 stprime;

View file

@ -227,15 +227,13 @@
uniform sampler2D landclass; uniform sampler2D landclass;
uniform sampler2DArray textureArray; uniform sampler2DArray textureArray;
uniform sampler1D dimensionsArray;
uniform sampler1D diffuseArray;
uniform sampler1D specularArray;
uniform sampler2D perlin; uniform sampler2D perlin;
// Passed from VPBTechnique, not the Effect // Passed from VPBTechnique, not the Effect
uniform int tile_level; uniform int tile_level;
uniform float tile_width; uniform float tile_width;
uniform float tile_height; uniform float tile_height;
uniform vec4 dimensionsArray[128];
// These should be sent as uniforms // These should be sent as uniforms
@ -259,12 +257,12 @@ int get_random_landclass(in vec2 co, in vec2 tile_size)
// Look up texture coordinates and stretching scale of ground textures // Look up texture coordinates and stretching scale of ground textures
void get_ground_texture_data(in float textureIndex, in vec2 tile_coord, void get_ground_texture_data(in int textureIndex, in vec2 tile_coord,
out vec2 st, out vec2 g_texture_scale, inout vec2 dx, inout vec2 dy) out vec2 st, out vec2 g_texture_scale, inout vec2 dx, inout vec2 dy)
{ {
// Look up stretching dimensions of ground textures in m - scaled to // Look up stretching dimensions of ground textures in m - scaled to
// fit in [0..1], so rescale // fit in [0..1], so rescale
vec2 g_texture_stretch_dim = 10000.0 * texture(dimensionsArray, textureIndex).st; vec2 g_texture_stretch_dim = dimensionsArray[textureIndex].st;
g_texture_scale = tile_size.xy / g_texture_stretch_dim.xy; g_texture_scale = tile_size.xy / g_texture_stretch_dim.xy;
// Correct partial derivatives to account for stretching of different textures // Correct partial derivatives to account for stretching of different textures
dx = dx * g_texture_scale; dx = dx * g_texture_scale;
@ -335,7 +333,7 @@ vec2 detile_texcoords_with_perlin_noise(in vec2 st, in vec2 ground_texture_scale
// the stretching of different textures, so that the correct mip-map level is looked // the stretching of different textures, so that the correct mip-map level is looked
// up and there are no seams. // up and there are no seams.
vec4 lookup_ground_texture_array(in float index, in vec2 tile_coord, in int landclass_id, vec4 lookup_ground_texture_array(in vec2 tile_coord, in int landclass_id,
in vec2 dx, in vec2 dy) in vec2 dx, in vec2 dy)
{ {
// Testing: may be able to save 1 or 2 op slots by combining dx/dy in a vec4 and // Testing: may be able to save 1 or 2 op slots by combining dx/dy in a vec4 and
@ -346,7 +344,7 @@ vec4 lookup_ground_texture_array(in float index, in vec2 tile_coord, in int land
vec4 texel; vec4 texel;
int lc = landclass_id; int lc = landclass_id;
get_ground_texture_data(index, tile_coord, st, g_texture_scale, dx, dy); get_ground_texture_data(lc, tile_coord, st, g_texture_scale, dx, dy);
st = detile_texcoords_with_perlin_noise(st, g_texture_scale, tile_coord, dx, dy); st = detile_texcoords_with_perlin_noise(st, g_texture_scale, tile_coord, dx, dy);

View file

@ -55,9 +55,6 @@ varying vec4 ecPosition;
uniform sampler2D landclass; uniform sampler2D landclass;
uniform sampler2DArray textureArray; uniform sampler2DArray textureArray;
uniform sampler1D dimensionsArray;
uniform sampler1D diffuseArray;
uniform sampler1D specularArray;
uniform sampler2D perlin; uniform sampler2D perlin;
@ -109,6 +106,10 @@ uniform int swatch_size; //in metres, typically 1000 or 2000
// Passed from VPBTechnique, not the Effect // Passed from VPBTechnique, not the Effect
uniform bool photoScenery; uniform bool photoScenery;
uniform vec4 dimensionsArray[128];
uniform vec4 ambientArray[128];
uniform vec4 diffuseArray[128];
uniform vec4 specularArray[128];
const float EarthRadius = 5800000.0; const float EarthRadius = 5800000.0;
const float terminator_width = 200000.0; const float terminator_width = 200000.0;
@ -181,7 +182,7 @@ int get_random_landclass(in vec2 co, in vec2 tile_size);
// the stretching of different textures, so that the correct mip-map level is looked // the stretching of different textures, so that the correct mip-map level is looked
// up and there are no seams. // up and there are no seams.
vec4 lookup_ground_texture_array(in float index, in vec2 tile_coord, in int landclass_id, vec4 lookup_ground_texture_array(in vec2 tile_coord, in int landclass_id,
in vec2 dx, in vec2 dy); in vec2 dx, in vec2 dy);
@ -377,12 +378,10 @@ float snownoise_50m = mix(noise_50m, slopenoise_100m, clamp(3.0*(1.0-steepness),
float index = float(lc)/512.0; float index = float(lc)/512.0;
vec4 index_n = vec4(lc_n)/512.0; vec4 index_n = vec4(lc_n)/512.0;
float mat_shininess = texture(dimensionsArray, index).z; float mat_shininess = dimensionsArray[lc].z;
vec4 mat_diffuse = texture(diffuseArray, index); vec4 mat_ambient = ambientArray[lc];
vec4 mat_specular = texture(specularArray, index); vec4 mat_diffuse = diffuseArray[lc];
vec4 mat_specular = specularArray[lc];
vec4 color = gl_Color;
color.a = 1.0;
@ -391,28 +390,44 @@ float snownoise_50m = mix(noise_50m, slopenoise_100m, clamp(3.0*(1.0-steepness),
// so any performance difference between the two is due to the texture lookup // so any performance difference between the two is due to the texture lookup
// color.rgb = color.rgb+0.00001*float(get_random_landclass(tile_coord.st, tile_size)); // color.rgb = color.rgb+0.00001*float(get_random_landclass(tile_coord.st, tile_size));
// Look up ground textures by indexing into the texture array.
// Different textures are stretched along the ground to different
// lengths along each axes as set by <xsize> and <ysize>
// regional definitions parameters
// Look up texture coordinates and scale of ground textures
// Landclass for this fragment
if (photoScenery) { if (photoScenery) {
// In the photoscenery case we don't have landclass or materials available, so we
// just use constants for the material properties.
mat_ambient = vec4(0.2,0.2,0.2,1.0);
mat_diffuse = vec4(0.8,0.8,0.8,1.0);
mat_specular = vec4(0.0,0.0,0.0,1.0);
texel = texture(landclass, vec2(gl_TexCoord[0].s, 1.0 - gl_TexCoord[0].t)); texel = texture(landclass, vec2(gl_TexCoord[0].s, 1.0 - gl_TexCoord[0].t));
// Do not attempt any mixing
flag = 0;
mix_flag = 0;
} else { } else {
texel = lookup_ground_texture_array(index, tile_coord, lc, dx, dy); // Color Mode is always AMBIENT_AND_DIFFUSE, which means
// using a base colour of white for ambient/diffuse,
// rather than the material color from ambientArray/diffuseArray.
mat_ambient = vec4(1.0,1.0,1.0,1.0);
mat_diffuse = vec4(1.0,1.0,1.0,1.0);
mat_specular = specularArray[lc];
mat_shininess = dimensionsArray[lc].z;
// Look up ground textures by indexing into the texture array.
// Different textures are stretched along the ground to different
// lengths along each axes as set by <xsize> and <ysize>
// regional definitions parameters
// Look up texture coordinates and scale of ground textures
// Landclass for this fragment
texel = lookup_ground_texture_array(tile_coord, lc, dx, dy);
// Mix texels - to work consistently it needs a more preceptual interpolation than mix() // Mix texels - to work consistently it needs a more preceptual interpolation than mix()
if (num_unique_neighbors != 0) if (num_unique_neighbors != 0)
{ {
// Closest neighbor landclass // Closest neighbor landclass
vec4 texel_closest = lookup_ground_texture_array(index_n[0], tile_coord, lc_n[0], dx, dy); vec4 texel_closest = lookup_ground_texture_array(tile_coord, lc_n[0], dx, dy);
// Neighbor contributions // Neighbor contributions
vec4 texel_nc=texel_closest; vec4 texel_nc=texel_closest;
@ -420,8 +435,7 @@ float snownoise_50m = mix(noise_50m, slopenoise_100m, clamp(3.0*(1.0-steepness),
if (num_unique_neighbors > 1) if (num_unique_neighbors > 1)
{ {
// 2nd Closest neighbor landclass // 2nd Closest neighbor landclass
vec4 texel_2nd_closest = lookup_ground_texture_array(index_n[1], tile_coord, lc_n[1], vec4 texel_2nd_closest = lookup_ground_texture_array(tile_coord, lc_n[1], dx, dy);
dx, dy);
texel_nc = mix(texel_closest, texel_2nd_closest, mfact[1]); texel_nc = mix(texel_closest, texel_2nd_closest, mfact[1]);
} }
@ -430,6 +444,10 @@ float snownoise_50m = mix(noise_50m, slopenoise_100m, clamp(3.0*(1.0-steepness),
} }
} }
vec4 color = gl_Color;
color.a = 1.0;
// Testing code: mix with green to show values of variables at each point // Testing code: mix with green to show values of variables at each point
//vec4 green = vec4(0.0, 0.5, 0.0, 0.0); //vec4 green = vec4(0.0, 0.5, 0.0, 0.0);
//texel = mix(texel, green, (mfact[2])); //texel = mix(texel, green, (mfact[2]));

View file

@ -46,10 +46,6 @@ varying vec3 relPos;
uniform sampler2D landclass; uniform sampler2D landclass;
uniform sampler2DArray textureArray; uniform sampler2DArray textureArray;
uniform sampler1D dimensionsArray;
uniform sampler1D diffuseArray;
uniform sampler1D specularArray;
uniform sampler2D perlin;
varying float yprime_alt; varying float yprime_alt;
varying float mie_angle; varying float mie_angle;
@ -70,6 +66,10 @@ uniform int tile_level;
uniform float tile_width; uniform float tile_width;
uniform float tile_height; uniform float tile_height;
uniform bool photoScenery; uniform bool photoScenery;
uniform vec4 dimensionsArray[128];
uniform vec4 ambientArray[128];
uniform vec4 diffuseArray[128];
uniform vec4 specularArray[128];
const float EarthRadius = 5800000.0; const float EarthRadius = 5800000.0;
const float terminator_width = 200000.0; const float terminator_width = 200000.0;
@ -140,8 +140,7 @@ int get_random_landclass(in vec2 co, in vec2 tile_size);
// the stretching of different textures, so that the correct mip-map level is looked // the stretching of different textures, so that the correct mip-map level is looked
// up and there are no seams. // up and there are no seams.
vec4 lookup_ground_texture_array(in float index, in vec2 tile_coord, in int landclass_id, vec4 lookup_ground_texture_array(in vec2 tile_coord, in int landclass_id, in vec2 dx, in vec2 dy);
in vec2 dx, in vec2 dy);
// Look up the landclass id [0 .. 255] for this particular fragment. // Look up the landclass id [0 .. 255] for this particular fragment.
@ -222,11 +221,58 @@ void main()
float index = float(lc)/512.0; float index = float(lc)/512.0;
vec4 index_n = vec4(lc_n)/512.0; vec4 index_n = vec4(lc_n)/512.0;
float mat_shininess = texture(dimensionsArray, index).z; // Material properties.
vec4 mat_diffuse = texture(diffuseArray, index); vec4 mat_diffuse, mat_ambient, mat_specular;
vec4 mat_specular = texture(specularArray, index); float mat_shininess;
vec4 color = gl_Color; if (photoScenery) {
mat_ambient = vec4(1.0,1.0,1.0,1.0);
mat_diffuse = vec4(1.0,1.0,1.0,1.0);
mat_specular = vec4(0.1, 0.1, 0.1, 1.0);
mat_shininess = 1.2;
texel = texture(landclass, vec2(gl_TexCoord[0].s, 1.0 - gl_TexCoord[0].t));
} else {
// Color Mode is always AMBIENT_AND_DIFFUSE, which means
// using a base colour of white for ambient/diffuse,
// rather than the material color from ambientArray/diffuseArray.
mat_ambient = vec4(1.0,1.0,1.0,1.0);
mat_diffuse = vec4(1.0,1.0,1.0,1.0);
mat_specular = specularArray[lc];
mat_shininess = dimensionsArray[lc].z;
// Look up ground textures by indexing into the texture array.
// Different textures are stretched along the ground to different
// lengths along each axes as set by <xsize> and <ysize>
// regional definitions parameters
// Look up texture coordinates and scale of ground textures
// Landclass for this fragment
texel = lookup_ground_texture_array(tile_coord, lc, dx, dy);
// Mix texels - to work consistently it needs a more preceptual interpolation than mix()
if (num_unique_neighbors != 0)
{
// Closest neighbor landclass
vec4 texel_closest = lookup_ground_texture_array(tile_coord, lc_n[0], dx, dy);
// Neighbor contributions
vec4 texel_nc=texel_closest;
if (num_unique_neighbors > 1)
{
// 2nd Closest neighbor landclass
vec4 texel_2nd_closest = lookup_ground_texture_array(tile_coord, lc_n[1],
dx, dy);
texel_nc = mix(texel_closest, texel_2nd_closest, mfact[1]);
}
texel = mix(texel, texel_nc, mfact[0]);
}
}
vec4 color = mat_ambient * (gl_LightModel.ambient + gl_LightSource[0].ambient);
// Testing code: // Testing code:
// Use rlc even when looking up textures to recreate the extra performance hit // Use rlc even when looking up textures to recreate the extra performance hit
@ -263,41 +309,6 @@ void main()
color = clamp(color, 0.0, 1.0); color = clamp(color, 0.0, 1.0);
// Look up ground textures by indexing into the texture array.
// Different textures are stretched along the ground to different
// lengths along each axes as set by <xsize> and <ysize>
// regional definitions parameters
// Look up texture coordinates and scale of ground textures
if (photoScenery) {
texel = texture(landclass, vec2(gl_TexCoord[0].s, 1.0 - gl_TexCoord[0].t));
} else {
// Landclass for this fragment
texel = lookup_ground_texture_array(index, tile_coord, lc, dx, dy);
// Mix texels - to work consistently it needs a more preceptual interpolation than mix()
if (num_unique_neighbors != 0)
{
// Closest neighbor landclass
vec4 texel_closest = lookup_ground_texture_array(index_n[0], tile_coord, lc_n[0], dx, dy);
// Neighbor contributions
vec4 texel_nc=texel_closest;
if (num_unique_neighbors > 1)
{
// 2nd Closest neighbor landclass
vec4 texel_2nd_closest = lookup_ground_texture_array(index_n[1], tile_coord, lc_n[1],
dx, dy);
texel_nc = mix(texel_closest, texel_2nd_closest, mfact[1]);
}
texel = mix(texel, texel_nc, mfact[0]);
}
}
// Testing code: mix with green to show values of variables at each point // Testing code: mix with green to show values of variables at each point
//vec4 green = vec4(0.0, 0.5, 0.0, 0.0); //vec4 green = vec4(0.0, 0.5, 0.0, 0.0);
//texel = mix(texel, green, (mfact[2])); //texel = mix(texel, green, (mfact[2]));

View file

@ -16,8 +16,6 @@
#define MODE_DIFFUSE 1 #define MODE_DIFFUSE 1
#define MODE_AMBIENT_AND_DIFFUSE 2 #define MODE_AMBIENT_AND_DIFFUSE 2
attribute vec2 orthophotoTexCoord;
// The constant term of the lighting equation that doesn't depend on // The constant term of the lighting equation that doesn't depend on
// the surface normal is passed in gl_{Front,Back}Color. The alpha // 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 // component is set to 1 for front, 0 for back in order to work around
@ -25,7 +23,6 @@ attribute vec2 orthophotoTexCoord;
varying vec4 light_diffuse_comp; varying vec4 light_diffuse_comp;
varying vec3 normal; varying vec3 normal;
varying vec3 relPos; varying vec3 relPos;
varying vec2 orthoTexCoord;
varying vec4 ecPosition; varying vec4 ecPosition;
varying float yprime_alt; varying float yprime_alt;
@ -82,7 +79,6 @@ void main()
ecPosition = gl_ModelViewMatrix * gl_Vertex; ecPosition = gl_ModelViewMatrix * gl_Vertex;
gl_Position = ftransform(); gl_Position = ftransform();
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
orthoTexCoord = orthophotoTexCoord;
normal = gl_NormalMatrix * gl_Normal; normal = gl_NormalMatrix * gl_Normal;
// here start computations for the haze layer // here start computations for the haze layer
@ -225,8 +221,7 @@ else // the faster, full-day version without lightfields
// Emission is all set to the default of vec4(0.0, 0.0, 0.0, 1.0) // Emission is all set to the default of vec4(0.0, 0.0, 0.0, 1.0)
//To do: Fix this once ambient colour becomes available in the fragment shaders. //To do: Fix this once ambient colour becomes available in the fragment shaders.
//const vec4 ambient_color = vec4(0.2, 0.2, 0.2, 1.0); //const vec4 ambient_color = vec4(0.2, 0.2, 0.2, 1.0);
const vec4 ambient_color = vec4(1.0); vec4 constant_term = gl_LightModel.ambient + light_ambient;
vec4 constant_term = ambient_color * (gl_LightModel.ambient + light_ambient);
// Another hack for supporting two-sided lighting without using // Another hack for supporting two-sided lighting without using
// gl_FrontFacing in the fragment shader. // gl_FrontFacing in the fragment shader.
gl_FrontColor.rgb = constant_term.rgb; gl_FrontColor.a = 1.0; gl_FrontColor.rgb = constant_term.rgb; gl_FrontColor.a = 1.0;

View file

@ -5,51 +5,67 @@
#extension GL_EXT_texture_array : enable #extension GL_EXT_texture_array : enable
varying vec3 normal; varying vec3 normal;
varying vec4 ecPosition;
uniform sampler2D landclass; uniform sampler2D landclass;
uniform sampler2DArray atlas; uniform sampler2DArray atlas;
uniform sampler1D dimensionsArray;
uniform sampler1D diffuseArray;
uniform sampler1D specularArray;
uniform sampler2D perlin; uniform sampler2D perlin;
// Passed from VPBTechnique, not the Effect // Passed from VPBTechnique, not the Effect
uniform float tile_width; uniform float tile_width;
uniform float tile_height; uniform float tile_height;
uniform bool photoScenery; uniform bool photoScenery;
uniform vec4 dimensionsArray[128];
uniform vec4 ambientArray[128];
uniform vec4 diffuseArray[128];
uniform vec4 specularArray[128];
// See include_fog.frag // See include_fog.frag
uniform int fogType; uniform int fogType;
vec3 fog_Func(vec3 color, int type); vec3 fog_Func(vec3 color, int type);
// See Shaders/shadows-include.frag
float getShadowing();
// See Shaders/clustered-include.frag
vec3 getClusteredLightsContribution(vec3 p, vec3 n, vec3 texel);
void main() void main()
{ {
float NdotL, NdotHV, fogFactor;
vec3 lightDir = gl_LightSource[0].position.xyz; vec3 lightDir = gl_LightSource[0].position.xyz;
vec3 halfVector = gl_LightSource[0].halfVector.xyz; vec3 halfVector = gl_LightSource[0].halfVector.xyz;
vec4 texel; vec4 texel;
vec4 fragColor; vec4 fragColor;
vec4 color = vec4(0.9, 0.9, 0.9, 1.0); vec4 specular = vec4(0.0);
vec4 specular = vec4(0.1, 0.1, 0.1, 1.0);
// If gl_Color.a == 0, this is a back-facing polygon and the // Material properties.
// normal should be reversed. // Material properties.
vec3 n = (2.0 * gl_Color.a - 1.0) * normal; vec4 mat_diffuse, mat_ambient, mat_specular;
n = normalize(n); float mat_shininess;
float NdotL = dot(n, lightDir);
float NdotHV = max(dot(n, halfVector), 0.0);
if (photoScenery) { if (photoScenery) {
mat_ambient = vec4(1.0,1.0,1.0,1.0);
mat_diffuse = vec4(1.0,1.0,1.0,1.0);
mat_specular = vec4(0.1, 0.1, 0.1, 1.0);
mat_shininess = 1.2;
texel = texture(landclass, vec2(gl_TexCoord[0].s, 1.0 - gl_TexCoord[0].t)); texel = texture(landclass, vec2(gl_TexCoord[0].s, 1.0 - gl_TexCoord[0].t));
} else { } else {
// The Landclass for this particular fragment. This can be used to // The Landclass for this particular fragment. This can be used to
// index into the atlas textures. // index into the atlas textures.
int lc = int(texture2D(landclass, gl_TexCoord[0].st).g * 255.0 + 0.5); int lc = int(texture2D(landclass, gl_TexCoord[0].st).g * 255.0 + 0.5);
// Color Mode is always AMBIENT_AND_DIFFUSE, which means
// using a base colour of white for ambient/diffuse,
// rather than the material color from ambientArray/diffuseArray.
mat_ambient = vec4(1.0,1.0,1.0,1.0);
mat_diffuse = vec4(1.0,1.0,1.0,1.0);
mat_specular = specularArray[lc];
mat_shininess = dimensionsArray[lc].z;
// Different textures have different have different dimensions. // Different textures have different have different dimensions.
// Dimensions array is scaled to fit in [0...1.0] in the texture1D, so has to be scaled back up here. vec2 atlas_dimensions = dimensionsArray[lc].st;
//color = texture(diffuseArray, float(lc)/512.0) * (gl_LightSource[0].ambient + NdotL * gl_LightSource[0].diffuse);
//specular = texture(specularArray, float(lc)/512.0);
vec2 atlas_dimensions = 10000.0 * texture(dimensionsArray, float(lc)/512.0).st;
vec2 atlas_scale = vec2(tile_width / atlas_dimensions.s, tile_height / atlas_dimensions.t ); vec2 atlas_scale = vec2(tile_width / atlas_dimensions.s, tile_height / atlas_dimensions.t );
vec2 st = atlas_scale * gl_TexCoord[0].st; vec2 st = atlas_scale * gl_TexCoord[0].st;
@ -65,7 +81,34 @@ void main()
texel = texture(atlas, vec3(st, lc)); texel = texture(atlas, vec3(st, lc));
} }
fragColor = color * texel + pow(NdotHV, gl_FrontMaterial.shininess) * gl_LightSource[0].specular * specular; vec4 color = mat_ambient * (gl_LightModel.ambient + gl_LightSource[0].ambient);
// If gl_Color.a == 0, this is a back-facing polygon and the
// normal should be reversed.
vec3 n = (2.0 * gl_Color.a - 1.0) * normal;
n = normalize(n);
NdotL = dot(n, lightDir);
if (NdotL > 0.0) {
float shadowmap = getShadowing();
color += mat_diffuse * NdotL * shadowmap;
NdotHV = max(dot(n, halfVector), 0.0);
if (mat_shininess > 0.0)
specular.rgb = (mat_specular.rgb
* gl_LightSource[0].specular.rgb
* pow(NdotHV, mat_shininess)
* shadowmap);
}
color.a = mat_diffuse.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.
color = clamp(color, 0.0, 1.0);
fragColor = color * texel + specular;
fragColor.rgb += getClusteredLightsContribution(ecPosition.xyz, n, texel.rgb);
fragColor.rgb = fog_Func(fragColor.rgb, fogType); fragColor.rgb = fog_Func(fragColor.rgb, fogType);
gl_FragColor = fragColor; gl_FragColor = fragColor;

View file

@ -5,56 +5,97 @@
#extension GL_EXT_texture_array : enable #extension GL_EXT_texture_array : enable
varying vec3 normal; varying vec3 normal;
varying vec4 ecPosition;
uniform sampler2D landclass; uniform sampler2D landclass;
uniform sampler2DArray atlas; uniform sampler2DArray atlas;
uniform sampler1D dimensionsArray;
uniform sampler1D diffuseArray;
uniform sampler1D specularArray;
// Passed from VPBTechnique, not the Effect // Passed from VPBTechnique, not the Effect
uniform float tile_width; uniform float tile_width;
uniform float tile_height; uniform float tile_height;
uniform bool photoScenery; uniform bool photoScenery;
uniform vec4 dimensionsArray[128];
uniform vec4 ambientArray[128];
uniform vec4 diffuseArray[128];
uniform vec4 specularArray[128];
// See include_fog.frag // See include_fog.frag
uniform int fogType; uniform int fogType;
vec3 fog_Func(vec3 color, int type); vec3 fog_Func(vec3 color, int type);
// See Shaders/shadows-include.frag
float getShadowing();
// See Shaders/clustered-include.frag
vec3 getClusteredLightsContribution(vec3 p, vec3 n, vec3 texel);
void main() void main()
{ {
float NdotL, NdotHV, fogFactor;
vec3 lightDir = gl_LightSource[0].position.xyz; vec3 lightDir = gl_LightSource[0].position.xyz;
vec3 halfVector = gl_LightSource[0].halfVector.xyz; vec3 halfVector = gl_LightSource[0].halfVector.xyz;
vec4 texel; vec4 texel;
vec4 fragColor; vec4 fragColor;
vec4 color = vec4(0.9, 0.9, 0.9, 1.0); vec4 specular = vec4(0.0);
vec4 specular = vec4(0.1, 0.1, 0.1, 1.0);
// If gl_Color.a == 0, this is a back-facing polygon and the // Material properties.
// normal should be reversed. vec4 mat_diffuse, mat_ambient, mat_specular;
vec3 n = (2.0 * gl_Color.a - 1.0) * normal; float mat_shininess;
n = normalize(n);
float NdotL = dot(n, lightDir);
float NdotHV = max(dot(n, halfVector), 0.0);
if (photoScenery) { if (photoScenery) {
mat_ambient = vec4(1.0,1.0,1.0,1.0);
mat_diffuse = vec4(1.0,1.0,1.0,1.0);
mat_specular = vec4(0.1, 0.1, 0.1, 1.0);
mat_shininess = 1.2;
texel = texture(landclass, vec2(gl_TexCoord[0].s, 1.0 - gl_TexCoord[0].t)); texel = texture(landclass, vec2(gl_TexCoord[0].s, 1.0 - gl_TexCoord[0].t));
} else { } else {
// The Landclass for this particular fragment. This can be used to // The Landclass for this particular fragment. This can be used to
// index into the atlas textures. // index into the atlas textures.
int lc = int(texture2D(landclass, gl_TexCoord[0].st).g * 255.0 + 0.5); int lc = int(texture2D(landclass, gl_TexCoord[0].st).g * 255.0 + 0.5);
// Color Mode is always AMBIENT_AND_DIFFUSE, which means
// using a base colour of white for ambient/diffuse,
// rather than the material color from ambientArray/diffuseArray.
mat_ambient = vec4(1.0,1.0,1.0,1.0);
mat_diffuse = vec4(1.0,1.0,1.0,1.0);
mat_specular = specularArray[lc];
mat_shininess = dimensionsArray[lc].z;
// Different textures have different have different dimensions. // Different textures have different have different dimensions.
// Dimensions array is scaled to fit in [0...1.0] in the texture1D, so has to be scaled back up here. vec2 atlas_dimensions = dimensionsArray[lc].st;
//color = texture(diffuseArray, float(lc)/512.0) * (gl_LightSource[0].ambient + NdotL * gl_LightSource[0].diffuse);
//specular = texture(specularArray, float(lc)/512.0);
vec2 atlas_dimensions = 10000.0 * texture(dimensionsArray, float(lc)/512.0).st;
vec2 atlas_scale = vec2(tile_width / atlas_dimensions.s, tile_height / atlas_dimensions.t ); vec2 atlas_scale = vec2(tile_width / atlas_dimensions.s, tile_height / atlas_dimensions.t );
texel = texture(atlas, vec3(atlas_scale * gl_TexCoord[0].st, lc)); texel = texture(atlas, vec3(atlas_scale * gl_TexCoord[0].st, lc));
} }
fragColor = color * texel + pow(NdotHV, gl_FrontMaterial.shininess) * gl_LightSource[0].specular * specular; vec4 color = mat_ambient * (gl_LightModel.ambient + gl_LightSource[0].ambient);
// If gl_Color.a == 0, this is a back-facing polygon and the
// normal should be reversed.
vec3 n = (2.0 * gl_Color.a - 1.0) * normal;
n = normalize(n);
NdotL = dot(n, lightDir);
if (NdotL > 0.0) {
float shadowmap = getShadowing();
color += mat_diffuse * NdotL * shadowmap;
NdotHV = max(dot(n, halfVector), 0.0);
if (mat_shininess > 0.0)
specular.rgb = (mat_specular.rgb
* gl_LightSource[0].specular.rgb
* pow(NdotHV, mat_shininess)
* shadowmap);
}
color.a = mat_diffuse.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.
color = clamp(color, 0.0, 1.0);
fragColor = color * texel + specular;
fragColor.rgb += getClusteredLightsContribution(ecPosition.xyz, n, texel.rgb);
fragColor.rgb = fog_Func(fragColor.rgb, fogType); fragColor.rgb = fog_Func(fragColor.rgb, fogType);
gl_FragColor = fragColor; gl_FragColor = fragColor;

View file

@ -21,10 +21,16 @@
// component is set to 1 for front, 0 for back in order to work around // component is set to 1 for front, 0 for back in order to work around
// bugs with gl_FrontFacing in the fragment shader. // bugs with gl_FrontFacing in the fragment shader.
varying vec3 normal; varying vec3 normal;
varying vec4 ecPosition;
// See Shaders/shadows-include.vert
void setupShadows(vec4 eyeSpacePos);
void main() void main()
{ {
gl_Position = ftransform(); gl_Position = ftransform();
ecPosition = gl_ModelViewMatrix * gl_Vertex;
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
normal = gl_NormalMatrix * gl_Normal; normal = gl_NormalMatrix * gl_Normal;
@ -32,6 +38,7 @@ void main()
// gl_FrontFacing in the fragment shader. // gl_FrontFacing in the fragment shader.
gl_FrontColor.a = 1.0; gl_FrontColor.a = 1.0;
gl_BackColor.a = 0.0; gl_BackColor.a = 0.0;
setupShadows(ecPosition);
} }