Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Animated the thrust flame #6056

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions data/shaders/opengl/thruster.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright © 2008-2025 Pioneer Developers. See AUTHORS.txt for details
// Licensed under the terms of the GPL v3. See licenses/GPL-3.txt

#include "attributes.glsl"
#include "lib.glsl"

uniform sampler2D texture0; //diffuse

in vec2 texCoord0;
in vec4 flame_color;
in float ramp;

out vec4 frag_color;

void main(void)
{
vec4 color = texture(texture0, texCoord0);
vec3 old_color = color.rgb;
color *= flame_color;
// generate a light blue flickering glow around the flame
float ramp2 = ramp * ramp;
color.g += ramp2 * ramp2 * old_color.g;
color.r += ramp2 * ramp * old_color.r;
color.b += ramp2 * old_color.b;

frag_color = color;
}
12 changes: 12 additions & 0 deletions data/shaders/opengl/thruster.shaderdef
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
## Copyright © 2008-2025 Pioneer Developers. See AUTHORS.txt for details
## Licensed under the terms of the GPL v3. See licenses/GPL-3.txt

# Basic shader for drawing unlit, possibly textured models that are animated

Shader thruster

Texture sampler2D texture0 name=diffuse
Buffer DrawData binding=1

Vertex "thruster.vert"
Fragment "thruster.frag"
46 changes: 46 additions & 0 deletions data/shaders/opengl/thruster.vert
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright © 2008-2025 Pioneer Developers. See AUTHORS.txt for details
// Licensed under the terms of the GPL v3. See licenses/GPL-3.txt

// #extension GL_ARB_gpu_shader5 : enable

#include "attributes.glsl"
#include "lib.glsl"

out vec2 texCoord0;
out vec4 flame_color;
out float ramp;

float map_percentage( float val, float base_percent)
{
return base_percent + val * (1.0 - base_percent);
}

void main(void)
{
// emission.r is the thruster power setting
float thruster_power = material.emission.r;
// emission.a is the random flicker value
float random = material.emission.a;

// power setting effects the brightness and opacity of the flame
float brightness = map_percentage(thruster_power, 0.25);
// flicker should only change the brightness a small amount each frame
float flicker = map_percentage(random, 0.95);

flame_color = material.diffuse * flicker * brightness;
// a very light blue flickering glow around flame
flame_color.rg *= vec2(flicker);

// the power setting also controls the length of the flame
// flame length can range from 50% to 100%
float flame_length = map_percentage(thruster_power, 0.5);
// modulate the flame shape using flicker
// flame_length only effects the z axis which is the thrust direction
vec4 scale = vec4(flicker, flicker, flicker * flame_length, 1.0);

gl_Position = uViewProjectionMatrix * (a_vertex * scale);

texCoord0 = a_uv0.xy;
// set the blend ramp
ramp = a_uv0.y * 0.5;
}
3 changes: 3 additions & 0 deletions src/Intro.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,5 +160,8 @@ void Intro::Draw(float deltaTime)
matrix4x4f::Translation(0, 0, m_dist) *
matrix4x4f::RotateXMatrix(DEG2RAD(-15.0f)) *
matrix4x4f::RotateYMatrix(duration);

// animate thrusters
m_model->SetTimeStep(duration);
m_model->Render(trans);
}
2 changes: 2 additions & 0 deletions src/ShipCockpit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,8 @@ void ShipCockpit::Update(const Player *player, float timeStep)
vector3f linthrust{ prop->GetLinThrusterState() };
vector3f angthrust{ prop->GetAngThrusterState() };
GetModel()->SetThrust(linthrust, -angthrust);
// animate the thrusters
GetModel()->SetTimeStep(timeStep);
}
}

Expand Down
1 change: 1 addition & 0 deletions src/editor/ModelViewerWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,7 @@ void ModelViewerWidget::DrawModel(matrix4x4f trans)
(m_options.showGeomBBox ? SceneGraph::Model::DEBUG_GEOMBBOX : 0x0) |
(m_options.wireframe ? SceneGraph::Model::DEBUG_WIREFRAME : 0x0));

