4784a929d7
Replace random buildings with one using proper instancing. Also implement more control over rendering of random buildings. see README.scenery for details.
93 lines
3.5 KiB
GLSL
93 lines
3.5 KiB
GLSL
// -*- mode: C; -*-
|
|
// RANDOM BUILDINGS for the UBERSHADER vertex shader
|
|
// 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 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)
|
|
{
|
|
// 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.
|
|
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)));
|
|
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));
|
|
VNormal = normalize(gl_NormalMatrix * normal);
|
|
|
|
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);
|
|
|
|
if(rembrandt_enabled < 1){
|
|
gl_FrontColor = gl_FrontMaterial.emission + vec4(1.0)
|
|
* (gl_LightModel.ambient + gl_LightSource[0].ambient);
|
|
} else {
|
|
gl_FrontColor = vec4(1.0);
|
|
}
|
|
gl_ClipVertex = ecPosition;
|
|
|
|
// 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;
|
|
}
|