1
0
Fork 0

Instance based random buildings

Replace random buildings with one using proper instancing.
Also implement more control over rendering of random buildings.
see README.scenery for details.
This commit is contained in:
Stuart Buchanan 2019-08-20 17:02:27 +01:00
parent 81fc15d8e7
commit 4784a929d7
12 changed files with 503 additions and 217 deletions

View file

@ -400,6 +400,25 @@ See README.materials for details on configuring the random building parameters.
The referenced <filename> (in the example buildings.txt) contains lines of the form
X Y Z R B W D H P S O F T
Where:
- X,Y,Z are the cartesian coordinates of the center of the front face. +X is East, +Y is North
- R is the building rotation in degrees centered on the middle of the front face.
- B is the building type [0, 1, 2] for SMALL, MEDIUM, LARGE
- W is the building width in meters
- D is the building depth in meters
- H is the building height in meters, excluding any pitched roof
- P is the pitch height in meters. 0 for a flat roof
- S is the roof shape (currently unused - all roofs are flat or gabled depending on pitch height) :
0=flat 1=skillion 2=gabled 3=half-hipped 4=hipped 5=pyramidal 6=gambled
7=mansard 8=dome 9=onion 10=round 11=saltbox
- O is the roof ridge orientation (currently unused, all roofs are assumed orthogonal) :
0 = parallel to the front face of the building
1 = orthogonal to the front face of the building
- F is the number of floors (integer)
- T is the texture index to use (integer). Buildings with the same T value will have the same texture assigned. There are 6 small, 6 medium and 4 large textures.
<x> <y> <z> <rot> <type>
where :

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 KiB

After

Width:  |  Height:  |  Size: 816 KiB

View file

@ -7,7 +7,7 @@
<type>2d</type>
<image>Textures/buildings.png</image>
<filter>linear-mipmap-linear</filter>
<wrap-s>clamp</wrap-s>
<wrap-s>repeat</wrap-s>
<wrap-t>clamp</wrap-t>
<internal-format>normalized</internal-format>
</texture>
@ -19,7 +19,7 @@
<image>Textures/buildings-normalmap_orig.png</image>
<type>2d</type>
<filter>linear-mipmap-linear</filter>
<wrap-s>clamp</wrap-s>
<wrap-s>repeat</wrap-s>
<wrap-t>clamp</wrap-t>
<internal-format>normalized</internal-format>
</texture>
@ -63,6 +63,12 @@
<negative-z>Aircraft/Generic/Effects/CubeMaps/buildings/D.png</negative-z>
</images>
</texture>
<texture n="6">
<!-- instance information from shader -->
<type>2d</type>
<wrap-s>clamp</wrap-s>
<wrap-t>clamp</wrap-t>
</texture>
<!--Ambient correction -->
<ambient-correction type="float"> 0.0 </ambient-correction>
<dirt-enabled type="int"> 0 </dirt-enabled>
@ -169,27 +175,27 @@
<color-mask type="vec4d">0 0 0 0</color-mask>
</pass>-->
<pass>
<texture-unit n="4">
<unit>4</unit>
<image>
<use>texture[3]/image</use>
</image>
<type>
<use>texture[3]/type</use>
</type>
<filter>
<use>texture[3]/filter</use>
</filter>
<wrap-s>
<use>texture[3]/wrap-s</use>
</wrap-s>
<wrap-t>
<use>texture[3]/wrap-t</use>
</wrap-t>
<internal-format>
<use>texture[3]/internal-format</use>
</internal-format>
</texture-unit>
<texture-unit n="4">
<unit>4</unit>
<image>
<use>texture[3]/image</use>
</image>
<type>
<use>texture[3]/type</use>
</type>
<filter>
<use>texture[3]/filter</use>
</filter>
<wrap-s>
<use>texture[3]/wrap-s</use>
</wrap-s>
<wrap-t>
<use>texture[3]/wrap-t</use>
</wrap-t>
<internal-format>
<use>texture[3]/internal-format</use>
</internal-format>
</texture-unit>
<program>
<vertex-shader n="0">Shaders/building-model-ALS-ultra.vert</vertex-shader>
<!--<fragment-shader n="0">Shaders/model-ALS-ultra.frag</fragment-shader>
@ -197,6 +203,22 @@
<fragment-shader n="2">Shaders/hazes.frag</fragment-shader>
<fragment-shader n="3">Shaders/secondary_lights.frag</fragment-shader>
<fragment-shader n="4">Shaders/filters-ALS.frag</fragment-shader>-->
<attribute>
<name>instancePosition</name>
<index>10</index>
</attribute>
<attribute>
<name>instanceScaleRotate</name>
<index>11</index>
</attribute>
<attribute>
<name>rotPitchTex0x</name>
<index>12</index>
</attribute>
<attribute>
<name>tex0yTex1xTex1y</name>
<index>13</index>
</attribute>
</program>
</pass>
</technique>
@ -249,6 +271,17 @@
<use>texture[0]/internal-format</use>
</internal-format>
</texture-unit>
<texture-unit>
<unit>1</unit>
<image><use>texture[6]/image</use></image>
<type><use>texture[6]/type</use></type>
<filter><use>texture[6]/filter</use></filter>
<wrap-s><use>texture[6]/wrap-s</use></wrap-s>
<wrap-t><use>texture[6]/wrap-t</use></wrap-t>
<internal-format>
<use>texture[6]/internal-format</use>
</internal-format>
</texture-unit>
<program>
<!--<vertex-shader n="0">Shaders/include_fog.vert</vertex-shader>-->
<!--<vertex-shader n="1">Shaders/building-default.vert</vertex-shader>-->
@ -256,12 +289,33 @@
<fragment-shader>Shaders/trivial.frag</fragment-shader>
<!--<fragment-shader n="0">Shaders/include_fog.frag</fragment-shader>
<fragment-shader n="1">Shaders/terrain-nocolor.frag</fragment-shader>-->
<attribute>
<name>instancePosition</name>
<index>10</index>
</attribute>
<attribute>
<name>instanceScaleRotate</name>
<index>11</index>
</attribute>
<attribute>
<name>rotPitchTex0x</name>
<index>12</index>
</attribute>
<attribute>
<name>tex0yTex1xTex1y</name>
<index>13</index>
</attribute>
</program>
<uniform>
<name>texture</name>
<type>sampler-2d</type>
<value type="int">0</value>
</uniform>
<uniform>
<name>dataBuffer</name>
<type>sampler-1d</type>
<value type="int">1</value>
</uniform>
<color-mask type="vec4d">0 0 0 0</color-mask>
</pass>
<pass>
@ -293,12 +347,39 @@
<use>texture[0]/internal-format</use>
</internal-format>
</texture-unit>
<texture-unit>
<unit>1</unit>
<image><use>texture[6]/image</use></image>
<type><use>texture[6]/type</use></type>
<filter><use>texture[6]/filter</use></filter>
<wrap-s><use>texture[6]/wrap-s</use></wrap-s>
<wrap-t><use>texture[6]/wrap-t</use></wrap-t>
<internal-format>
<use>texture[6]/internal-format</use>
</internal-format>
</texture-unit>
<program>
<vertex-shader>Shaders/building-ALS.vert</vertex-shader>
<fragment-shader>Shaders/terrain-ALS-base.frag</fragment-shader>
<fragment-shader>Shaders/hazes.frag</fragment-shader>
<fragment-shader>Shaders/filters-ALS.frag</fragment-shader>
<fragment-shader>Shaders/noise.frag</fragment-shader>
<attribute>
<name>instancePosition</name>
<index>10</index>
</attribute>
<attribute>
<name>instanceScaleRotate</name>
<index>11</index>
</attribute>
<attribute>
<name>rotPitchTex0x</name>
<index>12</index>
</attribute>
<attribute>
<name>tex0yTex1xTex1y</name>
<index>13</index>
</attribute>
</program>
<uniform>
<name>visibility</name>
@ -360,6 +441,11 @@
<type>sampler-2d</type>
<value type="int">0</value>
</uniform>
<uniform>
<name>dataBuffer</name>
<type>sampler-1d</type>
<value type="int">1</value>
</uniform>
<uniform>
<name>colorMode</name>
<type>int</type>
@ -387,7 +473,7 @@
</material>
<texture-unit n="4">
<unit>4</unit>
<image>
<image>
<use>texture[3]/image</use>
</image>
<type>
@ -408,10 +494,26 @@
</texture-unit>
<program n="0">
<vertex-shader n="0">Shaders/building-ubershader.vert</vertex-shader>
<attribute>
<name>instancePosition</name>
<index>10</index>
</attribute>
<attribute>
<name>instanceScaleRotate</name>
<index>11</index>
</attribute>
<attribute>
<name>rotPitchTex0x</name>
<index>12</index>
</attribute>
<attribute>
<name>tex0yTex1xTex1y</name>
<index>13</index>
</attribute>
</program>
</pass>
</technique>
<technique n="9">
<pass>
<material>
@ -427,7 +529,7 @@
</material>
<texture-unit n="4">
<unit>4</unit>
<image>
<image>
<use>texture[3]/image</use>
</image>
<type>
@ -448,25 +550,25 @@
</texture-unit>
<program n="0">
<vertex-shader n="0">Shaders/building-ubershader.vert</vertex-shader>
<attribute>
<name>instancePosition</name>
<index>10</index>
</attribute>
<attribute>
<name>instanceScaleRotate</name>
<index>11</index>
</attribute>
<attribute>
<name>rotPitchTex0x</name>
<index>12</index>
</attribute>
<attribute>
<name>tex0yTex1xTex1y</name>
<index>13</index>
</attribute>
</program>
</pass>
</technique>
<technique n="10">
<pass>
<program n="0">
<vertex-shader n="0">Shaders/building-deferred-gbuffer.vert</vertex-shader>
</program>
</pass>
</technique>
<technique n="11">
<pass>
<program n="0">
<vertex-shader n="0">Shaders/building-default.vert</vertex-shader>
</program>
</pass>
</technique>
</technique>
<technique n="12">
<pass>
@ -543,6 +645,17 @@
</internal-format>
-->
</texture-unit>
<texture-unit>
<unit>1</unit>
<image><use>texture[6]/image</use></image>
<type><use>texture[6]/type</use></type>
<filter><use>texture[6]/filter</use></filter>
<wrap-s><use>texture[6]/wrap-s</use></wrap-s>
<wrap-t><use>texture[6]/wrap-t</use></wrap-t>
<internal-format>
<use>texture[6]/internal-format</use>
</internal-format>
</texture-unit>
<vertex-program-two-side>
<use>vertex-program-two-side</use>
</vertex-program-two-side>
@ -551,6 +664,22 @@
<fragment-shader n="0">Shaders/include_fog.frag</fragment-shader>
<!--fog include-->
<fragment-shader n="1">Shaders/default.frag</fragment-shader>
<attribute>
<name>instancePosition</name>
<index>10</index>
</attribute>
<attribute>
<name>instanceScaleRotate</name>
<index>11</index>
</attribute>
<attribute>
<name>rotPitchTex0x</name>
<index>12</index>
</attribute>
<attribute>
<name>tex0yTex1xTex1y</name>
<index>13</index>
</attribute>
</program>
<!-- BEGIN fog include -->
<!--<uniform>
@ -601,6 +730,11 @@
<type>sampler-2d</type>
<value type="int">0</value>
</uniform>
<uniform>
<name>dataBuffer</name>
<type>sampler-1d</type>
<value type="int">1</value>
</uniform>
<uniform>
<name>colorMode</name>
<type>int</type>
@ -609,6 +743,6 @@
</value>
</uniform>
</pass>
</technique>
</technique>
</PropertyList>

