Skip to content
Snippets Groups Projects
Commit 661f5548 authored by Ptolemy's avatar Ptolemy
Browse files

SL-17274: Add WIP PBR Shader

parent 29533c34
No related branches found
No related tags found
2 merge requests!3Update to main branch,!2Rebase onto current main branch
...@@ -23,6 +23,28 @@ ...@@ -23,6 +23,28 @@
* $/LicenseInfo$ * $/LicenseInfo$
*/ */
#define DEBUG_PBR_PACKORM0 0 // Rough=0, Metal=0
#define DEBUG_PBR_PACKORM1 0 // Rough=1, Metal=1
#define DEBUG_PBR_TANGENT1 1 // Tangent = 1,0,0
#define DEBUG_PBR_RAW_DIFF 0 // Output: use diffuse in G-Buffer
#define DEBUG_PBR_RAW_SPEC 0 // Output: use spec in G-Buffer
#define DEBUG_PBR_IRRADIANCE 0 // Output: Diffuse Irradiance
#define DEBUG_PBR_DIFFUSE 0 // Output: Radiance Lambertian
#define DEBUG_PBR_ORM 0 // Output: Packed Occlusion Roughness Metal
#define DEBUG_PBR_ROUGH 0 // Output: grayscale roughenss
#define DEBUG_PBR_METAL 0 // Output: grayscale metal
#define DEBUG_PBR_REFLECTANCE 0 // Output: diffuse reflectance
#define DEBUG_PBR_SPEC 0 // Output: Final spec
#define DEBUG_PBR_SPEC_REFLECTION 0 // Output: reflection
#define DEBUG_PBR_NORMAL 0 // Output: passed in normal
#define DEBUG_PBR_VIEW 0 // Output: view_dir
#define DEBUG_PBR_BRDF 0 // Output: Environment BRDF
#define DEBUG_PBR_DOT_NV 0 // Output:
#define DEBUG_PBR_DOT_TV 0 // Output:
#define DEBUG_PBR_DOT_BV 0 // Output:
#define DEBUG_PBR_FRESNEL 0 // Output: roughness dependent fresnel
#extension GL_ARB_texture_rectangle : enable #extension GL_ARB_texture_rectangle : enable
#extension GL_ARB_shader_texture_lod : enable #extension GL_ARB_shader_texture_lod : enable
...@@ -87,6 +109,32 @@ vec4 applyWaterFogView(vec3 pos, vec4 color); ...@@ -87,6 +109,32 @@ vec4 applyWaterFogView(vec3 pos, vec4 color);
uniform vec3 view_dir; // PBR uniform vec3 view_dir; // PBR
#define getDiffuseLightPBR(n) ambenv
#define getSpecularPBR(reflection) glossenv
// Approximate Environment BRDF
vec2 getGGXApprox( vec2 uv )
{
vec2 st = vec2(1.) - uv;
float d = (st.x * st.x * 0.5) * (st.y * st.y);
float scale = 1.0 - d;
float bias = d;
return vec2( scale, bias );
}
vec2 getGGX( vec2 brdfPoint )
{
// TODO: use GGXLUT
// texture2D(GGXLUT, brdfPoint).rg;
return getGGXApprox( brdfPoint);
}
vec3 calcBaseReflect0(float ior)
{
vec3 reflect0 = vec3(pow((ior - 1.0) / (ior + 1.0), 2.0));
return reflect0;
}
void main() void main()
{ {
vec2 tc = vary_fragcoord.xy; vec2 tc = vary_fragcoord.xy;
...@@ -133,6 +181,136 @@ void main() ...@@ -133,6 +181,136 @@ void main()
vec3 legacyenv; vec3 legacyenv;
sampleReflectionProbes(ambenv, glossenv, legacyenv, pos.xyz, norm.xyz, spec.a, envIntensity); sampleReflectionProbes(ambenv, glossenv, legacyenv, pos.xyz, norm.xyz, spec.a, envIntensity);
bool hasPBR = GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR);
if (hasPBR)
{
vec3 colorDiffuse = vec3(0);
vec3 colorEmissive = vec3(0);
vec3 colorSpec = vec3(0);
// vec3 colorClearCoat = vec3(0);
// vec3 colorSheen = vec3(0);
// vec3 colorTransmission = vec3(0);
vec3 packedORM = spec.rgb; // Packed: Occlusion Roughness Metal
#if DEBUG_PBR_PACK_ORM0
packedORM = vec3(0,0,0);
#endif
#if DEBUG_PBR_PACK_ORM1
packedORM = vec3(1,1,1);
#endif
float IOR = 1.5; // default Index Of Reflection 1.5
vec3 reflect0 = vec3(0.04); // -> incidence reflectance 0.04
IOR = 0.0; // TODO: Set from glb
reflect0 = calcBaseReflect0(IOR);
float metal = packedORM.b;
vec3 reflect90 = vec3(0);
vec3 v = view_dir;
vec3 n = norm.xyz;
// vec3 t = texture2DRect(tangentMap, tc).rgb;
#if DEBUG_PBR_TANGENT1
vec3 t = vec3(1,0,0);
#endif
vec3 b = cross( n,t);
vec3 reflectVN = normalize(reflect(-v,n));
float dotNV = clamp(dot(n,v),0,1);
float dotTV = clamp(dot(n,t),0,1);
float dotBV = clamp(dot(n,b),0,1);
// Reference: getMetallicRoughnessInfo
float perceptualRough = packedORM.g;
float alphaRough = perceptualRough * perceptualRough;
vec3 colorDiff = mix( diffuse.rgb, vec3(0) , metal);
reflect0 = mix( reflect0 , diffuse.rgb, metal); // reflect at 0 degrees
reflect90 = vec3(1); // reflect at 90 degrees
float reflectance = max( max( reflect0.r, reflect0.g ), reflect0.b );
// Common to RadianceGGX and RadianceLambertian
float specWeight = 1.0;
vec2 brdfPoint = clamp(vec2(dotNV, perceptualRough), vec2(0,0), vec2(1,1));
vec2 vScaleBias = getGGX( brdfPoint); // Environment BRDF: scale and bias applied to reflect0
vec3 fresnelR = max(vec3(1.0 - perceptualRough), reflect0) - reflect0; // roughness dependent fresnel
vec3 kSpec = reflect0 + fresnelR*pow(1.0 - dotNV, 5.0);
// Reference: getIBLRadianceGGX
vec3 specLight = getSpecularPBR(reflection);
#if HAS_IBL
kSpec = mix( kSpec, iridescenceFresnel, iridescenceFactor);
#endif
vec3 FssEssRadiance = kSpec*vScaleBias.x + vScaleBias.y;
colorSpec += specWeight * specLight * FssEssRadiance;
// Reference: getIBLRadianceLambertian
vec3 irradiance = getDiffuseLightPBR(n);
vec3 FssEssLambert = specWeight * kSpec * vScaleBias.x + vScaleBias.y; // NOTE: Very similar to FssEssRadiance but with extra specWeight term
float Ems = (1.0 - vScaleBias.x + vScaleBias.y);
vec3 avg = specWeight * (reflect0 + (1.0 - reflect0) / 21.0);
vec3 AvgEms = avg * Ems;
vec3 FmsEms = AvgEms * FssEssLambert / (1.0 - AvgEms);
vec3 kDiffuse = colorDiffuse * (1.0 - FssEssLambert + FmsEms);
colorDiffuse += (FmsEms + kDiffuse) * irradiance;
color.rgb = colorDiffuse + colorEmissive + colorSpec;
#if DEBUG_PBR_BRDF
color.rgb = vec3(vScaleBias,0);
#endif
#if DEBUG_PBR_FRESNEL
color.rgb = fresnelR;
#endif
#if DEBUG_PBR_RAW_DIFF
color.rgb = diffuse.rgb;
#endif
#if DEBUG_PBR_RAW_SPEC
color.rgb = spec.rgb;
#endif
#if DEBUG_PBR_REFLECTANCE
color.rgb = vec3(reflectance);
#endif
#if DEBUG_PBR_IRRADIANCE
color.rgb = irradiance;
#endif
#if DEBUG_PBR_DIFFUSE
color.rgb = colorDiffuse;
#endif
#if DEBUG_PBR_EMISSIVE
color.rgb = colorEmissive;
#endif
#if DEBUG_PBR_METAL
color.rgb = vec3(metal);
#endif
#if DEBUG_PBR_ROUGH
color.rgb = vec3(perceptualRough);
#endif
#if DEBUG_PBR_SPEC
color.rgb = colorSpec;
#endif
#if DEBUG_PBR_SPEC_REFLECTION
color.rgb = specLight;
#endif
#if DEBUG_PBR_ORM
color.rgb = packedORM;
#endif
#if DEBUG_PBR_NORMAL
color.rgb = norm.xyz;
#endif
#if DEBUG_PBR_VIEW
color.rgb = view_dir;
#endif
#if DEBUG_PBR_DOT_NV
color.rgb = vec3(dotNV);
#endif
#if DEBUG_PBR_DOT_TV
color.rgb = vec3(dotTV);
#endif
#if DEBUG_PBR_DOT_BV
color.rgb = vec3(dotBV);
#endif
}
else
{
amblit = max(ambenv, amblit); amblit = max(ambenv, amblit);
color.rgb = amblit*ambocc; color.rgb = amblit*ambocc;
...@@ -183,7 +361,7 @@ void main() ...@@ -183,7 +361,7 @@ void main()
color = fogged.rgb; color = fogged.rgb;
bloom = fogged.a; bloom = fogged.a;
#endif #endif
}
// convert to linear as fullscreen lights need to sum in linear colorspace // convert to linear as fullscreen lights need to sum in linear colorspace
// and will be gamma (re)corrected downstream... // and will be gamma (re)corrected downstream...
//color = vec3(ambocc); //color = vec3(ambocc);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment