Files

79 lines
2.1 KiB
GLSL

#ifndef PHASE_GLSL
#define PHASE_GLSL
/*
** Physical based render code, develop by engineer: qiutanguu.
*/
#include "Common.glsl"
float getUniformPhase()
{
return 1.0f / (4.0f * kPI);
}
// https://www.shadertoy.com/view/Mtc3Ds
// rayleigh phase function.
float rayleighPhase(float cosTheta)
{
const float factor = 3.0f / (16.0f * kPI);
return factor * (1.0f + cosTheta * cosTheta);
}
// Schlick approximation
float cornetteShanksMiePhaseFunction(float g, float cosTheta)
{
float k = 3.0 / (8.0 * kPI) * (1.0 - g * g) / (2.0 + g * g);
return k * (1.0 + cosTheta * cosTheta) / pow(1.0 + g * g - 2.0 * g * -cosTheta, 1.5);
}
// Crazy light intensity.
float henyeyGreenstein(float cosTheta, float g)
{
float gg = g * g;
return (1. - gg) / pow(1. + gg - 2. * g * cosTheta, 1.5);
}
// See http://www.pbr-book.org/3ed-2018/Volume_Scattering/Phase_Functions.html
float hgPhase(float g, float cosTheta)
{
float numer = 1.0f - g * g;
float denom = 1.0f + g * g + 2.0f * g * cosTheta;
return numer / (4.0f * kPI * denom * sqrt(denom));
}
float dualLobPhase(float g0, float g1, float w, float cosTheta)
{
return mix(hgPhase(g0, cosTheta), hgPhase(g1, cosTheta), w);
}
float beersLaw(float density, float stepLength, float densityScale)
{
return exp(-density * stepLength * densityScale);
}
// From https://www.shadertoy.com/view/4sjBDG
float numericalMieFit(float costh)
{
// This function was optimized to minimize (delta*delta)/reference in order to capture
// the low intensity behavior.
float bestParams[10];
bestParams[0]=9.805233e-06;
bestParams[1]=-6.500000e+01;
bestParams[2]=-5.500000e+01;
bestParams[3]=8.194068e-01;
bestParams[4]=1.388198e-01;
bestParams[5]=-8.370334e+01;
bestParams[6]=7.810083e+00;
bestParams[7]=2.054747e-03;
bestParams[8]=2.600563e-02;
bestParams[9]=-4.552125e-12;
float p1 = costh + bestParams[3];
vec4 expValues = exp(vec4(bestParams[1] *costh+bestParams[2], bestParams[5] *p1*p1, bestParams[6] *costh, bestParams[9] *costh));
vec4 expValWeight= vec4(bestParams[0], bestParams[4], bestParams[7], bestParams[8]);
return dot(expValues, expValWeight);
}
#endif