Made an attempt at getting a smooth gradient of the flame color.
This commit is contained in:
parent
a1fb876880
commit
43aae3e8ec
@ -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);
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
5
flame.cc
5
flame.cc
@ -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);
|
||||||
|
2
flame.hh
2
flame.hh
@ -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;
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user