1
0
Fork 0

Updates to 3D clouds to use the new shading parameters.

This commit is contained in:
Stuart Buchanan 2011-10-06 21:21:13 +01:00
parent fa16a54fa1
commit c0bebf5404
4 changed files with 120 additions and 71 deletions

View file

@ -43,8 +43,6 @@ The cloud is defined by the following properties:
<height-map-texture> - whether to choose the vertical texture index based on
sprite height within the clouds (default false)
<num-sprites> - Number of sprite to generate for the cloud (default 20)
<bottom-shade> - Light multiplier for sprites at the bottom of the cloud
(default 1.0)
<min-sprite-width-m> - minimum width of the sprites used to create the cloud
(default 200)
<max-sprite-width-m> - maximum width of the sprites used to create the cloud
@ -56,7 +54,39 @@ The cloud is defined by the following properties:
<z-scale> - vertical scaling factor to apply to to the sprite after
billboarding. A small value would create a sprite that
looks squashed when viewed from the side. (default 1.0)
<min-bottom-lighting-factor> - See Shading below (default 1.0)
<max-bottom-lighting-factor> - See Shading below (default min-...-factor + 0.1)
<min-middle-lighting-factor> - See Shading below (default 1.0)
<max-middle-lighting-factor> - See Shading below (default min-...-factor + 0.1)
<min-top-lighting-factor> - See Shading below (default 1.0)
<max-top-lighting-factor> - See Shading below (default min-...-factor + 0.1)
<min-shade-lighting-factor> - See Shading below (default 0.5)
<max-shade-lighting-factor> - See Shading below (default min-...-factor + 0.1)
Shading
-------
the [min|max]-...-lighting-factor properties allow you to define diffuse lighting
multipliers to the bottom, middle, top, sunny and shaded parts of the cloud. In
each case, individual clouds will have a random multiplier between the min and
max values used to allow for some variation between individual clouds.
The top, middle and bottom lighting factors are applied based on the pixels vertical
positon in the cloud. A linear interpolation is used either between top/middle (if
the pixel is above the middle of the cloud) or middle/bottom (if the pixel is below
the middle of the cloud).
The top factor is also applied to _all_ pixels on the sunny side of the cloud. The
shade factor is applied based on the pixel position away from the sun, linearly
interpolated from top to shade. E.g this is not a straight linear interpolation
from top to shade across the entire cloud.
The final lighting factor is determined by the minimum of the vertical factor and
the sunny/shade factor. Note that this is applied to the individual pixels, not
sprites.
Textures
--------
The texture to use for the sprites is defined in the <texture> tag.
To allow some variation, you can create a texture file containing multiple

View file

@ -60,6 +60,10 @@
<name>usrAttr2</name>
<index>11</index>
</attribute>
<attribute>
<name>usrAttr3</name>
<index>12</index>
</attribute>
</program>
<uniform>
<name>baseTexture</name>

View file

