Made an attempt at getting a smooth gradient of the flame color.

This commit is contained in:
Faerbit 2015-03-08 13:52:17 +01:00
parent a1fb876880
commit 43aae3e8ec
5 changed files with 67 additions and 11 deletions

View File

@ -1,15 +1,40 @@
#version 150 #version 150
in vec3 fColor; in GS_OUT {
float maxAngle;
vec3 position;
}fs_in;
in vec4 flameCenter;
out vec4 oColor; out vec4 oColor;
uniform bool withColor; uniform bool withColor;
uniform vec3 camera;
vec3 colorFunction(float quotient) {
if (quotient < 0.2){
return vec3(1.0, 0.0, 0.0);
}
else {
return vec3(0.0, 1.0, 0.0);
}
}
void main() { void main() {
vec2 cameraXZ = vec2(camera.x, camera.z);
vec3 cameraVector = vec3(flameCenter) - camera;
vec2 cameraVectorXZ = normalize(vec2(cameraVector.x, cameraVector.z));
vec2 rightAngleVector;
if (cameraVectorXZ.y == 0.0) {
rightAngleVector = vec2(0.0, 1.0);
}
else {
rightAngleVector = normalize(vec2(1.0, -cameraVectorXZ.x/cameraVectorXZ.y));
}
float angle = acos(dot(cameraVectorXZ, normalize(vec2(fs_in.position.x, fs_in.position.z)-cameraXZ)));
if (withColor) { if (withColor) {
oColor = vec4(fColor, 0.6); oColor = vec4(colorFunction(angle/fs_in.maxAngle), 0.6);
} }
else { else {
oColor = vec4(0.0, 0.0, 0.0, 0.0); oColor = vec4(0.0, 0.0, 0.0, 0.0);

View File

@ -1,15 +1,22 @@
#version 150 #version 150
uniform mat4 modelViewProjectionMatrix; uniform mat4 modelViewProjectionMatrix;
uniform mat4 viewProjectionMatrix;
uniform float time; uniform float time;
uniform bool bottom; uniform bool bottom;
uniform bool left; uniform bool left;
uniform vec3 camera;
layout(points) in; layout(points) in;
layout(triangle_strip, max_vertices = 146) out; layout(triangle_strip, max_vertices = 85) out;
out GS_OUT {
float maxAngle;
vec3 position;
}gs_out;
in vec3 Color[]; in vec3 Color[];
out vec3 fColor; out vec4 flameCenter;
const float PI = 3.1415926; const float PI = 3.1415926;
const float transition_point_1 = 1.178097; const float transition_point_1 = 1.178097;
@ -29,9 +36,11 @@ const float begin_2 = 0;
const float end_2 = 3; const float end_2 = 3;
float flickerFunction() { float flickerFunction() {
return pow(0.6*sin(20.0*time), 2) + 0.4; //return pow(0.6*sin(20.0*time), 2) + 0.4;
return 1.0;
} }
float radiusFunction(float x) { float radiusFunction(float x) {
float value_1 = 0.0; float value_1 = 0.0;
float value_2 = 0.0; float value_2 = 0.0;
@ -51,7 +60,18 @@ float radiusFunction(float x) {
} }
void main() { void main() {
fColor = Color[0]; flameCenter = gl_in[0].gl_Position;
vec3 color = Color[0];
vec2 cameraXZ = vec2(camera.x, camera.z);
vec3 cameraVector = vec3(flameCenter) - camera;
vec2 cameraVectorXZ = normalize(vec2(cameraVector.x, cameraVector.z));
vec2 rightAngleVector;
if (cameraVectorXZ.y == 0.0) {
rightAngleVector = vec2(0.0, 1.0);
}
else {
rightAngleVector = normalize(vec2(1.0, -cameraVectorXZ.x/cameraVectorXZ.y));
}
float resolution = 8.0; float resolution = 8.0;
float this_begin = mix(begin_1, begin_2, flickerFunction()); float this_begin = mix(begin_1, begin_2, flickerFunction());
@ -70,6 +90,8 @@ void main() {
for (i; i<render_end; i+=step) { for (i; i<render_end; i+=step) {
float downRadius = radiusFunction(i); float downRadius = radiusFunction(i);
float upRadius = radiusFunction(i+step); float upRadius = radiusFunction(i+step);
float maxUpAngle = acos(dot(cameraVectorXZ, normalize((vec2(gl_in[0].gl_Position.x, gl_in[0].gl_Position.z) + rightAngleVector * upRadius) - cameraXZ)));
float maxDownAngle = acos(dot(cameraVectorXZ, normalize((vec2(gl_in[0].gl_Position.x, gl_in[0].gl_Position.z) + rightAngleVector * downRadius) - cameraXZ)));
float circle_end = 0.0; float circle_end = 0.0;
int j = 0; int j = 0;
if (left) { if (left) {
@ -85,18 +107,26 @@ void main() {
float rightAngle = PI * 2.0 / resolution * (j+1); float rightAngle = PI * 2.0 / resolution * (j+1);
vec4 offset = vec4(cos(rightAngle) * downRadius, i, -sin(rightAngle) * downRadius, 0.0); vec4 offset = vec4(cos(rightAngle) * downRadius, i, -sin(rightAngle) * downRadius, 0.0);
gs_out.position = vec3(gl_in[0].gl_Position + offset);
gs_out.maxAngle = maxDownAngle;
gl_Position = gl_in[0].gl_Position + modelViewProjectionMatrix * offset; gl_Position = gl_in[0].gl_Position + modelViewProjectionMatrix * offset;
EmitVertex(); EmitVertex();
offset = vec4(cos(rightAngle) * upRadius, i + step, -sin(rightAngle) * upRadius, 0.0); offset = vec4(cos(rightAngle) * upRadius, i + step, -sin(rightAngle) * upRadius, 0.0);
gs_out.position = vec3(gl_in[0].gl_Position + offset);
gs_out.maxAngle = maxUpAngle;
gl_Position = gl_in[0].gl_Position + modelViewProjectionMatrix * offset; gl_Position = gl_in[0].gl_Position + modelViewProjectionMatrix * offset;
EmitVertex(); EmitVertex();
offset = vec4(cos(leftAngle) * downRadius, i, -sin(leftAngle) * downRadius, 0.0); offset = vec4(cos(leftAngle) * downRadius, i, -sin(leftAngle) * downRadius, 0.0);
gs_out.position = vec3(gl_in[0].gl_Position + offset);
gs_out.maxAngle = maxDownAngle;
gl_Position = gl_in[0].gl_Position + modelViewProjectionMatrix * offset; gl_Position = gl_in[0].gl_Position + modelViewProjectionMatrix * offset;
EmitVertex(); EmitVertex();
offset = vec4(cos(leftAngle) * upRadius, i + step, -sin(leftAngle) * upRadius, 0.0); offset = vec4(cos(leftAngle) * upRadius, i + step, -sin(leftAngle) * upRadius, 0.0);
gs_out.position = vec3(gl_in[0].gl_Position + offset);
gs_out.maxAngle = maxUpAngle;
gl_Position = gl_in[0].gl_Position + modelViewProjectionMatrix * offset; gl_Position = gl_in[0].gl_Position + modelViewProjectionMatrix * offset;
EmitVertex(); EmitVertex();

View File

@ -24,7 +24,7 @@ Flame::Flame() {
} }
void Flame::render(SharedShaderProgram shader, glm::mat4 viewProjectionMatrix, float time, void Flame::render(SharedShaderProgram shader, glm::mat4 viewProjectionMatrix, float time,
bool withColor, glm::vec2 skewing) { bool withColor, glm::vec2 skewing, glm::vec3 camera) {
glm::mat4 modelMatrix; glm::mat4 modelMatrix;
// matrix is column major // matrix is column major
glm::mat4 skewMatrixX = glm::mat4 skewMatrixX =
@ -41,12 +41,13 @@ void Flame::render(SharedShaderProgram shader, glm::mat4 viewProjectionMatrix, f
modelMatrix = skewMatrixX * skewMatrixZ * glm::scale<float>(size * glm::vec3(1.1f)); modelMatrix = skewMatrixX * skewMatrixZ * glm::scale<float>(size * glm::vec3(1.1f));
} }
else { else {
modelMatrix = skewMatrixX * skewMatrixZ * glm::scale<float>(size); modelMatrix = skewMatrixX * skewMatrixZ * glm::scale<float>(size * glm::vec3(10.0f));
} }
glm::mat4 modelViewProjectionMatrix = viewProjectionMatrix * modelMatrix; glm::mat4 modelViewProjectionMatrix = viewProjectionMatrix * modelMatrix;
shader->setUniform("modelViewProjectionMatrix", modelViewProjectionMatrix); shader->setUniform("modelViewProjectionMatrix", modelViewProjectionMatrix);
shader->setUniform("viewProjectionMatrix", viewProjectionMatrix); shader->setUniform("viewProjectionMatrix", viewProjectionMatrix);
shader->setUniform("withColor", withColor); shader->setUniform("withColor", withColor);
shader->setUniform("camera", camera);
shader->setUniform("time", time); shader->setUniform("time", time);
shader->setUniform("bottom", true); shader->setUniform("bottom", true);
shader->setUniform("left", true); shader->setUniform("left", true);

View File

@ -9,7 +9,7 @@ class Flame : public Entity {
Flame(glm::vec3 position, glm::vec3 color, glm::vec3 size); Flame(glm::vec3 position, glm::vec3 color, glm::vec3 size);
Flame(); Flame();
void render(SharedShaderProgram shader, glm::mat4 viewProjectionMatrix, void render(SharedShaderProgram shader, glm::mat4 viewProjectionMatrix,
float time, bool withColor, glm::vec2 skewing); float time, bool withColor, glm::vec2 skewing, glm::vec3 camera);
private: private:
glm::vec3 color; glm::vec3 color;
glm::vec3 size; glm::vec3 size;

View File

@ -352,7 +352,7 @@ void Graphics::render(double time)
// draw with colors // draw with colors
for(unsigned int i = 0; i<closestFlames.size(); i++) { for(unsigned int i = 0; i<closestFlames.size(); i++) {
closestFlames.at(i)->render(flameShader, lightingViewProjectionMatrix, float(time), true, wind); closestFlames.at(i)->render(flameShader, lightingViewProjectionMatrix, float(time), true, wind, level->getPhysics()->getCameraPosition());
} }
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);
@ -364,7 +364,7 @@ void Graphics::render(double time)
glClear(GL_STENCIL_BUFFER_BIT);//clear stencil buffer glClear(GL_STENCIL_BUFFER_BIT);//clear stencil buffer
for(unsigned int i = 0; i<closestFlames.size(); i++) { for(unsigned int i = 0; i<closestFlames.size(); i++) {
closestFlames.at(i)->render(flameShader, lightingViewProjectionMatrix, float(time), false, wind); closestFlames.at(i)->render(flameShader, lightingViewProjectionMatrix, float(time), false, wind, level->getPhysics()->getCameraPosition());
} }
glStencilFunc(GL_EQUAL, 1, 0xFF); //Pass test if stencil value is 1 glStencilFunc(GL_EQUAL, 1, 0xFF); //Pass test if stencil value is 1