View file

@ -1,5 +1,6 @@
// -*-C++-*-
#version 120
#extension GL_EXT_draw_instanced : enable
// Shader that uses OpenGL state values to do per-pixel lighting
//
@ -15,6 +16,11 @@
#define MODE_DIFFUSE 1
#define MODE_AMBIENT_AND_DIFFUSE 2
attribute vec3 instancePosition; // (x,y,z)
attribute vec3 instanceScaleRotate; // (width, depth, height)
attribute vec3 rotPitchTex0x; // (rotation, pitch height, texture x offset)
attribute vec3 tex0yTex1xTex1y; // (texture y offset, texture x gain, texture y gain)
// The constant term of the lighting equation that doesn't depend on
// 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
@ -32,7 +38,7 @@ varying float mie_angle;
uniform int colorMode;
uniform float hazeLayerAltitude;
uniform float terminator;
uniform float terrain_alt;
uniform float terrain_alt;
uniform float avisibility;
uniform float visibility;
uniform float overcast;
@ -74,27 +80,46 @@ void main()
float scattering;
vec3 shadedFogColor = vec3(0.55, 0.67, 0.88);
// this code is copied from default.vert
// Determine the rotation for the building.
float sr = sin(6.28 * rotPitchTex0x.x);
float cr = cos(6.28 * rotPitchTex0x.x);
// Adjust pitch of roof to the correct height.
// The top roof vertices are the only ones that have fractional z values (1.5),
// so we can use this to identify them and scale up any pitched roof vertex to
// the correct pitch (rotPitchTex0x.y * 2.0 because of the fractional z value),
// then scale down by the building height (instanceScaleRotate.z) because
// immediately afterwards we will scale UP the vertex to the correct scale.
vec3 position = gl_Vertex.xyz;
position.z = position.z + fract(position.z) * 2.0 * rotPitchTex0x.y / instanceScaleRotate.z - fract(position.z);
position = position * instanceScaleRotate.xyz;
// Rotation of the building and movement into position
position.xy = vec2(dot(position.xy, vec2(cr, sr)), dot(position.xy, vec2(-sr, cr)));
position = position + instancePosition.xyz;
gl_Position = gl_ModelViewProjectionMatrix * vec4(position,1.0);
// Texture coordinates are stored as tex0 and tex1 across two attributes.
// tex0 contains the bottom leftmost point, and tex1 contains (w,h).
gl_TexCoord[0].x = sign(gl_MultiTexCoord0.x) * rotPitchTex0x.z + gl_MultiTexCoord0.x * tex0yTex1xTex1y.y;
gl_TexCoord[0].y = tex0yTex1xTex1y.x + gl_MultiTexCoord0.y * tex0yTex1xTex1y.z;
// Rotate the normal.
normal = gl_Normal;
// The roof pieces have a normal of (+/-0.7, 0.0, 0.7)
// If the roof is flat, then we need to change it to (0,0,1).
// First term evaluates for normals without a +z component (all except roof)
// Second term evaluates for roof normals with a pitch
// Third term evaluates for flat roofs
normal = step(0.5, 1.0 - normal.z) * normal + step(0.5, normal.z) * clamp(rotPitchTex0x.y, 0.0, 1.0) * normal + step(0.5, normal.z) * (1.0 - clamp(rotPitchTex0x.y, 0.0, 1.0)) * vec3(0,0,1);
// Rotate the normal as per the building.
normal.xy = vec2(dot(normal.xy, vec2(cr, sr)), dot(normal.xy, vec2(-sr, cr)));
normal = gl_NormalMatrix * normal;
//vec4 ecPosition = gl_ModelViewMatrix * gl_Vertex;
// Determine the rotation for the building. The Color alpha value provides rotation information
float sr = sin(6.28 * gl_Color.a);
float cr = cos(6.28 * gl_Color.a);
vec3 position = gl_Vertex.xyz;
// Rotation of the building and movement into position
position.xy = vec2(dot(position.xy, vec2(cr, sr)), dot(position.xy, vec2(-sr, cr)));
position = position + gl_Color.xyz;
gl_Position = gl_ModelViewProjectionMatrix * vec4(position,1.0);
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
// Rotate the normal.
normal = gl_Normal;
normal.xy = vec2(dot(normal.xy, vec2(cr, sr)), dot(normal.xy, vec2(-sr, cr)));
normal = gl_NormalMatrix * normal;
vec4 ambient_color, diffuse_color;
if (colorMode == MODE_DIFFUSE) {
diffuse_color = vec4(1.0,1.0,1.0,1.0);
@ -106,13 +131,13 @@ void main()
diffuse_color = gl_FrontMaterial.diffuse;
ambient_color = gl_FrontMaterial.ambient;
}
// here start computations for the haze layer
// we need several geometrical quantities
// first current altitude of eye position in model space
vec4 ep = gl_ModelViewMatrixInverse * vec4(0.0,0.0,0.0,1.0);
// and relative position to vector
relPos = gl_Vertex.xyz + gl_Color.xyz - ep.xyz;
@ -122,21 +147,21 @@ void main()
// altitude of the vertex in question, somehow zero leads to artefacts, so ensure it is at least 100m
vertex_alt = max(gl_Vertex.z + gl_Color.z,100.0);
scattering = ground_scattering + (1.0 - ground_scattering) * smoothstep(hazeLayerAltitude -100.0, hazeLayerAltitude + 100.0, vertex_alt);
scattering = ground_scattering + (1.0 - ground_scattering) * smoothstep(hazeLayerAltitude -100.0, hazeLayerAltitude + 100.0, vertex_alt);
// branch dependent on daytime
if (terminator < 1000000.0) // the full, sunrise and sunset computation
{
// establish coordinates relative to sun position
vec3 lightFull = (gl_ModelViewMatrixInverse * gl_LightSource[0].position).xyz;
vec3 lightHorizon = normalize(vec3(lightFull.x,lightFull.y, 0.0));
// yprime is the distance of the vertex into sun direction
yprime = -dot(relPos, lightHorizon);
@ -146,14 +171,14 @@ if (terminator < 1000000.0) // the full, sunrise and sunset computation
// two times terminator width governs how quickly light fades into shadow
// now the light-dimming factor
earthShade = 0.6 * (1.0 - smoothstep(-terminator_width+ terminator, terminator_width + terminator, yprime_alt)) + 0.4;
// parametrized version of the Flightgear ground lighting function
lightArg = (terminator-yprime_alt)/100000.0;
// directional scattering for low sun
if (lightArg < 10.0)
{mie_angle = (0.5 * dot(normalize(relPos), normalize(lightFull)) ) + 0.5;}
else
else
{mie_angle = 1.0;}
@ -166,18 +191,18 @@ if (terminator < 1000000.0) // the full, sunrise and sunset computation
light_diffuse = light_diffuse * scattering;
light_ambient.r = light_func(lightArg, 0.236, 0.253, 1.073, 0.572, 0.33);
light_ambient.g = light_ambient.r * 0.4/0.33;
light_ambient.b = light_ambient.r * 0.5/0.33;
light_ambient.g = light_ambient.r * 0.4/0.33;
light_ambient.b = light_ambient.r * 0.5/0.33;
light_ambient.a = 1.0;
// correct ambient light intensity and hue before sunrise
if (earthShade < 0.5)
{
//light_ambient = light_ambient * (0.4 + 0.6 * smoothstep(0.2, 0.5, earthShade));
intensity = length(light_ambient.rgb);
intensity = length(light_ambient.rgb);
light_ambient.rgb = intensity * normalize(mix(light_ambient.rgb, shadedFogColor, 1.0 -smoothstep(0.4, 0.8,earthShade) ));
intensity = length(light_diffuse.rgb);
intensity = length(light_diffuse.rgb);
light_diffuse.rgb = intensity * normalize(mix(light_diffuse.rgb, shadedFogColor, 1.0 -smoothstep(0.4, 0.7,earthShade) ));
}
@ -205,10 +230,10 @@ else
else // the faster, full-day version without lightfields
{
//vertex_alt = max(gl_Vertex.z,100.0);
earthShade = 1.0;
mie_angle = 1.0;
if (terminator > 3000000.0)
{light_diffuse = vec4 (1.0, 1.0, 1.0, 1.0);
light_ambient = vec4 (0.33, 0.4, 0.5, 1.0); }
@ -222,15 +247,15 @@ else // the faster, full-day version without lightfields
light_diffuse.a = 1.0;
light_ambient.r = 0.316 + lightArg * 0.016;
light_ambient.g = light_ambient.r * 0.4/0.33;
light_ambient.g = light_ambient.r * 0.4/0.33;
light_ambient.b = light_ambient.r * 0.5/0.33;
light_ambient.a = 1.0;
}
}
light_diffuse = light_diffuse * scattering;
yprime_alt = -sqrt(2.0 * EarthRadius * hazeLayerAltitude);
}
if (use_IR_vision)
{
light_ambient.rgb = max(light_ambient.rgb, vec3 (0.5, 0.5, 0.5));
@ -250,8 +275,7 @@ if (use_IR_vision)
diffuse_term.a = 1.0;
// Another hack for supporting two-sided lighting without using
// gl_FrontFacing in the fragment shader.
gl_FrontColor.rgb = constant_term.rgb;
gl_BackColor.rgb = constant_term.rgb;
//gl_FrontColor.a = mie_angle; gl_BackColor.a = mie_angle;
gl_FrontColor.rgb = constant_term.rgb;
gl_BackColor.rgb = constant_term.rgb;
//gl_FrontColor.a = mie_angle; gl_BackColor.a = mie_angle;
}