@ -35,33 +35,29 @@ ns = Nimbostratus (Rain cloud)
<clouds>
<cb-large>
<min-cloud-width-m>1600</min-cloud-width-m>
<max-cloud-width-m>2000</max-cloud-width-m>
<min-cloud-height-m>4000</min-cloud-height-m>
<max-cloud-height-m>3000</max-cloud-height-m>
<num-sprites>10</num-sprites>
<texture>cl_cumulus.png</texture>
<num-textures-x>4</num-textures-x>
<num-textures-y>4</num-textures-y>
<bottom-shade>0.3</bottom-shade>
<min-bottom-lighting-factor>0.3</min-bottom-lighting-factor>
<min-shade-lighting-factor>0.4</min-shade-lighting-factor>
<min-sprite-width-m>800</min-sprite-width-m>
<max-sprite-width-m>1200</max-sprite-width-m>
<min-sprite-height-m>800</min-sprite-height-m>
<max-sprite-height-m>1200</max-sprite-height-m>
<height-map-texture>true</height-map-texture>
</cb-large>
<cb-small>
<min-cloud-width-m>800</min-cloud-width-m>
<max-cloud-width-m>400</max-cloud-width-m>
<min-cloud-height-m>500</min-cloud-height-m>
<max-cloud-height-m>200</max-cloud-height-m>
<min-cloud-height-m>800</min-cloud-height-m>
<num-sprites>10</num-sprites>
<texture>cl_cumulus.png</texture>
<num-textures-x>4</num-textures-x>
<num-textures-y>4</num-textures-y>
<bottom-shade>0.3</bottom-shade>
<min-bottom-lighting-factor>0.3</min-bottom-lighting-factor>
<min-shade-lighting-factor>0.4</min-shade-lighting-factor>
<min-sprite-width-m>400</min-sprite-width-m>
<max-sprite-width-m>800</max-sprite-width-m>
<min-sprite-height-m>400</min-sprite-height-m>
<max-sprite-height-m>800</max-sprite-height-m>
<height-map-texture>true</height-map-texture>
</cb-small>
<cu-large>
<min-cloud-width-m>600</min-cloud-width-m>
@ -69,89 +65,95 @@ ns = Nimbostratus (Rain cloud)
<min-cloud-height-m>400</min-cloud-height-m>
<max-cloud-height-m>800</max-cloud-height-m>
<num-sprites>20</num-sprites>
<texture>cl_cumulus.png</texture>
<texture>cl_cumulus2.png</texture>
<num-textures-x>4</num-textures-x>
<num-textures-y>4</num-textures-y>
<bottom-shade>0.6</bottom-shade>
<min-bottom-lighting-factor>0.2</min-bottom-lighting-factor>
<min-shade-lighting-factor>0.3</min-shade-lighting-factor>
<min-sprite-width-m>400</min-sprite-width-m>
<max-sprite-width-m>700</max-sprite-width-m>
<min-sprite-height-m>300</min-sprite-height-m>
<max-sprite-height-m>700</max-sprite-height-m>
<height-map-texture>true</height-map-texture>
</cu-large>
<cu-small>
<min-cloud-width-m>300</min-cloud-width-m>
<max-cloud-width-m>800</max-cloud-width-m>
<min-cloud-height-m>200</min-cloud-height-m>
<max-cloud-height-m>300</max-cloud-height-m>
<num-sprites>10</num-sprites>
<texture>cl_cumulus.png</texture>
<min-cloud-width-m>600</min-cloud-width-m>
<max-cloud-width-m>900</max-cloud-width-m>
<min-cloud-height-m>400</min-cloud-height-m>
<max-cloud-height-m>600</max-cloud-height-m>
<num-sprites>20</num-sprites>
<texture>cl_cumulus2.png</texture>
<num-textures-x>4</num-textures-x>
<num-textures-y>4</num-textures-y>
<bottom-shade>0.7</bottom-shade>
<min-sprite-width-m>200</min-sprite-width-m>
<min-bottom-lighting-factor>0.4</min-bottom-lighting-factor>
<min-shade-lighting-factor>0.5</min-shade-lighting-factor>
<min-sprite-width-m>300</min-sprite-width-m>
<max-sprite-width-m>400</max-sprite-width-m>
<min-sprite-height-m>150</min-sprite-height-m>
<min-sprite-height-m>200</min-sprite-height-m>
<max-sprite-height-m>300</max-sprite-height-m>
<height-map-texture>true</height-map-texture>
</cu-small>
<ns-large>
<min-cloud-width-m>1200</min-cloud-width-m>
<max-cloud-width-m>3000</max-cloud-width-m>
<min-cloud-height-m>200</min-cloud-height-m>
<max-cloud-height-m>400</max-cloud-height-m>
<min-cloud-height-m>400</min-cloud-height-m>
<max-cloud-height-m>800</max-cloud-height-m>
<num-sprites>40</num-sprites>
<texture>cl_st.png</texture>
<num-textures-x>1</num-textures-x>
<num-textures-y>1</num-textures-y>
<bottom-shade>0.2</bottom-shade>
<min-bottom-lighting-factor>0.2</min-bottom-lighting-factor>
<min-sprite-width-m>300</min-sprite-width-m>
<max-sprite-width-m>600</max-sprite-width-m>
<min-sprite-height-m>100</min-sprite-height-m>
<max-sprite-height-m>200</max-sprite-height-m>
<height-map-texture>false</height-map-texture>
<z-scale>0.5</z-scale>
</ns-large>
<ns-white>
<min-cloud-width-m>600</min-cloud-width-m>
<max-cloud-width-m>2000</max-cloud-width-m>
<min-cloud-height-m>200</min-cloud-height-m>
<max-cloud-height-m>300</max-cloud-height-m>
<min-cloud-height-m>400</min-cloud-height-m>
<max-cloud-height-m>600</max-cloud-height-m>
<num-sprites>40</num-sprites>
<texture>cl_st.png</texture>
<num-textures-x>1</num-textures-x>
<num-textures-y>1</num-textures-y>
<bottom-shade>0.3</bottom-shade>
<min-bottom-lighting-factor>0.3</min-bottom-lighting-factor>
<min-sprite-width-m>300</min-sprite-width-m>
<max-sprite-width-m>600</max-sprite-width-m>
<min-sprite-height-m>100</min-sprite-height-m>
<max-sprite-height-m>200</max-sprite-height-m>
<height-map-texture>false</height-map-texture>
<z-scale>0.5</z-scale>
</ns-white>
<st-small>
<min-cloud-width-m>800</min-cloud-width-m>
<max-cloud-width-m>1500</max-cloud-width-m>
<min-cloud-height-m>100</min-cloud-height-m>
<max-cloud-height-m>200</max-cloud-height-m>
<num-sprites>40</num-sprites>
<texture>cl_st.png</texture>
<num-textures-x>1</num-textures-x>
<num-textures-y>1</num-textures-y>
<bottom-shade>0.9</bottom-shade>
<min-sprite-width-m>300</min-sprite-width-m>
<max-sprite-width-m>600</max-sprite-width-m>
<min-sprite-height-m>200</min-sprite-height-m>
<max-sprite-height-m>400</max-sprite-height-m>
</st-small>
<st-large>
<min-cloud-width-m>1800</min-cloud-width-m>
<max-cloud-width-m>2500</max-cloud-width-m>
<min-cloud-width-m>1000</min-cloud-width-m>
<min-cloud-height-m>200</min-cloud-height-m>
<max-cloud-height-m>400</max-cloud-height-m>
<num-sprites>40</num-sprites>
<texture>cl_st.png</texture>
<num-textures-x>1</num-textures-x>
<num-textures-y>1</num-textures-y>
<bottom-shade>0.9</bottom-shade>
<texture>cl_cumulus.png</texture>
<num-textures-x>4</num-textures-x>
<num-textures-y>4</num-textures-y>
<min-bottom-lighting-factor>0.9</min-bottom-lighting-factor>
<min-sprite-width-m>400</min-sprite-width-m>
<max-sprite-width-m>800</max-sprite-width-m>
<min-sprite-height-m>300</min-sprite-height-m>
<max-sprite-height-m>500</max-sprite-height-m>
<min-sprite-height-m>400</min-sprite-height-m>
<max-sprite-height-m>800</max-sprite-height-m>
<height-map-texture>false</height-map-texture>
<z-scale>0.3</z-scale>
</st-small>
<st-large>
<min-cloud-width-m>2000</min-cloud-width-m>
<min-cloud-height-m>1000</min-cloud-height-m>
<num-sprites>40</num-sprites>
<texture>cl_st.png</texture>
<num-textures-x>1</num-textures-x>
<num-textures-y>1</num-textures-y>
<min-bottom-lighting-factor>0.9</min-bottom-lighting-factor>
<min-sprite-width-m>600</min-sprite-width-m>
<min-sprite-height-m>600</min-sprite-height-m>
<height-map-texture>false</height-map-texture>
<z-scale>0.4</z-scale>
</st-large>
</clouds>
<boxes>

