diff --git a/data/shader/flame.fsh b/data/shader/flame.fsh index 7a4127d..4f64611 100644 --- a/data/shader/flame.fsh +++ b/data/shader/flame.fsh @@ -1,15 +1,40 @@ #version 150 -in vec3 fColor; +in GS_OUT { + float maxAngle; + vec3 position; +}fs_in; + +in vec4 flameCenter; out vec4 oColor; 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() { + 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) { - oColor = vec4(fColor, 0.6); + oColor = vec4(colorFunction(angle/fs_in.maxAngle), 0.6); } else { oColor = vec4(0.0, 0.0, 0.0, 0.0); diff --git a/data/shader/flame.gsh b/data/shader/flame.gsh index 3c1cba4..2ee8fbb 100644 --- a/data/shader/flame.gsh +++ b/data/shader/flame.gsh @@ -1,15 +1,22 @@ #version 150 uniform mat4 modelViewProjectionMatrix; +uniform mat4 viewProjectionMatrix; uniform float time; uniform bool bottom; uniform bool left; +uniform vec3 camera; 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[]; -out vec3 fColor; +out vec4 flameCenter; const float PI = 3.1415926; const float transition_point_1 = 1.178097; @@ -29,9 +36,11 @@ const float begin_2 = 0; const float end_2 = 3; 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 value_1 = 0.0; float value_2 = 0.0; @@ -51,7 +60,18 @@ float radiusFunction(float x) { } 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 this_begin = mix(begin_1, begin_2, flickerFunction()); @@ -70,6 +90,8 @@ void main() { for (i; i(size * glm::vec3(1.1f)); } else { - modelMatrix = skewMatrixX * skewMatrixZ * glm::scale(size); + modelMatrix = skewMatrixX * skewMatrixZ * glm::scale(size * glm::vec3(10.0f)); } glm::mat4 modelViewProjectionMatrix = viewProjectionMatrix * modelMatrix; shader->setUniform("modelViewProjectionMatrix", modelViewProjectionMatrix); shader->setUniform("viewProjectionMatrix", viewProjectionMatrix); shader->setUniform("withColor", withColor); + shader->setUniform("camera", camera); shader->setUniform("time", time); shader->setUniform("bottom", true); shader->setUniform("left", true); diff --git a/flame.hh b/flame.hh index 5649774..6bbebdd 100644 --- a/flame.hh +++ b/flame.hh @@ -9,7 +9,7 @@ class Flame : public Entity { Flame(glm::vec3 position, glm::vec3 color, glm::vec3 size); Flame(); 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: glm::vec3 color; glm::vec3 size; diff --git a/graphics.cc b/graphics.cc index 1272914..88fb33b 100644 --- a/graphics.cc +++ b/graphics.cc @@ -352,7 +352,7 @@ void Graphics::render(double time) // draw with colors for(unsigned int i = 0; irender(flameShader, lightingViewProjectionMatrix, float(time), true, wind); + closestFlames.at(i)->render(flameShader, lightingViewProjectionMatrix, float(time), true, wind, level->getPhysics()->getCameraPosition()); } glDisable(GL_CULL_FACE); @@ -364,7 +364,7 @@ void Graphics::render(double time) glClear(GL_STENCIL_BUFFER_BIT);//clear stencil buffer for(unsigned int i = 0; irender(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