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

improve planet rings shaders #5708

Merged
merged 3 commits into from
Jan 18, 2024
Merged
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
19 changes: 19 additions & 0 deletions data/shaders/opengl/lib.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,25 @@ struct Surface {
float ambientOcclusion;
};

// Phase functions
// https://www.scratchapixel.com/lessons/procedural-generation-virtual-worlds/simulating-sky/simulating-colors-of-the-sky.html
float miePhaseFunction(const float g, const float mu)
{
/*
* Mie phase function:
*/
return 3.f / (8.f * 3.141592) * ((1.f - g * g) * (1.f + mu * mu)) / ((2.f + g * g) * pow(1.f + g * g - 2.f * g * mu, 1.5f));
}

float rayleighPhaseFunction(const float mu)
{
/*
* Rayleigh phase function:
*/
return 3.f / (16.f * 3.141592) * (1 + mu * mu);
}


// Currently used by: hopefully everything
// Evaluates a standard blinn-phong diffuse+specular, with the addition of a
// light intensity term to scale the lighting contribution based on (pre-calculated)
Expand Down
17 changes: 16 additions & 1 deletion data/shaders/opengl/planetrings.frag
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
uniform sampler2D texture0;
in vec2 texCoord0;
in vec4 texCoord1;
in vec4 varyingEyepos;

out vec4 frag_color;

Expand All @@ -16,10 +17,24 @@ void main(void)
vec4 col = vec4(0.0);
vec4 texCol = texture(texture0, texCoord0);

vec3 eyenorm = normalize(varyingEyepos.xyz);

for (int i=0; i<NUM_LIGHTS; ++i) {
float l = findSphereEyeRayEntryDistance(-vec3(texCoord1), vec3(uViewMatrixInverse * uLight[i].position), 1.0);
if (l <= 0.0) {
col = col + texCol*uLight[i].diffuse;
// first term: diffuse light phase (like in full/new moon)
float mu = dot(normalize(vec3(uLight[i].position)), eyenorm);
float diffuse = sqrt((1 - mu) / 2);

// second term: diffuse mie (scattering through ring)
float g = 0.76f;
float phaseThrough = miePhaseFunction(g, mu);

// third term: reflect mie (imitate albedo >= 1.0)
float muRev = dot(-normalize(vec3(uLight[i].position)), eyenorm);
float phaseReflect = miePhaseFunction(g, muRev);

col = col + texCol * (diffuse + phaseThrough + phaseReflect) * uLight[i].diffuse;
}
}
col.a = texCol.a;
Expand Down
2 changes: 2 additions & 0 deletions data/shaders/opengl/planetrings.vert
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@

out vec2 texCoord0;
out vec4 texCoord1;
out vec4 varyingEyepos;

void main(void)
{
gl_Position = matrixTransform();

texCoord0 = a_uv0.xy;
texCoord1 = a_vertex;
varyingEyepos = uViewMatrix * a_vertex;
}
4 changes: 2 additions & 2 deletions src/Planet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,9 @@ void Planet::GenerateRings(Graphics::Renderer *renderer)
{
Color *row;
row = buf.get();
std::fill_n(row, RING_TEXTURE_WIDTH, Color::BLACK);
std::fill_n(row, RING_TEXTURE_WIDTH, Color::BLANK);
row = buf.get() + (RING_TEXTURE_LENGTH - 1) * RING_TEXTURE_WIDTH;
std::fill_n(row, RING_TEXTURE_WIDTH, Color::BLACK);
std::fill_n(row, RING_TEXTURE_WIDTH, Color::BLANK);
}

const vector3f texSize(RING_TEXTURE_WIDTH, RING_TEXTURE_LENGTH, 0.0f);
Expand Down