GLuint cloudVAO;
GLuint cloudVertBuffer;
GLuint cloudTransBuffer;
vector<float> cloudTrans;
vector<glm::vec3> cloudVerts;
float cloudHeight = 250;
void renderClouds(Perlin cloudPerlin)
{
cloudVerts.empty();
cloudTrans.empty();
for(float x = 0; x < 1024; x++)
{
for(float y = 0; y<1024; y++)
{
float perlin = cloudPerlin.Get(x/1024.0f,y/1024.0f);
perlin++;
perlin/=2.0f;
//log(istr(x) + " " + istr(y) + " " + fstr(perlin));
/*glm::vec3 tmp(x,y,100);
cloudVerts.push_back(tmp);*/
glm::vec3 temp1(x,cloudHeight,y);
glm::vec3 temp2(x,cloudHeight,y+1);
glm::vec3 temp3(x+1,cloudHeight,y);
glm::vec3 temp4(x+1,cloudHeight,y+1);
glm::vec3 temp5(x+1,cloudHeight,y);
glm::vec3 temp6(x,cloudHeight,y+1);
cloudVerts.push_back(temp1);
cloudVerts.push_back(temp2);
cloudVerts.push_back(temp3);
cloudVerts.push_back(temp4);
cloudVerts.push_back(temp5);
cloudVerts.push_back(temp6);
cloudTrans.push_back(perlin);
cloudTrans.push_back(perlin);
cloudTrans.push_back(perlin);
cloudTrans.push_back(perlin);
cloudTrans.push_back(perlin);
cloudTrans.push_back(perlin);
}
}
glGenVertexArrays(1,&cloudVAO);
glBindVertexArray(cloudVAO);
glGenBuffers(1, &cloudVertBuffer);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, cloudVertBuffer);
glBufferData(GL_ARRAY_BUFFER, cloudVerts.size() * sizeof(glm::vec3), &cloudVerts[0], GL_STATIC_DRAW);
glVertexAttribPointer(
0, // attribute
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
glGenBuffers(1, &cloudTransBuffer);
glEnableVertexAttribArray(6);
glBindBuffer(GL_ARRAY_BUFFER, cloudTransBuffer);
glBufferData(GL_ARRAY_BUFFER, cloudTrans.size() * sizeof(float), &cloudTrans[0], GL_STATIC_DRAW);
glVertexAttribPointer(
6, // attribute
1, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
}
GLuint cloudID;
void displayClouds()
{
glDisable(GL_CULL_FACE);
transform(0,0,0);
glUniform1i(cloudID,1);
glBindVertexArray(cloudVAO);
glDrawArrays(GL_TRIANGLES, 0, cloudVerts.size() );
glUniform1i(cloudID,0);
glEnable(GL_CULL_FACE);
}
Fragment shader:#version 330 core
// Interpolated values from the vertex shaders
in vec2 UV;
in vec3 Position_worldspace;
in vec3 Normal_cameraspace;
in vec3 EyeDirection_cameraspace;
in vec3 ambientColor;
in vec3 diffuseColor;
in vec3 specularColor;
in float cloudTrans;
in vec3 Light0Direction_cameraspace;
in vec3 Light1Direction_cameraspace;
in vec3 Light2Direction_cameraspace;
in vec3 Light3Direction_cameraspace;
in vec3 Light4Direction_cameraspace;
in vec3 Light5Direction_cameraspace;
in vec3 Light6Direction_cameraspace;
in vec3 Light7Direction_cameraspace;
// Ouput data
out vec4 color;
// Values that stay constant for the whole mesh.
uniform sampler2D myTextureSampler;
uniform mat4 MV;
uniform int textured;
uniform int terrain;
uniform vec3 worldAmbient;
uniform int cloud;
uniform vec3 Light0_Position;
uniform vec3 Light1_Position;
uniform vec3 Light2_Position;
uniform vec3 Light3_Position;
uniform vec3 Light4_Position;
uniform vec3 Light5_Position;
uniform vec3 Light6_Position;
uniform vec3 Light7_Position;
uniform vec3 Light0_Color;
uniform vec3 Light1_Color;
uniform vec3 Light2_Color;
uniform vec3 Light3_Color;
uniform vec3 Light4_Color;
uniform vec3 Light5_Color;
uniform vec3 Light6_Color;
uniform vec3 Light7_Color;
uniform float Light0_Power;
uniform float Light1_Power;
uniform float Light2_Power;
uniform float Light3_Power;
uniform float Light4_Power;
uniform float Light5_Power;
uniform float Light6_Power;
uniform float Light7_Power;
uniform vec3 sunColor;
uniform vec3 sunPos;
in vec3 sunDirection_cameraspace;
void main()
{
// Material properties
vec3 MaterialDiffuseColor = diffuseColor;
vec3 MaterialAmbientColor = ambientColor;
vec3 MaterialSpecularColor = specularColor;
if(cloud == 1)
{
color = vec4(1,1,1,cloudTrans);
}
else
{
if(terrain == 1)
{
MaterialAmbientColor = texture2D( myTextureSampler, UV ).rgb * worldAmbient;
MaterialDiffuseColor = MaterialAmbientColor;
MaterialSpecularColor = vec3(0,0,0);
}
else
{
if(textured == 1)
{
MaterialAmbientColor = texture2D( myTextureSampler, UV ).rgb * worldAmbient;
MaterialDiffuseColor = diffuseColor * texture2D( myTextureSampler, UV ).rgb;
MaterialSpecularColor = specularColor;
}
else
{
//blender wasn't exporting ambient colors, so we're using diffuse for now
MaterialAmbientColor = MaterialDiffuseColor * worldAmbient;
}
}
float distance0 = length( Light0_Position - Position_worldspace );
float distance1 = length( Light1_Position - Position_worldspace );
float distance2 = length( Light2_Position - Position_worldspace );
float distance3 = length( Light3_Position - Position_worldspace );
float distance4 = length( Light4_Position - Position_worldspace );
float distance5 = length( Light5_Position - Position_worldspace );
float distance6 = length( Light6_Position - Position_worldspace );
float distance7 = length( Light7_Position - Position_worldspace );
vec3 n = normalize( Normal_cameraspace );
vec3 E = normalize(EyeDirection_cameraspace);
vec3 l0 = normalize( Light0Direction_cameraspace );
float cosTheta0 = clamp( dot( n,l0 ), 0,1 );
vec3 l1 = normalize( Light1Direction_cameraspace );
float cosTheta1 = clamp( dot( n,l1 ), 0,1 );
vec3 l2 = normalize( Light2Direction_cameraspace );
float cosTheta2 = clamp( dot( n,l2 ), 0,1 );
vec3 l3 = normalize( Light3Direction_cameraspace );
float cosTheta3 = clamp( dot( n,l3 ), 0,1 );
vec3 l4 = normalize( Light4Direction_cameraspace );
float cosTheta4 = clamp( dot( n,l4 ), 0,1 );
vec3 l5 = normalize( Light5Direction_cameraspace );
float cosTheta5 = clamp( dot( n,l5 ), 0,1 );
vec3 l6 = normalize( Light6Direction_cameraspace );
float cosTheta6 = clamp( dot( n,l6 ), 0,1 );
vec3 l7 = normalize( Light7Direction_cameraspace );
float cosTheta7 = clamp( dot( n,l7 ), 0,1 );
vec3 lS = normalize( sunDirection_cameraspace );
float cosThetaS = clamp( dot( n,lS ), 0,1 );
vec3 R0 = reflect(-l0,n);
float cosAlpha0 = clamp( dot( E,R0 ), 0,1 );
vec3 R1 = reflect(-l1,n);
float cosAlpha1 = clamp( dot( E,R1 ), 0,1 );
vec3 R2 = reflect(-l2,n);
float cosAlpha2 = clamp( dot( E,R2 ), 0,1 );
vec3 R3 = reflect(-l3,n);
float cosAlpha3 = clamp( dot( E,R3 ), 0,1 );
vec3 R4 = reflect(-l4,n);
float cosAlpha4 = clamp( dot( E,R4 ), 0,1 );
vec3 R5 = reflect(-l5,n);
float cosAlpha5 = clamp( dot( E,R5 ), 0,1 );
vec3 R6 = reflect(-l6,n);
float cosAlpha6 = clamp( dot( E,R6 ), 0,1 );
vec3 R7 = reflect(-l7,n);
float cosAlpha7 = clamp( dot( E,R7 ), 0,1 );
vec3 colorPower0 = Light0_Color * Light0_Power;
vec3 colorPower1 = Light1_Color * Light1_Power;
vec3 colorPower2 = Light2_Color * Light2_Power;
vec3 colorPower3 = Light3_Color * Light3_Power;
vec3 colorPower4 = Light4_Color * Light4_Power;
vec3 colorPower5 = Light5_Color * Light5_Power;
vec3 colorPower6 = Light6_Color * Light6_Power;
vec3 colorPower7 = Light7_Color * Light7_Power;
vec3 MaterialDiffuseColor0 = colorPower0 * cosTheta0 / (distance0*distance0);
vec3 MaterialSpecularColor0 = Light0_Color * Light0_Power * pow(cosAlpha0,5) / (distance0*distance0);
vec3 MaterialDiffuseColor1 = colorPower1 * cosTheta1 / (distance1*distance1);
vec3 MaterialSpecularColor1 = Light1_Color * Light1_Power * pow(cosAlpha1,5) / (distance1*distance1);
vec3 MaterialDiffuseColor2 = colorPower2 * cosTheta2 / (distance2*distance2);
vec3 MaterialSpecularColor2 = Light2_Color * Light2_Power * pow(cosAlpha2,5) / (distance2*distance2);
vec3 MaterialDiffuseColor3 = colorPower3 * cosTheta3 / (distance3*distance3);
vec3 MaterialSpecularColor3 = Light3_Color * Light3_Power * pow(cosAlpha3,5) / (distance3*distance3);
vec3 MaterialDiffuseColor4 = colorPower4 * cosTheta4 / (distance4*distance4);
vec3 MaterialSpecularColor4 = Light4_Color * Light4_Power * pow(cosAlpha4,5) / (distance4*distance4);
vec3 MaterialDiffuseColor5 = colorPower5 * cosTheta5 / (distance5*distance5);
vec3 MaterialSpecularColor5 = Light5_Color * Light5_Power * pow(cosAlpha5,5) / (distance5*distance5);
vec3 MaterialDiffuseColor6 = colorPower6 * cosTheta6 / (distance6*distance6);
vec3 MaterialSpecularColor6 = Light6_Color * Light6_Power * pow(cosAlpha6,5) / (distance6*distance6);
vec3 MaterialDiffuseColor7 = colorPower7 * cosTheta7 / (distance7*distance7);
vec3 MaterialSpecularColor7 = Light7_Color * Light7_Power * pow(cosAlpha7,5) / (distance7*distance7);
vec3 tmpcolor = MaterialAmbientColor;
tmpcolor += MaterialDiffuseColor * sunColor * cosThetaS;
tmpcolor += (MaterialDiffuseColor * MaterialDiffuseColor0) + (MaterialSpecularColor * MaterialSpecularColor0);
tmpcolor += (MaterialDiffuseColor * MaterialDiffuseColor1) + (MaterialSpecularColor * MaterialSpecularColor1);
tmpcolor += (MaterialDiffuseColor * MaterialDiffuseColor2) + (MaterialSpecularColor * MaterialSpecularColor2);
tmpcolor += (MaterialDiffuseColor * MaterialDiffuseColor3) + (MaterialSpecularColor * MaterialSpecularColor3);
tmpcolor += (MaterialDiffuseColor * MaterialDiffuseColor4) + (MaterialSpecularColor * MaterialSpecularColor4);
tmpcolor += (MaterialDiffuseColor * MaterialDiffuseColor5) + (MaterialSpecularColor * MaterialSpecularColor5);
tmpcolor += (MaterialDiffuseColor * MaterialDiffuseColor6) + (MaterialSpecularColor * MaterialSpecularColor6);
tmpcolor += (MaterialDiffuseColor * MaterialDiffuseColor7) + (MaterialSpecularColor * MaterialSpecularColor7);
color = vec4(tmpcolor,1);
}
}
There's a vertex shader too, but it's not relevant.Clouds from below.
Clouds from above.
Problems:
1. They end abruptly.
2. The clouds end up being over 2 million faces and bring the fps down to almost 1.
So, how do I do decent dynamic (moving/changeable) clouds in opengl 4?