m_model->SetTimeStep(0.01f);
m_model->Render(m_modelViewMat);
m_navLights->Render(m_renderer);
}
Expand Down
11 changes: 11 additions & 0 deletions src/scenegraph/Model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,9 @@ namespace SceneGraph {
//Override renderdata if this model is called from ModelNode
RenderData params = (rd != 0) ? (*rd) : m_renderData;

// reset time step for next frame
m_renderData.timeStep = 0.f;

m_renderer->SetTransform(trans);

//using the entire model bounding radius for all nodes at the moment.
Expand Down Expand Up @@ -212,6 +215,9 @@ namespace SceneGraph {
//Override renderdata if this model is called from ModelNode
RenderData params = (rd != 0) ? (*rd) : m_renderData;

// reset time step
m_renderData.timeStep = 0.f;

//using the entire model bounding radius for all nodes at the moment.
//BR could also be a property of Node.
params.boundingRadius = GetDrawClipRadius();
Expand Down Expand Up @@ -434,6 +440,11 @@ namespace SceneGraph {
m_renderData.angthrust[2] = ang.z;
}

void Model::SetTimeStep(const float timeStep)
{
m_renderData.timeStep = timeStep;
}

void Model::SetThrusterColor(const vector3f &dir, const Color &color)
{
assert(m_root != nullptr);
Expand Down
1 change: 1 addition & 0 deletions src/scenegraph/Model.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ namespace SceneGraph {
Graphics::Renderer *GetRenderer() const { return m_renderer; }

//special for ship model use
void SetTimeStep(const float timeStep);
void SetThrust(const vector3f &linear, const vector3f &angular);

void SetThrusterColor(const vector3f &dir, const Color &color);
Expand Down
2 changes: 2 additions & 0 deletions src/scenegraph/Node.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,15 @@ namespace SceneGraph {
float linthrust[3]; // 1.0 to -1.0
float angthrust[3]; // 1.0 to -1.0
Color customColor;
float timeStep; // used as a heart beat for shaders

float boundingRadius; //updated by model and passed to submodels
unsigned int nodemask;

RenderData() :
linthrust(),
angthrust(),
timeStep(0.f),
boundingRadius(0.f),
nodemask(NODE_SOLID) //draw solids
{
Expand Down
30 changes: 24 additions & 6 deletions src/scenegraph/Thruster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ namespace SceneGraph {
linearOnly(_linear),
dir(_dir),
pos(_pos),
currentColor(baseColor)
currentColor(baseColor),
m_time(0.f)
{
//set up materials
Graphics::MaterialDescriptor desc;
Expand All @@ -41,12 +42,12 @@ namespace SceneGraph {
rsd.depthWrite = false;
rsd.cullMode = Graphics::CULL_NONE;

m_tMat.Reset(r->CreateMaterial("unlit", desc, rsd));
m_tMat.Reset(r->CreateMaterial("thruster", desc, rsd));
m_tMat->SetTexture("texture0"_hash,
Graphics::TextureBuilder::Billboard(thrusterTextureFilename).GetOrCreateTexture(r, "billboard"));
m_tMat->diffuse = baseColor;

m_glowMat.Reset(r->CreateMaterial("unlit", desc, rsd));
m_glowMat.Reset(r->CreateMaterial("thruster", desc, rsd));
m_glowMat->SetTexture("texture0"_hash,
Graphics::TextureBuilder::Billboard(thrusterGlowTextureFilename).GetOrCreateTexture(r, "billboard"));
m_glowMat->diffuse = baseColor;
Expand All @@ -59,7 +60,8 @@ namespace SceneGraph {
linearOnly(thruster.linearOnly),
dir(thruster.dir),
pos(thruster.pos),
currentColor(thruster.currentColor)
currentColor(thruster.currentColor),
m_time(thruster.m_time)
{
}

Expand Down Expand Up @@ -100,8 +102,24 @@ namespace SceneGraph {
}
}
if (power < 0.001f) return;

m_tMat->diffuse = m_glowMat->diffuse = currentColor * power;

// animate the thrust flame using the thruster shader
// update animation time on each render
// a unique time stamp is needed for each thruster flame to have a unique flicker
// use thruster position to make each thruster time different
m_time += abs(trans[12] + trans[13] + trans[14]) * rd->timeStep * 1000.0f;
// generate a psuedo random flicker
// this could be done in the vertex shader but the value only needs to be
// generated once per frame, not for every vertex
const float flicker = sin(m_time) * 43758.5453f;

// pass the power setting and flicker value using the material emissive
// emissive.a is the flicker value for the flame
m_tMat->emissive.a = m_glowMat->emissive.a = flicker;
// emissive.r is the thruster power setting which effects flame length and brightness
m_tMat->emissive.r = m_glowMat->emissive.r = 255.0f * power;

m_tMat->diffuse = m_glowMat->diffuse = currentColor;

//directional fade
vector3f cdir = vector3f(trans * -dir).Normalized();
Expand Down
1 change: 1 addition & 0 deletions src/scenegraph/Thruster.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ namespace SceneGraph {
vector3f dir;
vector3f pos;
Color currentColor;
float m_time; // used for animating the thruster
};

} // namespace SceneGraph
Expand Down
5 changes: 4 additions & 1 deletion src/ship/Propulsion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,10 @@ void Propulsion::Render(Graphics::Renderer *r, const Camera *camera, const vecto
* thruster and so on)... this code is :-/
*/
//angthrust negated, for some reason
if (m_smodel != nullptr) m_smodel->SetThrust(vector3f(GetLinThrusterState()), -vector3f(GetAngThrusterState()));
if (m_smodel != nullptr) {
m_smodel->SetThrust(vector3f(GetLinThrusterState()), -vector3f(GetAngThrusterState()));
m_smodel->SetTimeStep(Pi::game->GetTimeStep());
}
}

void Propulsion::AIModelCoordsMatchSpeedRelTo(const vector3d &v, const DynamicBody *other)
Expand Down
Loading