View file

@ -7,13 +7,17 @@ uniform float range; // From /sim/rendering/clouds3d-vis-range
attribute vec3 usrAttr1;
attribute vec3 usrAttr2;
attribute vec3 usrAttr3;
float textureIndexX = usrAttr1.r;
float textureIndexY = usrAttr1.g;
float wScale = usrAttr1.b;
float hScale = usrAttr2.r;
float shade = usrAttr2.g;
float shade_factor = usrAttr2.g;
float cloud_height = usrAttr2.b;
float bottom_factor = usrAttr3.r;
float middle_factor = usrAttr3.g;
float top_factor = usrAttr3.b;
void main(void)
{
@ -34,11 +38,12 @@ void main(void)
gl_Position.xyz = gl_Vertex.x * u;
gl_Position.xyz += gl_Vertex.y * r * wScale;
gl_Position.xyz += gl_Vertex.z * w * hScale;
gl_Position.xyz += gl_Color.xyz;
// Apply Z scaling to allow sprites to be squashed in the z-axis
gl_Position.z = gl_Position.z * gl_Color.w;
// Now shift the sprite to the correct position in the cloud.
gl_Position.xyz += gl_Color.xyz;
// Determine a lighting normal based on the vertex position from the
// center of the cloud, so that sprite on the opposite side of the cloud to the sun are darker.
float n = dot(normalize(-gl_LightSource[0].position.xyz),
@ -48,21 +53,29 @@ void main(void)
vec3 ecPosition = vec3(gl_ModelViewMatrix * gl_Position);
float fogCoord = abs(ecPosition.z);
// Determine fractional height of vertex from 0 at the bottom, and 1 at mid-height.
// Used to determine shading.
float fract = smoothstep(0.0, cloud_height, gl_Position.z + cloud_height);
// Determine the shading of the vertex. We shade it based on it's position
// in the cloud relative to the sun, and it's vertical position in the cloud.
float shade = mix(shade_factor, top_factor, smoothstep(-0.3, 0.0, n));
//if (n < 0) {
// shade = mix(top_factor, shade_factor, abs(n));
//}
float h = gl_Position.z;
shade = min(shade,
min(mix(bottom_factor, middle_factor, smoothstep(0.0, 0.5 * h, h)),
mix(middle_factor, top_factor, smoothstep(0.5 * h, h, h)) ) );
//float h = gl_Position.z / cloud_height;
//if (h < 0.5) {
// shade = min(shade, mix(bottom_factor, middle_factor, smoothstep(0.0, 0.5, h)));
//} else {
// shade = min(shade, mix(middle_factor, top_factor, smoothstep(2.0 * (h - 0.5)));
// }
// Final position of the sprite
gl_Position = gl_ModelViewProjectionMatrix * gl_Position;
// Determine the shading of the sprite based on its vertical position and position relative to the sun.
n = min(smoothstep(-0.5, 0.0, n), fract);
// Determine the shading based on a mixture from the backlight to the front
vec4 backlight = gl_LightSource[0].diffuse * shade;
gl_FrontColor = mix(backlight, gl_LightSource[0].diffuse, n);
gl_FrontColor += gl_FrontLightModelProduct.sceneColor;
gl_FrontColor = gl_LightSource[0].diffuse * shade + gl_FrontLightModelProduct.sceneColor;
// As we get within 100m of the sprite, it is faded out. Equally at large distances it also fades out.
gl_FrontColor.a = min(smoothstep(10.0, 100.0, fogCoord), 1.0 - smoothstep(range*0.8, range, fogCoord));