View file

@ -8,10 +8,16 @@
// Diffuse colors come from the gl_Color, ambient from the material. This is
// equivalent to osg::Material::DIFFUSE.
#version 120
#extension GL_EXT_draw_instanced : enable
#define MODE_OFF 0
#define MODE_DIFFUSE 1
#define MODE_AMBIENT_AND_DIFFUSE 2
attribute vec3 instancePosition; // (x,y,z)
attribute vec3 instanceScaleRotate; // (width, depth, height)
attribute vec3 rotPitchTex0x; // (rotation, pitch height, texture x offset)
attribute vec3 tex0yTex1xTex1y; // (texture y offset, texture x gain, texture y gain)
// The constant term of the lighting equation that doesn't depend on
// 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
@ -29,24 +35,42 @@ uniform int colorMode;
void main()
{
// Determine the rotation for the building. The Color alpha value provides rotation information
float sr = sin(6.28 * gl_Color.a);
float cr = cos(6.28 * gl_Color.a);
// Determine the rotation for the building.
float sr = sin(6.28 * rotPitchTex0x.x);
float cr = cos(6.28 * rotPitchTex0x.x);
// Adjust pitch of roof to the correct height.
// The top roof vertices are the only ones that have fractional z values (1.5),
// so we can use this to identify them and scale up any pitched roof vertex to
// the correct pitch (rotPitchTex0x.y * 2.0 because of the fractional z value),
// then scale down by the building height (instanceScaleRotate.z) because
// immediately afterwards we will scale UP the vertex to the correct scale.
vec3 position = gl_Vertex.xyz;
position.z = position.z + fract(position.z) * 2.0 * rotPitchTex0x.y / instanceScaleRotate.z - fract(position.z);
position = position * instanceScaleRotate.xyz;
// Rotation of the building and movement into position
position.xy = vec2(dot(position.xy, vec2(cr, sr)), dot(position.xy, vec2(-sr, cr)));
position = position + gl_Color.xyz;
gl_Position = gl_ModelViewProjectionMatrix * vec4(position,1.0);
//gl_Position = ftransform();
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
position = position + instancePosition.xyz;
gl_Position = gl_ModelViewProjectionMatrix * vec4(position,1.0);
// Texture coordinates are stored as tex0 and tex1 across two attributes.
// tex0 contains the bottom leftmost point, and tex1 contains (w,h).
gl_TexCoord[0].x = sign(gl_MultiTexCoord0.x) * rotPitchTex0x.z + gl_MultiTexCoord0.x * tex0yTex1xTex1y.y;
gl_TexCoord[0].y = tex0yTex1xTex1y.x + gl_MultiTexCoord0.y * tex0yTex1xTex1y.z;
// Rotate the normal.
normal = gl_Normal;
// The roof pieces have a normal of (+/-0.7, 0.0, 0.7)
// If the roof is flat, then we need to change it to (0,0,1).
// First term evaluates for normals without a +z component (all except roof)
// Second term evaluates for roof normals with a pitch
// Third term evaluates for flat roofs
normal = step(0.5, 1.0 - normal.z) * normal + step(0.5, normal.z) * clamp(rotPitchTex0x.y, 0.0, 1.0) * normal + step(0.5, normal.z) * (1.0 - clamp(rotPitchTex0x.y, 0.0, 1.0)) * vec3(0,0,1);
// Rotate the normal as per the building.
normal.xy = vec2(dot(normal.xy, vec2(cr, sr)), dot(normal.xy, vec2(-sr, cr)));
normal = gl_NormalMatrix * normal;
@ -61,7 +85,7 @@ void main()
diffuse_color = gl_FrontMaterial.diffuse;
ambient_color = gl_FrontMaterial.ambient;
}
diffuse_term = diffuse_color * gl_LightSource[0].diffuse;
vec4 constant_term = gl_FrontMaterial.emission + ambient_color *
(gl_LightModel.ambient + gl_LightSource[0].ambient);

View file

@ -3,29 +3,60 @@
// Author: Frederic Bouvier.
//
#version 120
#extension GL_EXT_draw_instanced : enable
attribute vec3 instancePosition; // (x,y,z)
attribute vec3 instanceScaleRotate; // (width, depth, height)
attribute vec3 rotPitchTex0x; // (rotation, pitch height, texture x offset)
attribute vec3 tex0yTex1xTex1y; // (texture y offset, texture x gain, texture y gain)
varying vec3 ecNormal;
varying float alpha;
void main() {
// Determine the rotation for the building. The Color alpha value provides rotation information
float sr = sin(6.28 * gl_Color.a);
float cr = cos(6.28 * gl_Color.a);
vec3 position = gl_Vertex.xyz;
// Rotation of the building and movement into position
position.xy = vec2(dot(position.xy, vec2(cr, sr)), dot(position.xy, vec2(-sr, cr)));
position = position + gl_Color.xyz;
gl_Position = gl_ModelViewProjectionMatrix * vec4(position,1.0);
// Rotate the normal.
ecNormal = gl_Normal;
ecNormal.xy = vec2(dot(ecNormal.xy, vec2(cr, sr)), dot(ecNormal.xy, vec2(-sr, cr)));
ecNormal = gl_NormalMatrix * ecNormal;
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
gl_FrontColor = vec4(1.0, 1.0, 1.0, 1.0);
gl_BackColor = vec4(1.0, 1.0, 1.0, 1.0);
alpha = 1.0;
void main() {
// Determine the rotation for the building.
float sr = sin(6.28 * rotPitchTex0x.x);
float cr = cos(6.28 * rotPitchTex0x.x);
// Adjust pitch of roof to the correct height.
// The top roof vertices are the only ones that have fractional z values (1.5),
// so we can use this to identify them and scale up any pitched roof vertex to
// the correct pitch (rotPitchTex0x.y * 2.0 because of the fractional z value),
// then scale down by the building height (instanceScaleRotate.z) because
// immediately afterwards we will scale UP the vertex to the correct scale.
vec3 position = gl_Vertex.xyz;
position.z = position.z + fract(position.z) * 2.0 * rotPitchTex0x.y / instanceScaleRotate.z - fract(position.z);
position = position * instanceScaleRotate.xyz;
// Rotation of the building and movement into position
position.xy = vec2(dot(position.xy, vec2(cr, sr)), dot(position.xy, vec2(-sr, cr)));
position = position + instancePosition.xyz;
gl_Position = gl_ModelViewProjectionMatrix * vec4(position,1.0);
// Texture coordinates are stored as tex0 and tex1 across two attributes.
// tex0 contains the bottom leftmost point, and tex1 contains (w,h).
gl_TexCoord[0].x = sign(gl_MultiTexCoord0.x) * rotPitchTex0x.z + gl_MultiTexCoord0.x * tex0yTex1xTex1y.y;
gl_TexCoord[0].y = tex0yTex1xTex1y.x + gl_MultiTexCoord0.y * tex0yTex1xTex1y.z;
// Rotate the normal.
ecNormal = gl_Normal;
// The roof pieces have a normal of (+/-0.7, 0.0, 0.7)
// If the roof is flat, then we need to change it to (0,0,1).
// First term evaluates for normals without a +z component (all except roof)
// Second term evaluates for roof normals with a pitch
// Third term evaluates for flat roofs
ecNormal = step(0.5, 1.0 - ecNormal.z) * ecNormal +
step(0.5, ecNormal.z) * clamp(rotPitchTex0x.y, 0.0, 1.0) * ecNormal +
step(0.5, ecNormal.z) * (1.0 - clamp(rotPitchTex0x.y, 0.0, 1.0)) * vec3(0,0,1);
// Rotate the normal as per the building.
ecNormal.xy = vec2(dot(ecNormal.xy, vec2(cr, sr)), dot(ecNormal.xy, vec2(-sr, cr)));
ecNormal = gl_NormalMatrix * ecNormal;
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
gl_FrontColor = vec4(1.0, 1.0, 1.0, 1.0);
gl_BackColor = vec4(1.0, 1.0, 1.0, 1.0);
alpha = 1.0;
}

View file

@ -3,6 +3,11 @@
// © Emilian Huminiuc and Vivian Meazza 2011
#version 120
attribute vec3 instancePosition; // (x,y,z)
attribute vec3 instanceScaleRotate; // (width, depth, height)
attribute vec3 rotPitchTex0x; // (rotation, pitch height, texture x offset)
attribute vec3 tex0yTex1xTex1y; // (texture y offset, texture x gain, texture y gain)
varying vec3 rawpos;
varying vec3 VNormal;
varying vec3 VTangent;
@ -48,83 +53,105 @@ void rotationMatrixH(in float sinRz, in float cosRz, out mat4 rotmat)
void main(void)
{
float sr = sin(6.28 * gl_Color.a);
float cr = cos(6.28 * gl_Color.a);
rawpos = gl_Vertex.xyz;
// Rotation of the object and movement into position
rawpos.xy = vec2(dot(rawpos.xy, vec2(cr, sr)), dot(rawpos.xy, vec2(-sr, cr)));
rawpos = rawpos + gl_Color.xyz;
vec4 ecPosition = gl_ModelViewMatrix * vec4(rawpos.x, rawpos.y, rawpos.z, 1.0);
//fog_Func(fogType);
// Determine the rotation for the building.
float sr = sin(6.28 * rotPitchTex0x.x);
float cr = cos(6.28 * rotPitchTex0x.x);
// Rotate the normal.
vec3 normal = gl_Normal;
normal.xy = vec2(dot(normal.xy, vec2(cr, sr)), dot(normal.xy, vec2(-sr, cr)));
//normal = gl_NormalMatrix * normal;
// Adjust pitch of roof to the correct height.
// The top roof vertices are the only ones that have fractional z values (1.5),
// so we can use this to identify them and scale up any pitched roof vertex to
// the correct pitch (rotPitchTex0x.y * 2.0 because of the fractional z value),
// then scale down by the building height (instanceScaleRotate.z) because
// immediately afterwards we will scale UP the vertex to the correct scale.
rawpos = gl_Vertex.xyz;
rawpos.z = rawpos.z + fract(rawpos.z) * 2.0 * rotPitchTex0x.y / instanceScaleRotate.z - fract(rawpos.z);
rawpos = rawpos * instanceScaleRotate.xyz;
VNormal = normalize(gl_NormalMatrix * normal);
vec3 n = normalize(normal);
vec3 tempTangent = cross(n, vec3(1.0,0.0,0.0));
vec3 tempBinormal = cross(n, tempTangent);
// Rotation of the building and movement into rawpos
rawpos.xy = vec2(dot(rawpos.xy, vec2(cr, sr)), dot(rawpos.xy, vec2(-sr, cr)));
rawpos = rawpos + instancePosition.xyz;
vec4 ecPosition = gl_ModelViewMatrix * vec4(rawpos, 1.0);
if (nmap_enabled > 0){
tempTangent = tangent;
tempBinormal = binormal;
}
// Texture coordinates are stored as tex0 and tex1 across two attributes.
// tex0 contains the bottom leftmost point, and tex1 contains (w,h).
gl_TexCoord[0].x = sign(gl_MultiTexCoord0.x) * rotPitchTex0x.z + gl_MultiTexCoord0.x * tex0yTex1xTex1y.y;
gl_TexCoord[0].y = tex0yTex1xTex1y.x + gl_MultiTexCoord0.y * tex0yTex1xTex1y.z;
VTangent = normalize(gl_NormalMatrix * tempTangent);
VBinormal = normalize(gl_NormalMatrix * tempBinormal);
vec3 t = tempTangent;
vec3 b = tempBinormal;
// Rotate the normal.
vec3 normal = gl_Normal;
// Super hack: if diffuse material alpha is less than 1, assume a
// transparency animation is at work
if (gl_FrontMaterial.diffuse.a < 1.0)
alpha = gl_FrontMaterial.diffuse.a;
else
alpha = 1.0;
// The roof pieces have a normal of (+/-0.7, 0.0, 0.7)
// If the roof is flat, then we need to change it to (0,0,1).
// First term evaluates for normals without a +z component (all except roof)
// Second term evaluates for roof normals with a pitch
// Third term evaluates for flat roofs
normal = step(0.5, 1.0 - normal.z) * normal +
step(0.5, normal.z) * clamp(rotPitchTex0x.y, 0.0, 1.0) * normal +
step(0.5, normal.z) * (1.0 - clamp(rotPitchTex0x.y, 0.0, 1.0)) * vec3(0,0,1);
// Vertex in eye coordinates
vertVec = ecPosition.xyz;
vViewVec.x = dot(t, vertVec);
vViewVec.y = dot(b, vertVec);
vViewVec.z = dot(n, vertVec);
// Rotate the normal as per the building.
normal.xy = vec2(dot(normal.xy, vec2(cr, sr)), dot(normal.xy, vec2(-sr, cr)));
// calculate the reflection vector
vec4 reflect_eye = vec4(reflect(vertVec, VNormal), 0.0);
vec3 reflVec_stat = normalize(gl_ModelViewMatrixInverse * reflect_eye).xyz;
if (refl_dynamic > 0){
//prepare rotation matrix
mat4 RotMatPR;
mat4 RotMatH;
float _roll = roll;
if (_roll>90.0 || _roll < -90.0)
{
_roll = -_roll;
}
float cosRx = cos(radians(_roll));
float sinRx = sin(radians(_roll));
float cosRy = cos(radians(-pitch));
float sinRy = sin(radians(-pitch));
float cosRz = cos(radians(hdg));
float sinRz = sin(radians(hdg));
rotationMatrixPR(sinRx, cosRx, sinRy, cosRy, RotMatPR);
rotationMatrixH(sinRz, cosRz, RotMatH);
vec3 reflVec_dyn = (RotMatH * (RotMatPR * normalize(gl_ModelViewMatrixInverse * reflect_eye))).xyz;
VNormal = normalize(gl_NormalMatrix * normal);
vec3 n = normalize(normal);
vec3 tempTangent = cross(n, vec3(1.0,0.0,0.0));
vec3 tempBinormal = cross(n, tempTangent);
reflVec = reflVec_dyn;
} else {
reflVec = reflVec_stat;
if (nmap_enabled > 0){
tempTangent = tangent;
tempBinormal = binormal;
}
VTangent = normalize(gl_NormalMatrix * tempTangent);
VBinormal = normalize(gl_NormalMatrix * tempBinormal);
vec3 t = tempTangent;
vec3 b = tempBinormal;
// Super hack: if diffuse material alpha is less than 1, assume a
// transparency animation is at work
if (gl_FrontMaterial.diffuse.a < 1.0)
alpha = gl_FrontMaterial.diffuse.a;
else
alpha = 1.0;
// Vertex in eye coordinates
vertVec = ecPosition.xyz;
vViewVec.x = dot(t, vertVec);
vViewVec.y = dot(b, vertVec);
vViewVec.z = dot(n, vertVec);
// calculate the reflection vector
vec4 reflect_eye = vec4(reflect(vertVec, VNormal), 0.0);
vec3 reflVec_stat = normalize(gl_ModelViewMatrixInverse * reflect_eye).xyz;
if (refl_dynamic > 0){
//prepare rotation matrix
mat4 RotMatPR;
mat4 RotMatH;
float _roll = roll;
if (_roll>90.0 || _roll < -90.0)
{
_roll = -_roll;
}
float cosRx = cos(radians(_roll));
float sinRx = sin(radians(_roll));
float cosRy = cos(radians(-pitch));
float sinRy = sin(radians(-pitch));
float cosRz = cos(radians(hdg));
float sinRz = sin(radians(hdg));
rotationMatrixPR(sinRx, cosRx, sinRy, cosRy, RotMatPR);
rotationMatrixH(sinRz, cosRz, RotMatH);
vec3 reflVec_dyn = (RotMatH * (RotMatPR * normalize(gl_ModelViewMatrixInverse * reflect_eye))).xyz;
if(rembrandt_enabled < 1){
gl_FrontColor = gl_FrontMaterial.emission + vec4(1.0,1.0,1.0,1.0)
* (gl_LightModel.ambient + gl_LightSource[0].ambient);
} else {
gl_FrontColor = vec4(1.0,1.0,1.0,1.0);
}
gl_Position = gl_ModelViewProjectionMatrix * vec4(rawpos,1.0);
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
reflVec = reflVec_dyn;
} else {
reflVec = reflVec_stat;
}
if(rembrandt_enabled < 1){
gl_FrontColor = gl_FrontMaterial.emission + vec4(1.0,1.0,1.0,1.0)
* (gl_LightModel.ambient + gl_LightSource[0].ambient);
} else {
gl_FrontColor = vec4(1.0,1.0,1.0,1.0);
}
gl_Position = gl_ModelViewProjectionMatrix * vec4(rawpos,1.0);
}

View file

@ -3,53 +3,77 @@
// Licence: GPL v2
// © Emilian Huminiuc and Vivian Meazza 2011
#version 120
#extension GL_EXT_draw_instanced : enable
varying vec4 diffuseColor;
varying vec3 VBinormal;
varying vec3 VNormal;
varying vec3 VTangent;
varying vec3 rawpos;
varying vec3 eyeVec;
varying vec3 normal;
uniform int refl_dynamic;
uniform int nmap_enabled;
uniform int shader_qual;
uniform int rembrandt_enabled;
attribute vec3 instancePosition; // (x,y,z)
attribute vec3 instanceScaleRotate; // (width, depth, height)
attribute vec3 rotPitchTex0x; // (rotation, pitch height, texture x offset)
attribute vec3 tex0yTex1xTex1y; // (texture y offset, texture x gain, texture y gain)
void main(void)
{
float sr = sin(6.28 * gl_Color.a);
float cr = cos(6.28 * gl_Color.a);
rawpos = gl_Vertex.xyz;
// Rotation of the object and movement into position
rawpos.xy = vec2(dot(rawpos.xy, vec2(cr, sr)), dot(rawpos.xy, vec2(-sr, cr)));
rawpos = rawpos + gl_Color.xyz;
vec4 ecPosition = gl_ModelViewMatrix * vec4(rawpos.xyz, 1.0);
// Determine the rotation for the building.
float sr = sin(6.28 * rotPitchTex0x.x);
float cr = cos(6.28 * rotPitchTex0x.x);
// Adjust pitch of roof to the correct height.
// The top roof vertices are the only ones that have fractional z values (1.5),
// so we can use this to identify them and scale up any pitched roof vertex to
// the correct pitch (rotPitchTex0x.y * 2.0 because of the fractional z value),
// then scale down by the building height (instanceScaleRotate.z) because
// immediately afterwards we will scale UP the vertex to the correct scale.
vec3 position = gl_Vertex.xyz;
position.z = position.z + fract(position.z) * 2.0 * rotPitchTex0x.y / instanceScaleRotate.z - fract(position.z);
position = position * instanceScaleRotate.xyz;
// Rotation of the building and movement into position
position.xy = vec2(dot(position.xy, vec2(cr, sr)), dot(position.xy, vec2(-sr, cr)));
position = position + instancePosition.xyz;
gl_Position = gl_ModelViewProjectionMatrix * vec4(position,1.0);
vec4 ecPosition = gl_ModelViewMatrix * vec4(position, 1.0);
eyeVec = ecPosition.xyz;
// Rotate the normal.
vec3 normal = gl_Normal;
normal.xy = vec2(dot(normal.xy, vec2(cr, sr)), dot(normal.xy, vec2(-sr, cr)));
// Rotate the normal.
normal = gl_Normal;
VNormal = normalize(gl_NormalMatrix * normal);
vec3 n = normalize(normal);
vec3 c1 = cross(n, vec3(0.0,0.0,1.0));
vec3 c2 = cross(n, vec3(0.0,1.0,0.0));
// The roof pieces have a normal of (+/-0.7, 0.0, 0.7)
// If the roof is flat, then we need to change it to (0,0,1).
// First term evaluates for normals without a +z component (all except roof)
// Second term evaluates for roof normals with a pitch
// Third term evaluates for flat roofs
normal = step(0.5, 1.0 - normal.z) * normal + step(0.5, normal.z) * clamp(rotPitchTex0x.y, 0.0, 1.0) * normal + step(0.5, normal.z) * (1.0 - clamp(rotPitchTex0x.y, 0.0, 1.0)) * vec3(0,0,1);
VTangent = c1;
if(length(c2)>length(c1)){
VTangent = c2;
}
// Rotate the normal as per the building.
normal.xy = vec2(dot(normal.xy, vec2(cr, sr)), dot(normal.xy, vec2(-sr, cr)));
vec3 n = normalize(normal);
VBinormal = cross(n, VTangent);
vec3 c1 = cross(n, vec3(0.0,0.0,1.0));
vec3 c2 = cross(n, vec3(0.0,1.0,0.0));
VNormal = normalize(gl_NormalMatrix * normal);
VTangent = normalize(gl_NormalMatrix * -VTangent);
VBinormal = normalize(gl_NormalMatrix * VBinormal);
VTangent = c1;
if(length(c2)>length(c1)){
VTangent = c2;
}
VBinormal = cross(n, VTangent);
VTangent = normalize(gl_NormalMatrix * -VTangent);
VBinormal = normalize(gl_NormalMatrix * VBinormal);
// Force no alpha on random buildings
diffuseColor = vec4(gl_FrontMaterial.diffuse.rgb,1.0);
@ -60,7 +84,10 @@ void main(void)
} else {
gl_FrontColor = vec4(1.0);
}
gl_Position = gl_ModelViewProjectionMatrix * vec4(rawpos,1.0);
gl_ClipVertex = ecPosition;
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
// Texture coordinates are stored as tex0 and tex1 across two attributes.
// tex0 contains the bottom leftmost point, and tex1 contains (w,h).
gl_TexCoord[0].x = sign(gl_MultiTexCoord0.x) * rotPitchTex0x.z + gl_MultiTexCoord0.x * tex0yTex1xTex1y.y;
gl_TexCoord[0].y = tex0yTex1xTex1y.x + gl_MultiTexCoord0.y * tex0yTex1xTex1y.z;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 702 KiB

After

Width:  |  Height:  |  Size: 876 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 722 KiB

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 381 KiB

After

Width:  |  Height:  |  Size: 323 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 MiB

After

Width:  |  Height:  |  Size: 2.4 MiB