SL-17702: PBR: Cleanup light shaders to use calcHalfVectors, remove da alias, and unused sa
parent
9b8751a6e4
commit
314f27d1b1
|
|
@ -31,13 +31,25 @@ uniform vec2 screen_res;
|
|||
|
||||
const float M_PI = 3.14159265;
|
||||
|
||||
void calcHalfVectors(vec3 h, vec3 n, vec3 v, out float nh, out float nv, out float vh)
|
||||
// In:
|
||||
// lv unnormalized surface to light vector
|
||||
// n normal of the surface
|
||||
// pos unnormalized camera to surface vector
|
||||
// Out:
|
||||
// l normalized surace to light vector
|
||||
// nl diffuse angle
|
||||
// nh specular angle
|
||||
void calcHalfVectors(vec3 lv, vec3 n, vec3 v,
|
||||
out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist)
|
||||
{
|
||||
// l = normalize(lv);
|
||||
// h = normalize(l + v);
|
||||
l = normalize(lv);
|
||||
h = normalize(l + v);
|
||||
nh = clamp(dot(n, h), 0.0, 1.0);
|
||||
nl = clamp(dot(n, l), 0.0, 1.0);
|
||||
nv = clamp(dot(n, v), 0.0, 1.0);
|
||||
vh = clamp(dot(v, h), 0.0, 1.0);
|
||||
|
||||
lightDist = length(lv);
|
||||
}
|
||||
|
||||
vec2 getScreenCoordinate(vec2 screenpos)
|
||||
|
|
|
|||
|
|
@ -52,10 +52,14 @@ uniform mat4 inv_proj;
|
|||
|
||||
VARYING vec4 vary_fragcoord;
|
||||
|
||||
void calcHalfVectors(vec3 h, vec3 n, vec3 npos, out float nh, out float nv, out float vh);
|
||||
vec3 BRDFLambertian( vec3 reflect0, vec3 reflect90, vec3 c_diff, float specWeight, float vh );
|
||||
vec3 BRDFSpecularGGX( vec3 reflect0, vec3 reflect90, float alphaRoughness, float specWeight, float vh, float nl, float nv, float nh );
|
||||
void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);
|
||||
vec3 getLightIntensityPoint(vec3 lightColor, float lightRange, float lightDistance);
|
||||
vec4 getPosition(vec2 pos_screen);
|
||||
vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity);
|
||||
vec2 getScreenXY(vec4 clip);
|
||||
void initMaterial( vec3 diffuse, vec3 packedORM, out float alphaRough, out vec3 c_diff, out vec3 reflect0, out vec3 reflect90, out float specWeight );
|
||||
vec3 srgb_to_linear(vec3 c);
|
||||
|
||||
void main()
|
||||
|
|
@ -66,10 +70,6 @@ void main()
|
|||
vec3 final_color = vec3(0, 0, 0);
|
||||
vec2 tc = getScreenXY(vary_fragcoord);
|
||||
vec3 pos = getPosition(tc).xyz;
|
||||
if (pos.z < far_z)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
float envIntensity; // not used for this shader
|
||||
vec3 n;
|
||||
|
|
@ -78,8 +78,8 @@ void main()
|
|||
vec4 spec = texture2DRect(specularRect, tc);
|
||||
vec3 diffuse = texture2DRect(diffuseRect, tc).rgb;
|
||||
|
||||
float noise = texture2D(noiseMap, tc/128.0).b;
|
||||
vec3 v = -normalize(pos);
|
||||
vec3 h, l, v = -normalize(pos);
|
||||
float nh, nl, nv, vh, lightDist;
|
||||
|
||||
if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
|
||||
{
|
||||
|
|
@ -92,6 +92,13 @@ void main()
|
|||
}
|
||||
else
|
||||
{
|
||||
if (pos.z < far_z)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
float noise = texture2D(noiseMap, tc/128.0).b;
|
||||
|
||||
// As of OSX 10.6.7 ATI Apple's crash when using a variable size loop
|
||||
for (int i = 0; i < LIGHT_COUNT; ++i)
|
||||
{
|
||||
|
|
@ -100,11 +107,11 @@ void main()
|
|||
dist /= light[i].w;
|
||||
if (dist <= 1.0)
|
||||
{
|
||||
float da = dot(n, lv);
|
||||
if (da > 0.0)
|
||||
float nl = dot(n, lv);
|
||||
if (nl > 0.0)
|
||||
{
|
||||
lv = normalize(lv);
|
||||
da = dot(n, lv);
|
||||
float lightDist;
|
||||
calcHalfVectors(lv, n, v, h, l, nh, nl, nv, vh, lightDist);
|
||||
|
||||
float fa = light_col[i].a + 1.0;
|
||||
float dist_atten = clamp(1.0 - (dist - 1.0 * (1.0 - fa)) / fa, 0.0, 1.0);
|
||||
|
|
@ -116,25 +123,21 @@ void main()
|
|||
|
||||
dist_atten *= noise;
|
||||
|
||||
float lit = da * dist_atten;
|
||||
float lit = nl * dist_atten;
|
||||
|
||||
vec3 col = light_col[i].rgb * lit * diffuse;
|
||||
|
||||
if (spec.a > 0.0)
|
||||
{
|
||||
lit = min(da * 6.0, 1.0) * dist_atten;
|
||||
vec3 h = normalize(lv + v);
|
||||
float nh, nv, vh;
|
||||
calcHalfVectors(h, n, v, nh, nv, vh);
|
||||
float sa = nh;
|
||||
float fres = pow(1 - dot(h, v), 5) * 0.4 + 0.5;
|
||||
lit = min(nl * 6.0, 1.0) * dist_atten;
|
||||
float fres = pow(1 - vh, 5) * 0.4 + 0.5;
|
||||
|
||||
float gtdenom = 2 * nh;
|
||||
float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
|
||||
float gt = max(0, min(gtdenom * nv / vh, gtdenom * nl / vh));
|
||||
|
||||
if (nh > 0.0)
|
||||
{
|
||||
float scol = fres * texture2D(lightFunc, vec2(nh, spec.a)).r * gt / (nh * da);
|
||||
float scol = fres * texture2D(lightFunc, vec2(nh, spec.a)).r * gt / (nh * nl);
|
||||
col += lit * scol * light_col[i].rgb * spec.rgb;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ uniform float sun_wash;
|
|||
uniform int proj_shadow_idx;
|
||||
uniform float shadow_fade;
|
||||
|
||||
// Light params
|
||||
uniform vec3 center;
|
||||
uniform float size;
|
||||
uniform vec3 color;
|
||||
|
|
@ -72,9 +73,13 @@ uniform vec2 screen_res;
|
|||
|
||||
uniform mat4 inv_proj;
|
||||
|
||||
void calcHalfVectors(vec3 h, vec3 n, vec3 v, out float nh, out float nv, out float vh);
|
||||
vec3 BRDFLambertian( vec3 reflect0, vec3 reflect90, vec3 c_diff, float specWeight, float vh );
|
||||
vec3 BRDFSpecularGGX( vec3 reflect0, vec3 reflect90, float alphaRoughness, float specWeight, float vh, float nl, float nv, float nh );
|
||||
void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);
|
||||
vec3 getLightIntensitySpot(vec3 lightColor, float lightRange, float lightDistance, vec3 v);
|
||||
vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity);
|
||||
vec2 getScreenXY(vec4 clip);
|
||||
void initMaterial( vec3 diffuse, vec3 packedORM, out float alphaRough, out vec3 c_diff, out vec3 reflect0, out vec3 reflect90, out float specWeight );
|
||||
vec3 srgb_to_linear(vec3 cs);
|
||||
|
||||
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
|
||||
|
|
@ -182,8 +187,9 @@ void main()
|
|||
}
|
||||
|
||||
lv = proj_origin-pos.xyz;
|
||||
lv = normalize(lv);
|
||||
float da = dot(n, lv);
|
||||
vec3 h, l, v = -normalize(pos);
|
||||
float nh, nl, nv, vh, lightDist;
|
||||
calcHalfVectors(lv, n, v, h, l, nh, nl, nv, vh, lightDist);
|
||||
|
||||
vec3 diffuse = texture2DRect(diffuseRect, tc).rgb;
|
||||
vec4 spec = texture2DRect(specularRect, tc);
|
||||
|
|
@ -210,9 +216,9 @@ void main()
|
|||
float amb_da = proj_ambiance;
|
||||
float lit = 0.0;
|
||||
|
||||
if (da > 0.0)
|
||||
if (nl > 0.0)
|
||||
{
|
||||
lit = da * dist_atten * noise;
|
||||
lit = nl * dist_atten * noise;
|
||||
|
||||
float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
|
||||
float lod = diff * proj_lod;
|
||||
|
|
@ -224,14 +230,14 @@ void main()
|
|||
final_color = dlit*lit*diffuse*shadow;
|
||||
|
||||
// unshadowed for consistency between forward and deferred?
|
||||
amb_da += (da*0.5+0.5) /* * (1.0-shadow) */ * proj_ambiance;
|
||||
amb_da += (nl*0.5+0.5) /* * (1.0-shadow) */ * proj_ambiance;
|
||||
}
|
||||
|
||||
//float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
|
||||
vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
|
||||
|
||||
// use unshadowed for consistency between forward and deferred?
|
||||
amb_da += (da*da*0.5+0.5) /* * (1.0-shadow) */ * proj_ambiance;
|
||||
amb_da += (nl*nl*0.5+0.5) /* * (1.0-shadow) */ * proj_ambiance;
|
||||
amb_da *= dist_atten * noise;
|
||||
amb_da = min(amb_da, 1.0-lit);
|
||||
|
||||
|
|
@ -241,22 +247,16 @@ void main()
|
|||
|
||||
if (spec.a > 0.0)
|
||||
{
|
||||
vec3 v = -normalize(pos);
|
||||
dlit *= min(da*6.0, 1.0) * dist_atten;
|
||||
dlit *= min(nl*6.0, 1.0) * dist_atten;
|
||||
|
||||
//vec3 ref = dot(pos+lv, n);
|
||||
vec3 h = normalize(lv + v);
|
||||
float nh, nv, vh;
|
||||
calcHalfVectors(h, n, v, nh, nv, vh);
|
||||
float sa = nh;
|
||||
float fres = pow(1 - dot(h, v), 5)*0.4+0.5;
|
||||
float fres = pow(1 - vh, 5)*0.4+0.5;
|
||||
|
||||
float gtdenom = 2 * nh;
|
||||
float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
|
||||
float gt = max(0, min(gtdenom * nv / vh, gtdenom * nl / vh));
|
||||
|
||||
if (nh > 0.0)
|
||||
{
|
||||
float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
|
||||
float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*nl);
|
||||
vec3 speccol = dlit*scol*spec.rgb*shadow;
|
||||
speccol = clamp(speccol, vec3(0), vec3(1));
|
||||
final_color += speccol;
|
||||
|
|
|
|||
|
|
@ -59,7 +59,8 @@ uniform vec4 viewport;
|
|||
|
||||
vec3 BRDFLambertian( vec3 reflect0, vec3 reflect90, vec3 c_diff, float specWeight, float vh );
|
||||
vec3 BRDFSpecularGGX( vec3 reflect0, vec3 reflect90, float alphaRoughness, float specWeight, float vh, float nl, float nv, float nh );
|
||||
void calcHalfVectors(vec3 h, vec3 n, vec3 v, out float nh, out float nv, out float vh);
|
||||
void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);
|
||||
vec3 getLightIntensityPoint(vec3 lightColor, float lightRange, float lightDistance);
|
||||
vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity);
|
||||
vec4 getPosition(vec2 pos_screen);
|
||||
vec2 getScreenXY(vec4 clip);
|
||||
|
|
@ -72,35 +73,18 @@ void main()
|
|||
vec2 tc = getScreenXY(vary_fragcoord);
|
||||
vec3 pos = getPosition(tc).xyz;
|
||||
|
||||
vec3 lv = trans_center.xyz-pos;
|
||||
float dist = length(lv);
|
||||
if (dist >= size)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
dist /= size;
|
||||
|
||||
float envIntensity;
|
||||
vec3 n;
|
||||
vec4 norm = getNormalEnvIntensityFlags(tc, n, envIntensity); // need `norm.w` for GET_GBUFFER_FLAG()
|
||||
|
||||
float da = dot(n, lv);
|
||||
if (da < 0.0)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
lv = normalize(lv);
|
||||
da = dot(n, lv); // alias for: nl
|
||||
|
||||
vec3 diffuse = texture2DRect(diffuseRect, tc).rgb;
|
||||
vec4 spec = texture2DRect(specularRect, tc);
|
||||
|
||||
// Common half vectors calcs
|
||||
vec3 v = -normalize(pos);
|
||||
vec3 h = normalize(lv + v);
|
||||
float nh, nv, vh;
|
||||
calcHalfVectors(h, n, v, nh, nv, vh);
|
||||
vec3 lv = trans_center.xyz-pos;
|
||||
vec3 h, l, v = -normalize(pos);
|
||||
float nh, nl, nv, vh, lightDist;
|
||||
calcHalfVectors(lv, n, v, h, l, nh, nl, nv, vh, lightDist);
|
||||
|
||||
if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
|
||||
{
|
||||
|
|
@ -113,9 +97,6 @@ void main()
|
|||
float alphaRough, specWeight;
|
||||
initMaterial( diffuse, packedORM, alphaRough, c_diff, reflect0, reflect90, specWeight );
|
||||
|
||||
vec3 l = lv; // already normalized
|
||||
float nl = clamp(dot(n, l), 0.0, 1.0);
|
||||
|
||||
if (nl > 0.0 || nv > 0.0)
|
||||
{
|
||||
vec3 intensity = size * color;
|
||||
|
|
@ -127,28 +108,40 @@ void main()
|
|||
}
|
||||
else
|
||||
{
|
||||
float dist = lightDist;
|
||||
if (dist >= size)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
dist /= size;
|
||||
|
||||
if (nl < 0.0)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
float fa = falloff+1.0;
|
||||
float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
|
||||
dist_atten *= dist_atten;
|
||||
dist_atten *= 2.0;
|
||||
|
||||
float noise = texture2D(noiseMap, tc/128.0).b;
|
||||
float lit = da * dist_atten * noise;
|
||||
float lit = nl * dist_atten * noise;
|
||||
|
||||
final_color = color.rgb*lit*diffuse;
|
||||
|
||||
if (spec.a > 0.0)
|
||||
{
|
||||
lit = min(da*6.0, 1.0) * dist_atten;
|
||||
lit = min(nl*6.0, 1.0) * dist_atten;
|
||||
|
||||
float sa = nh;
|
||||
float fres = pow(1 - dot(h, v), 5) * 0.4+0.5;
|
||||
float fres = pow(1 - vh, 5) * 0.4+0.5;
|
||||
float gtdenom = 2 * nh;
|
||||
float gt = max(0,(min(gtdenom * nv / vh, gtdenom * da / vh)));
|
||||
float gt = max(0,(min(gtdenom * nv / vh, gtdenom * nl / vh)));
|
||||
|
||||
if (nh > 0.0)
|
||||
{
|
||||
float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
|
||||
float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*nl);
|
||||
final_color += lit*scol*color.rgb*spec.rgb;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,9 +72,13 @@ uniform vec2 screen_res;
|
|||
|
||||
uniform mat4 inv_proj;
|
||||
|
||||
void calcHalfVectors(vec3 h, vec3 n, vec3 v, out float nh, out float nv, out float vh);
|
||||
vec2 getScreenXY(vec4 clip_point);
|
||||
vec3 BRDFLambertian( vec3 reflect0, vec3 reflect90, vec3 c_diff, float specWeight, float vh );
|
||||
vec3 BRDFSpecularGGX( vec3 reflect0, vec3 reflect90, float alphaRoughness, float specWeight, float vh, float nl, float nv, float nh );
|
||||
void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);
|
||||
vec3 getLightIntensitySpot(vec3 lightColor, float lightRange, float lightDistance, vec3 v);
|
||||
vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity);
|
||||
vec2 getScreenXY(vec4 clip_point);
|
||||
void initMaterial( vec3 diffuse, vec3 packedORM, out float alphaRough, out vec3 c_diff, out vec3 reflect0, out vec3 reflect90, out float specWeight );
|
||||
vec3 srgb_to_linear(vec3 c);
|
||||
|
||||
vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
|
||||
|
|
@ -144,7 +148,7 @@ void main()
|
|||
vec4 shd = texture2DRect(lightMap, tc);
|
||||
shadow = (proj_shadow_idx == 0) ? shd.b : shd.a;
|
||||
shadow += shadow_fade;
|
||||
shadow = clamp(shadow, 0.0, 1.0);
|
||||
shadow = clamp(shadow, 0.0, 1.0);
|
||||
}
|
||||
|
||||
float envIntensity;
|
||||
|
|
@ -172,8 +176,9 @@ void main()
|
|||
}
|
||||
|
||||
lv = proj_origin-pos.xyz;
|
||||
lv = normalize(lv);
|
||||
float da = dot(n, lv);
|
||||
vec3 h, l, v = -normalize(pos);
|
||||
float nh, nl, nv, vh, lightDist;
|
||||
calcHalfVectors(lv, n, v, h, l, nh, nl, nv, vh, lightDist);
|
||||
|
||||
vec3 diffuse = texture2DRect(diffuseRect, tc).rgb;
|
||||
vec4 spec = texture2DRect(specularRect, tc);
|
||||
|
|
@ -200,9 +205,9 @@ void main()
|
|||
float amb_da = proj_ambiance;
|
||||
float lit = 0.0;
|
||||
|
||||
if (da > 0.0)
|
||||
if (nl > 0.0)
|
||||
{
|
||||
lit = da * dist_atten * noise;
|
||||
lit = nl * dist_atten * noise;
|
||||
|
||||
float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
|
||||
float lod = diff * proj_lod;
|
||||
|
|
@ -213,13 +218,13 @@ void main()
|
|||
|
||||
final_color = dlit*lit*diffuse*shadow;
|
||||
|
||||
amb_da += (da*0.5+0.5) /* * (1.0-shadow) */ * proj_ambiance;
|
||||
amb_da += (nl*0.5+0.5) /* * (1.0-shadow) */ * proj_ambiance;
|
||||
}
|
||||
|
||||
//float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
|
||||
vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
|
||||
|
||||
amb_da += (da*da*0.5+0.5) /* * (1.0-shadow) */ * proj_ambiance;
|
||||
amb_da += (nl*nl*0.5+0.5) /* * (1.0-shadow) */ * proj_ambiance;
|
||||
amb_da *= dist_atten * noise;
|
||||
amb_da = min(amb_da, 1.0-lit);
|
||||
|
||||
|
|
@ -228,22 +233,15 @@ void main()
|
|||
|
||||
if (spec.a > 0.0)
|
||||
{
|
||||
dlit *= min(da*6.0, 1.0) * dist_atten;
|
||||
vec3 v = -normalize(pos);
|
||||
|
||||
//vec3 ref = dot(pos+lv, n);
|
||||
vec3 h = normalize(lv + v);
|
||||
float nh, nv, vh;
|
||||
calcHalfVectors(h, n, v, nh, nv, vh);
|
||||
float sa = nh;
|
||||
dlit *= min(nl*6.0, 1.0) * dist_atten;
|
||||
float fres = pow(1 - dot(h, v), 5)*0.4+0.5;
|
||||
|
||||
float gtdenom = 2 * nh;
|
||||
float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
|
||||
float gt = max(0, min(gtdenom * nv / vh, gtdenom * nl / vh));
|
||||
|
||||
if (nh > 0.0)
|
||||
{
|
||||
float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
|
||||
float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*nl);
|
||||
vec3 speccol = dlit*scol*spec.rgb*shadow;
|
||||
speccol = clamp(speccol, vec3(0), vec3(1));
|
||||
final_color += speccol;
|
||||
|
|
|
|||
Loading…
Reference in New Issue