Domain tiling effect for ALS tree shader
This commit is contained in:
parent
0a2702c375
commit
b1d909b22e
5 changed files with 241 additions and 2 deletions
|
@ -36,6 +36,7 @@
|
||||||
<quality_level><use>/sim/rendering/shaders/landmass</use></quality_level>
|
<quality_level><use>/sim/rendering/shaders/landmass</use></quality_level>
|
||||||
<tquality_level><use>/sim/rendering/shaders/transition</use></tquality_level>
|
<tquality_level><use>/sim/rendering/shaders/transition</use></tquality_level>
|
||||||
<wind_effects><use>/sim/rendering/shaders/wind-effects</use></wind_effects>
|
<wind_effects><use>/sim/rendering/shaders/wind-effects</use></wind_effects>
|
||||||
|
<forest_effects><use>/sim/rendering/shaders/forest</use></forest_effects>
|
||||||
<windE><use>/environment/sea/surface/wind-from-east-fps</use></windE>
|
<windE><use>/environment/sea/surface/wind-from-east-fps</use></windE>
|
||||||
<windN><use>/environment/sea/surface/wind-from-north-fps</use></windN>
|
<windN><use>/environment/sea/surface/wind-from-north-fps</use></windN>
|
||||||
<cloudpos1_x><use>/local-weather/cloud-shadows/cloudpos-x[0]</use></cloudpos1_x>
|
<cloudpos1_x><use>/local-weather/cloud-shadows/cloudpos-x[0]</use></cloudpos1_x>
|
||||||
|
@ -119,6 +120,7 @@
|
||||||
<alpha-to-coverage>true</alpha-to-coverage>
|
<alpha-to-coverage>true</alpha-to-coverage>
|
||||||
<program>
|
<program>
|
||||||
<vertex-shader>Shaders/tree-haze.vert</vertex-shader>
|
<vertex-shader>Shaders/tree-haze.vert</vertex-shader>
|
||||||
|
<vertex-shader>Shaders/noise.frag</vertex-shader>
|
||||||
<vertex-shader>Shaders/cloud-shadowfunc.frag</vertex-shader>
|
<vertex-shader>Shaders/cloud-shadowfunc.frag</vertex-shader>
|
||||||
<fragment-shader>Shaders/tree-haze.frag</fragment-shader>
|
<fragment-shader>Shaders/tree-haze.frag</fragment-shader>
|
||||||
</program>
|
</program>
|
||||||
|
@ -427,6 +429,11 @@
|
||||||
<type>int</type>
|
<type>int</type>
|
||||||
<value><use>wind_effects</use></value>
|
<value><use>wind_effects</use></value>
|
||||||
</uniform>
|
</uniform>
|
||||||
|
<uniform>
|
||||||
|
<name>forest_effects</name>
|
||||||
|
<type>int</type>
|
||||||
|
<value><use>forest_effects</use></value>
|
||||||
|
</uniform>
|
||||||
</pass>
|
</pass>
|
||||||
</technique>
|
</technique>
|
||||||
|
|
||||||
|
@ -472,6 +479,7 @@
|
||||||
</alpha-test>
|
</alpha-test>
|
||||||
<program>
|
<program>
|
||||||
<vertex-shader>Shaders/tree-haze.vert</vertex-shader>
|
<vertex-shader>Shaders/tree-haze.vert</vertex-shader>
|
||||||
|
<vertex-shader>Shaders/noise.frag</vertex-shader>
|
||||||
<vertex-shader>Shaders/cloud-shadowfunc.frag</vertex-shader>
|
<vertex-shader>Shaders/cloud-shadowfunc.frag</vertex-shader>
|
||||||
<fragment-shader>Shaders/tree-haze.frag</fragment-shader>
|
<fragment-shader>Shaders/tree-haze.frag</fragment-shader>
|
||||||
</program>
|
</program>
|
||||||
|
@ -780,6 +788,11 @@
|
||||||
<type>int</type>
|
<type>int</type>
|
||||||
<value><use>wind_effects</use></value>
|
<value><use>wind_effects</use></value>
|
||||||
</uniform>
|
</uniform>
|
||||||
|
<uniform>
|
||||||
|
<name>forest_effects</name>
|
||||||
|
<type>int</type>
|
||||||
|
<value><use>forest_effects</use></value>
|
||||||
|
</uniform>
|
||||||
</pass>
|
</pass>
|
||||||
</technique>
|
</technique>
|
||||||
|
|
||||||
|
|
192
Shaders/noise.frag
Normal file
192
Shaders/noise.frag
Normal file
|
@ -0,0 +1,192 @@
|
||||||
|
// -*-C++-*-
|
||||||
|
|
||||||
|
// This is a library of noise functions, taking a coordinate vector and a wavelength
|
||||||
|
// as input and returning a number [0:1] as output.
|
||||||
|
|
||||||
|
// * Noise2D(in vec2 coord, in float wavelength) is 2d Perlin noise
|
||||||
|
// * Noise3D(in vec3 coord, in float wavelength) is 3d Perlin noise
|
||||||
|
// * DotNoise2D(in vec2 coord, in float wavelength, in float fractionalMaxDotSize, in float dDensity)
|
||||||
|
// is sparse dot noise and takes a dot density parameter
|
||||||
|
// * VoronoiNoise2D(in vec2 coord, in float wavelength, in float xrand, in float yrand)
|
||||||
|
// is a function mapping the terrain into random domains, based on Voronoi tiling of a regular grid
|
||||||
|
// distorted with xrand and yrand
|
||||||
|
|
||||||
|
// Thorsten Renk 2014
|
||||||
|
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
|
||||||
|
float rand2D(in vec2 co){
|
||||||
|
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
|
||||||
|
}
|
||||||
|
|
||||||
|
float rand3D(in vec3 co){
|
||||||
|
return fract(sin(dot(co.xyz ,vec3(12.9898,78.233,144.7272))) * 43758.5453);
|
||||||
|
}
|
||||||
|
|
||||||
|
float cosine_interpolate(in float a, in float b, in float x)
|
||||||
|
{
|
||||||
|
float ft = x * 3.1415927;
|
||||||
|
float f = (1.0 - cos(ft)) * .5;
|
||||||
|
|
||||||
|
return a*(1.0-f) + b*f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float simple_interpolate(in float a, in float b, in float x)
|
||||||
|
{
|
||||||
|
return a + smoothstep(0.0,1.0,x) * (b-a);
|
||||||
|
}
|
||||||
|
|
||||||
|
float interpolatedNoise2D(in float x, in float y)
|
||||||
|
{
|
||||||
|
float integer_x = x - fract(x);
|
||||||
|
float fractional_x = x - integer_x;
|
||||||
|
|
||||||
|
float integer_y = y - fract(y);
|
||||||
|
float fractional_y = y - integer_y;
|
||||||
|
|
||||||
|
float v1 = rand2D(vec2(integer_x, integer_y));
|
||||||
|
float v2 = rand2D(vec2(integer_x+1.0, integer_y));
|
||||||
|
float v3 = rand2D(vec2(integer_x, integer_y+1.0));
|
||||||
|
float v4 = rand2D(vec2(integer_x+1.0, integer_y +1.0));
|
||||||
|
|
||||||
|
float i1 = simple_interpolate(v1 , v2 , fractional_x);
|
||||||
|
float i2 = simple_interpolate(v3 , v4 , fractional_x);
|
||||||
|
|
||||||
|
return simple_interpolate(i1 , i2 , fractional_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
float interpolatedNoise3D(in float x, in float y, in float z)
|
||||||
|
{
|
||||||
|
float integer_x = x - fract(x);
|
||||||
|
float fractional_x = x - integer_x;
|
||||||
|
|
||||||
|
float integer_y = y - fract(y);
|
||||||
|
float fractional_y = y - integer_y;
|
||||||
|
|
||||||
|
float integer_z = z - fract(z);
|
||||||
|
float fractional_z = z - integer_z;
|
||||||
|
|
||||||
|
float v1 = rand3D(vec3(integer_x, integer_y, integer_z));
|
||||||
|
float v2 = rand3D(vec3(integer_x+1.0, integer_y, integer_z));
|
||||||
|
float v3 = rand3D(vec3(integer_x, integer_y+1.0, integer_z));
|
||||||
|
float v4 = rand3D(vec3(integer_x+1.0, integer_y +1.0, integer_z));
|
||||||
|
|
||||||
|
float v5 = rand3D(vec3(integer_x, integer_y, integer_z+1.0));
|
||||||
|
float v6 = rand3D(vec3(integer_x+1.0, integer_y, integer_z+1.0));
|
||||||
|
float v7 = rand3D(vec3(integer_x, integer_y+1.0, integer_z+1.0));
|
||||||
|
float v8 = rand3D(vec3(integer_x+1.0, integer_y +1.0, integer_z+1.0));
|
||||||
|
|
||||||
|
|
||||||
|
float i1 = simple_interpolate(v1,v5, fractional_z);
|
||||||
|
float i2 = simple_interpolate(v2,v6, fractional_z);
|
||||||
|
float i3 = simple_interpolate(v3,v7, fractional_z);
|
||||||
|
float i4 = simple_interpolate(v4,v8, fractional_z);
|
||||||
|
|
||||||
|
float ii1 = simple_interpolate(i1,i2,fractional_x);
|
||||||
|
float ii2 = simple_interpolate(i3,i4,fractional_x);
|
||||||
|
|
||||||
|
|
||||||
|
return simple_interpolate(ii1 , ii2 , fractional_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float Noise2D(in vec2 coord, in float wavelength)
|
||||||
|
{
|
||||||
|
return interpolatedNoise2D(coord.x/wavelength, coord.y/wavelength);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
float Noise3D(in vec3 coord, in float wavelength)
|
||||||
|
{
|
||||||
|
return interpolatedNoise3D(coord.x/wavelength, coord.y/wavelength, coord.z/wavelength);
|
||||||
|
}
|
||||||
|
|
||||||
|
float dotNoise2D(in float x, in float y, in float fractionalMaxDotSize, in float dDensity)
|
||||||
|
{
|
||||||
|
float integer_x = x - fract(x);
|
||||||
|
float fractional_x = x - integer_x;
|
||||||
|
|
||||||
|
float integer_y = y - fract(y);
|
||||||
|
float fractional_y = y - integer_y;
|
||||||
|
|
||||||
|
if (rand2D(vec2(integer_x+1.0, integer_y +1.0)) > dDensity)
|
||||||
|
{return 0.0;}
|
||||||
|
|
||||||
|
float xoffset = (rand2D(vec2(integer_x, integer_y)) -0.5);
|
||||||
|
float yoffset = (rand2D(vec2(integer_x+1.0, integer_y)) - 0.5);
|
||||||
|
float dotSize = 0.5 * fractionalMaxDotSize * max(0.25,rand2D(vec2(integer_x, integer_y+1.0)));
|
||||||
|
|
||||||
|
|
||||||
|
vec2 truePos = vec2 (0.5 + xoffset * (1.0 - 2.0 * dotSize) , 0.5 + yoffset * (1.0 -2.0 * dotSize));
|
||||||
|
|
||||||
|
float distance = length(truePos - vec2(fractional_x, fractional_y));
|
||||||
|
|
||||||
|
return 1.0 - smoothstep (0.3 * dotSize, 1.0* dotSize, distance);
|
||||||
|
}
|
||||||
|
|
||||||
|
float DotNoise2D(in vec2 coord, in float wavelength, in float fractionalMaxDotSize, in float dDensity)
|
||||||
|
{
|
||||||
|
return dotNoise2D(coord.x/wavelength, coord.y/wavelength, fractionalMaxDotSize, dDensity);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float voronoiNoise2D(in float x, in float y, in float xrand, in float yrand)
|
||||||
|
{
|
||||||
|
float integer_x = x - fract(x);
|
||||||
|
float fractional_x = x - integer_x;
|
||||||
|
|
||||||
|
float integer_y = y - fract(y);
|
||||||
|
float fractional_y = y - integer_y;
|
||||||
|
|
||||||
|
float val[4];
|
||||||
|
|
||||||
|
val[0] = rand2D(vec2(integer_x, integer_y));
|
||||||
|
val[1] = rand2D(vec2(integer_x+1.0, integer_y));
|
||||||
|
val[2] = rand2D(vec2(integer_x, integer_y+1.0));
|
||||||
|
val[3] = rand2D(vec2(integer_x+1.0, integer_y+1.0));
|
||||||
|
|
||||||
|
float xshift[4];
|
||||||
|
|
||||||
|
xshift[0] = xrand * (rand2D(vec2(integer_x+0.5, integer_y)) - 0.5);
|
||||||
|
xshift[1] = xrand * (rand2D(vec2(integer_x+1.5, integer_y)) -0.5);
|
||||||
|
xshift[2] = xrand * (rand2D(vec2(integer_x+0.5, integer_y+1.0))-0.5);
|
||||||
|
xshift[3] = xrand * (rand2D(vec2(integer_x+1.5, integer_y+1.0))-0.5);
|
||||||
|
|
||||||
|
float yshift[4];
|
||||||
|
|
||||||
|
yshift[0] = yrand * (rand2D(vec2(integer_x, integer_y +0.5)) - 0.5);
|
||||||
|
yshift[1] = yrand * (rand2D(vec2(integer_x+1.0, integer_y+0.5)) -0.5);
|
||||||
|
yshift[2] = yrand * (rand2D(vec2(integer_x, integer_y+1.5))-0.5);
|
||||||
|
yshift[3] = yrand * (rand2D(vec2(integer_x+1.5, integer_y+1.5))-0.5);
|
||||||
|
|
||||||
|
|
||||||
|
float dist[4];
|
||||||
|
|
||||||
|
dist[0] = sqrt((fractional_x + xshift[0]) * (fractional_x + xshift[0]) + (fractional_y + yshift[0]) * (fractional_y + yshift[0]));
|
||||||
|
dist[1] = sqrt((1.0 -fractional_x + xshift[1]) * (1.0-fractional_x+xshift[1]) + (fractional_y +yshift[1]) * (fractional_y+yshift[1]));
|
||||||
|
dist[2] = sqrt((fractional_x + xshift[2]) * (fractional_x + xshift[2]) + (1.0-fractional_y +yshift[2]) * (1.0-fractional_y + yshift[2]));
|
||||||
|
dist[3] = sqrt((1.0-fractional_x + xshift[3]) * (1.0-fractional_x + xshift[3]) + (1.0-fractional_y +yshift[3]) * (1.0-fractional_y + yshift[3]));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int i, i_min;
|
||||||
|
float dist_min = 100.0;
|
||||||
|
for (i=0; i<4;i++)
|
||||||
|
{
|
||||||
|
if (dist[i] < dist_min)
|
||||||
|
{
|
||||||
|
dist_min = dist[i];
|
||||||
|
i_min = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return val[i_min];
|
||||||
|
//return val[0];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
float VoronoiNoise2D(in vec2 coord, in float wavelength, in float xrand, in float yrand)
|
||||||
|
{
|
||||||
|
return voronoiNoise2D(coord.x/wavelength, coord.y/wavelength, xrand, yrand);
|
||||||
|
}
|
|
@ -25,6 +25,7 @@ varying float yprime_alt;
|
||||||
|
|
||||||
uniform int colorMode;
|
uniform int colorMode;
|
||||||
uniform int wind_effects;
|
uniform int wind_effects;
|
||||||
|
uniform int forest_effects;
|
||||||
uniform float hazeLayerAltitude;
|
uniform float hazeLayerAltitude;
|
||||||
uniform float terminator;
|
uniform float terminator;
|
||||||
uniform float terrain_alt;
|
uniform float terrain_alt;
|
||||||
|
@ -45,6 +46,7 @@ float earthShade;
|
||||||
float mie_angle;
|
float mie_angle;
|
||||||
|
|
||||||
float shadow_func (in float x, in float y, in float noise, in float dist);
|
float shadow_func (in float x, in float y, in float noise, in float dist);
|
||||||
|
float VoronoiNoise2D(in vec2 coord, in float wavelength, in float xrand, in float yrand);
|
||||||
|
|
||||||
// This is the value used in the skydome scattering shader - use the same here for consistency?
|
// This is the value used in the skydome scattering shader - use the same here for consistency?
|
||||||
const float EarthRadius = 5800000.0;
|
const float EarthRadius = 5800000.0;
|
||||||
|
@ -105,6 +107,13 @@ void main()
|
||||||
position.y = position.y + position.z * (sin(osg_SimulationTime * 1.8 + (gl_Color.x + gl_Color.y + gl_Color.z) * 0.01) + 1.0) * 0.0025 * WindE;
|
position.y = position.y + position.z * (sin(osg_SimulationTime * 1.8 + (gl_Color.x + gl_Color.y + gl_Color.z) * 0.01) + 1.0) * 0.0025 * WindE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Scale by random domains
|
||||||
|
if (forest_effects > 0)
|
||||||
|
{
|
||||||
|
float voronoi = 0.5 + 1.0 * VoronoiNoise2D(gl_Color.xy, 200.0, 1.5, 1.5);
|
||||||
|
position.xyz = position.xyz * voronoi;
|
||||||
|
}
|
||||||
|
|
||||||
// Move to correct location (stored in gl_Color)
|
// Move to correct location (stored in gl_Color)
|
||||||
position = position + gl_Color.xyz;
|
position = position + gl_Color.xyz;
|
||||||
gl_Position = gl_ModelViewProjectionMatrix * vec4(position,1.0);
|
gl_Position = gl_ModelViewProjectionMatrix * vec4(position,1.0);
|
||||||
|
|
|
@ -173,6 +173,30 @@
|
||||||
</empty>
|
</empty>
|
||||||
</group>
|
</group>
|
||||||
|
|
||||||
|
<group>
|
||||||
|
<layout>hbox</layout>
|
||||||
|
<halign>right</halign>
|
||||||
|
<text>
|
||||||
|
<label>Forest</label>
|
||||||
|
</text>
|
||||||
|
<slider>
|
||||||
|
<name>forest</name>
|
||||||
|
<min>0.0</min>
|
||||||
|
<max>1.0</max>
|
||||||
|
<step>1.0</step>
|
||||||
|
<fraction>0.17</fraction>
|
||||||
|
<live>true</live>
|
||||||
|
<property>/sim/rendering/shaders/forest</property>
|
||||||
|
<binding>
|
||||||
|
<command>dialog-apply</command>
|
||||||
|
<object-name>forest</object-name>
|
||||||
|
</binding>
|
||||||
|
</slider>
|
||||||
|
<empty>
|
||||||
|
<pref-width>55</pref-width>
|
||||||
|
</empty>
|
||||||
|
</group>
|
||||||
|
|
||||||
<group>
|
<group>
|
||||||
<layout>hbox</layout>
|
<layout>hbox</layout>
|
||||||
<halign>right</halign>
|
<halign>right</halign>
|
||||||
|
@ -196,7 +220,7 @@
|
||||||
<pref-width>55</pref-width>
|
<pref-width>55</pref-width>
|
||||||
</empty>
|
</empty>
|
||||||
</group>
|
</group>
|
||||||
|
<!--
|
||||||
<group>
|
<group>
|
||||||
<layout>hbox</layout>
|
<layout>hbox</layout>
|
||||||
<visible>
|
<visible>
|
||||||
|
@ -302,7 +326,7 @@
|
||||||
<live>true</live>
|
<live>true</live>
|
||||||
<property>/sim/rendering/dome-density</property>
|
<property>/sim/rendering/dome-density</property>
|
||||||
</text>
|
</text>
|
||||||
</group>
|
</group>-->
|
||||||
|
|
||||||
<group>
|
<group>
|
||||||
<layout>hbox</layout>
|
<layout>hbox</layout>
|
||||||
|
|
|
@ -146,6 +146,7 @@ Started September 2000 by David Megginson, david@megginson.com
|
||||||
<urban type="float" userarchive="y">1.0</urban>
|
<urban type="float" userarchive="y">1.0</urban>
|
||||||
<water type="float" userarchive="y">1.0</water>
|
<water type="float" userarchive="y">1.0</water>
|
||||||
<wind-effects type="float" userarchive="y">0.0</wind-effects>
|
<wind-effects type="float" userarchive="y">0.0</wind-effects>
|
||||||
|
<forest type="float" userarchive="y">0.0</forest>
|
||||||
<lights type="float" userarchive="y">1.0</lights>
|
<lights type="float" userarchive="y">1.0</lights>
|
||||||
<quality-level-internal type="float" userarchive="y">1.0</quality-level-internal>
|
<quality-level-internal type="float" userarchive="y">1.0</quality-level-internal>
|
||||||
</shaders>
|
</shaders>
|
||||||
|
|
Loading…
Reference in a new issue