diff --git a/shaders/lib/shading-pbr.glsl b/shaders/lib/shading-pbr.glsl index c941a8e..bc94553 100644 --- a/shaders/lib/shading-pbr.glsl +++ b/shaders/lib/shading-pbr.glsl @@ -24,9 +24,8 @@ struct T_PBRPrecomputed float PBR_SchlickFresnel( in float u ) { - const float m = clamp( 1 - u , 0 , 1 ) , - m2 = m * m; - return m2 * m2 * m; + const float m = 1 - u , m2 = M_Sqr( m ); + return M_Sqr( m2 ) * m; } float PBR_GTR2Aniso( @@ -38,7 +37,7 @@ float PBR_GTR2Aniso( { float x = hDotX / ax , y = hDotY / ay , p = x * x + y * y + nDotH * nDotH; - return 1 / ( PI * ax * ay * p * p ); + return 1 / ( ax * ay * p * p ); } float PBR_SmithGGXAniso( @@ -59,7 +58,7 @@ T_PBRPrecomputed PBR_Precompute( { T_PBRPrecomputed rv; - rv.nDotV = dot( normal , camDir ); + rv.nDotV = abs( dot( normal , camDir ) ) + 1e-5; rv.fv = PBR_SchlickFresnel( rv.nDotV ); float tDir = step( .99 , abs( normal.z ) ) , @@ -93,19 +92,21 @@ vec3 PBR_Shade( in vec3 lightDir ) { float nDotL = dot( normal , lightDir ); - if ( nDotL < 0 || pre.nDotV < 0 ) { + if ( nDotL < 0 ) { return vec3( 0 ); } vec3 halfVec = normalize( lightDir + camDir ) ; - float nDotH = dot( normal , halfVec ) , - lDotH = dot( lightDir , halfVec ) , + float nDotH = M_Saturate( dot( normal , halfVec ) ) , + lDotH = M_Saturate( dot( lightDir , halfVec ) ) , // Diffuse fresnel - go from 1 at normal incidence to .5 at grazing // and mix in diffuse retro-reflection based on roughness FL = PBR_SchlickFresnel( nDotL ) , - Fd90 = 0.5 + 2 * lDotH * lDotH * material.roughness , - Fd = mix( 1 , Fd90 , FL ) * mix( 1 , Fd90 , pre.fv ) , + Fd90 = ( 0.5 + 2 * lDotH * lDotH ) * material.roughness , + Fd = ( 1 + ( Fd90 - 1 ) * FL ) + * ( 1 + ( Fd90 - 1 ) * pre.fv ) + * ( 1 - 0.51 * material.roughness / 1.51 ) , // Based on Hanrahan-Krueger brdf approximation of isotropic bssrdf // 1.25 scale is used to (roughly) preserve albedo @@ -124,11 +125,10 @@ vec3 PBR_Shade( pre.ax , pre.ay ) * pre.vgs; vec3 Fs = mix( pre.cSpecular , vec3(1) , FH ); - return nDotL * ( ( ( 1 / PI ) - * mix( Fd , ss , material.subsurface ) - * material.cAlbedo /* + Fsheen */) - * pow( 1 - material.metallic , 3 ) - + Gs * Fs * Ds ); + return nDotL * ( mix( Fd , ss , material.subsurface ) + * material.cAlbedo + * ( 1 - material.metallic ) + + Gs * Fs * Ds ) / PI; } vec3 PBR_Shade( diff --git a/shaders/lib/utils.glsl b/shaders/lib/utils.glsl index 6d74e8d..2cda412 100644 --- a/shaders/lib/utils.glsl +++ b/shaders/lib/utils.glsl @@ -36,7 +36,7 @@ vec3 M_NormalizeColor( float M_Saturate( in float x ) { - return clamp( x , 0 , 1 ); + return clamp( x , 0. , 1. ); } float M_LengthSqr( diff --git a/shaders/scene.f.glsl b/shaders/scene.f.glsl index 3c4ea5b..410272a 100644 --- a/shaders/scene.f.glsl +++ b/shaders/scene.f.glsl @@ -10,15 +10,15 @@ T_BPMaterial BPMaterials[1] = { - { vec3( .95 , .8 , 1 ) , vec3( 1 ) , 1 , 5 } + { vec3( .95 , .8 , 1 ) * .2 , vec3( 10 ) , 800 , 0 } }; T_PBRMaterial PBRMaterials[1] = { { // Albedo color - vec3( .8 , 1 , .8 ) , + vec3( .9 , 1 , .9 ) , // Roughness , metallic , subsurface , anisotropy - .3 , .8 , .8 , .9 , + .25 , .5 , .9 , .9 , // Specular strength / tint% .5 , .5 } @@ -68,13 +68,33 @@ vec3 pointlight( in float lightIntensity ) { vec3 lightRay = lightPos - hitPos; - float lPwr = lightIntensity / max( .01 , dot( lightRay , lightRay ) ); - if ( lPwr < .05 ) { + float lPwr = lightIntensity / max( .001 , dot( lightRay , lightRay ) ); + if ( lPwr < .00005 ) { return vec3( 0 ); } - return lightColor * lPwr * PBR_Shade( - material , pre , -rayDir , normal , lightRay ); + return lightColor * lPwr * PBR_Shade( material , pre , + -rayDir , normal , normalize( lightRay ) ); +} + + +vec3 pointlight( + in T_BPMaterial material , + in vec3 hitPos , + in vec3 rayDir , + in vec3 normal , + in vec3 lightPos , + in vec3 lightColor , + in float lightIntensity ) +{ + vec3 lightRay = lightPos - hitPos; + float lPwr = lightIntensity / max( .1 , dot( lightRay , lightRay ) ); + if ( lPwr < .00005 ) { + return vec3( 0 ); + } + + return lightColor * lPwr * BP_Shade( + material , -rayDir , normal , lightRay ); } @@ -116,8 +136,15 @@ void main( ) int mtype , mtidx , glowidx; mapMaterial( midx , mtype , mtidx , glowidx ); if ( mtype == 0 ) { - bc = sunlightColor * BP_Shade( BPMaterials[ mtidx ] , + T_BPMaterial mat = BPMaterials[ mtidx ]; + bc = sunlightColor * BP_Shade( mat , -rayDir , normal , sunlightDir ); + bc += pointlight( mat , + hitPos , rayDir , normal , + pl1Pos , pl1Color , pl1Power ); + bc += pointlight( mat , + hitPos , rayDir , normal , + pl2Pos , pl2Color , pl2Power ); } else { T_PBRMaterial mat = PBRMaterials[ mtidx ]; T_PBRPrecomputed pre = PBR_Precompute(