Common.IBL.IBLKernels.frag Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jme3-core Show documentation
Show all versions of jme3-core Show documentation
jMonkeyEngine is a 3-D game engine for adventurous Java developers
The newest version!
/**
* This code is based on the following articles:
* https://learnopengl.com/PBR/IBL/Diffuse-irradiance
* https://learnopengl.com/PBR/IBL/Specular-IBL
* - Riccardo Balbo
*/
#import "Common/ShaderLib/GLSLCompat.glsllib"
#import "Common/IBL/Math.glsl"
in vec2 TexCoords;
in vec3 LocalPos;
uniform samplerCube m_EnvMap;
uniform float m_Roughness;
uniform int m_FaceId;
void brdfKernel(){
float NdotV=TexCoords.x;
float m_Roughness=TexCoords.y;
vec3 V;
V.x = sqrt(1.0 - NdotV*NdotV);
V.y = 0.0;
V.z = NdotV;
float A = 0.0;
float B = 0.0;
vec3 N = vec3(0.0, 0.0, 1.0);
const uint SAMPLE_COUNT = 1024u;
for(uint i = 0u; i < SAMPLE_COUNT; i++){
vec4 Xi = Hammersley(i, SAMPLE_COUNT);
vec3 H = ImportanceSampleGGX(Xi, m_Roughness, N);
vec3 L = normalize(2.0 * dot(V, H) * H - V);
float NdotL = max(L.z, 0.0);
float NdotH = max(H.z, 0.0);
float VdotH = max(dot(V, H), 0.0);
if(NdotL > 0.0){
float G = GeometrySmith(N, V, L, m_Roughness);
float G_Vis = (G * VdotH) / (NdotH * NdotV);
float Fc = pow(1.0 - VdotH, 5.0);
A += (1.0 - Fc) * G_Vis;
B += Fc * G_Vis;
}
}
A /= float(SAMPLE_COUNT);
B /= float(SAMPLE_COUNT);
outFragColor.rg=vec2(A, B);
outFragColor.ba=vec2(0);
}
void irradianceKernel(){
// the sample direction equals the hemisphere's orientation
vec3 N = normalize(LocalPos);
vec3 irradiance = vec3(0.0);
vec3 up = vec3(0.0, 1.0, 0.0);
vec3 right = cross(up, N);
up = cross(N, right);
float sampleDelta = 0.025;
float nrSamples = 0.0;
for(float phi = 0.0; phi < 2.0 * PI; phi += sampleDelta){
for(float theta = 0.0; theta < 0.5 * PI; theta += sampleDelta){
// spherical to cartesian (in tangent space)
vec3 tangentSample = vec3(sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta));
// tangent space to world
vec3 sampleVec = tangentSample.x * right + tangentSample.y * up + tangentSample.z * N;
irradiance += texture(m_EnvMap, sampleVec).rgb * cos(theta) * sin(theta);
nrSamples++;
}
}
irradiance = PI * irradiance * (1.0 / float(nrSamples));
outFragColor = vec4(irradiance, 1.0);
}
void prefilteredEnvKernel(){
vec3 N = normalize(LocalPos);
vec3 R = N;
vec3 V = R;
// float a2 = m_Roughness;
float a2 = m_Roughness * m_Roughness; // jme impl, why?
a2 *= a2;
const uint SAMPLE_COUNT = 1024u;
float totalWeight = 0.0;
vec3 prefilteredColor = vec3(0.0);
for(uint i = 0u; i < SAMPLE_COUNT; ++i) {
vec4 Xi = Hammersley(i, SAMPLE_COUNT);
vec3 H = ImportanceSampleGGX(Xi, a2, N);
float VoH = dot(V,H);
vec3 L = normalize(2.0 * VoH * H - V);
float NdotL = max(dot(N, L), 0.0);
if(NdotL > 0.0) {
// TODO: use mipmap
prefilteredColor += texture(m_EnvMap, L).rgb * NdotL;
totalWeight += NdotL;
}
}
prefilteredColor = prefilteredColor / totalWeight;
outFragColor = vec4(prefilteredColor, 1.0);
}
void main(){
#if defined(SIBL)
prefilteredEnvKernel();
#elif defined(IRRADIANCE)
irradianceKernel();
#else
brdfKernel();
#endif
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy