playcanvas
Version:
Open-source WebGL/WebGPU 3D engine for the web
230 lines (189 loc) • 9.37 kB
JavaScript
var lightFunctionLight_default = (
/* glsl */
`
void evaluateLight{i}(
vec3 iridescenceFresnel
) {
// light color
vec3 lightColor = light{i}_color;
// early return if the light color is black (used by shadow catcher - this way this light is very cheap)
if (all(equal(lightColor, vec3(0.0)))) {
return;
}
dLightDirNormW = light{i}_direction;
dAtten = 1.0;
vec3 lightDirW = evalOmniLight(light{i}_position);
dLightDirNormW = normalize(lightDirW);
// cookie attenuation
vec3 cookieAttenuation = getCookie2DXform(light{i}_cookie, light{i}_shadowMatrix, light{i}_cookieIntensity, light{i}_cookieMatrix, light{i}_cookieOffset).{LIGHT{i}COOKIE_CHANNEL};
vec3 cookieAttenuation = getCookie2D(light{i}_cookie, light{i}_shadowMatrix, light{i}_cookieIntensity).{LIGHT{i}COOKIE_CHANNEL};
vec3 cookieAttenuation = getCookie2DClipXform(light{i}_cookie, light{i}_shadowMatrix, light{i}_cookieIntensity, light{i}_cookieMatrix, light{i}_cookieOffset).{LIGHT{i}COOKIE_CHANNEL};
vec3 cookieAttenuation = getCookie2DClip(light{i}_cookie, light{i}_shadowMatrix, light{i}_cookieIntensity).{LIGHT{i}COOKIE_CHANNEL};
vec3 cookieAttenuation = getCookieCube(light{i}_cookie, light{i}_shadowMatrix, light{i}_cookieIntensity).{LIGHT{i}COOKIE_CHANNEL};
// multiply light color by the cookie attenuation
lightColor *= cookieAttenuation;
// distance falloff
dAtten = getFalloffLinear(light{i}_radius, lightDirW);
dAtten = getFalloffInvSquared(light{i}_radius, lightDirW);
// non punctual lights only gets the range window here
dAtten = getFalloffWindow(light{i}_radius, lightDirW);
// spot light angle falloff
dAtten *= getSpotEffect(light{i}_direction, light{i}_innerConeAngle, light{i}_outerConeAngle, dLightDirNormW);
if (dAtten < 0.00001) {
return;
}
// evaluate area light values
calcRectLightValues(light{i}_position, light{i}_halfWidth, light{i}_halfHeight);
calcDiskLightValues(light{i}_position, light{i}_halfWidth, light{i}_halfHeight);
calcSphereLightValues(light{i}_position, light{i}_halfWidth, light{i}_halfHeight);
// diffuse lighting - LTC lights do not mix diffuse lighting into attenuation that affects specular
// attenDiffuse - separate diffuse attenuation for non-punctual light sources
// NB: A better approximation perhaps using wrap lighting could be implemented here
float attenDiffuse = getLightDiffuse(litArgs_worldNormal, dViewDirW, dLightDirNormW);
// 16.0 is a constant that is in getFalloffInvSquared()
float attenDiffuse = getRectLightDiffuse(litArgs_worldNormal, dViewDirW, lightDirW, dLightDirNormW) * 16.0;
float attenDiffuse = getDiskLightDiffuse(litArgs_worldNormal, dViewDirW, lightDirW, dLightDirNormW) * 16.0;
float attenDiffuse = getSphereLightDiffuse(litArgs_worldNormal, dViewDirW, lightDirW, dLightDirNormW) * 16.0;
// one parameter is unused for punctual lights
dAtten *= getLightDiffuse(litArgs_worldNormal, vec3(0.0), dLightDirNormW);
// apply the shadow attenuation
float shadow = getShadow{i}(vec3(0.0));
float shadow = getShadow{i}(lightDirW);
// Apply shadow intensity to the shadow value
shadow = mix(1.0, shadow, light{i}_shadowIntensity);
dAtten *= shadow;
// accumulate shadows for directional lights
dShadowCatcher *= shadow;
// area light - they do not mix diffuse lighting into specular attenuation
dDiffuseLight += ((attenDiffuse * dAtten) * lightColor) * (1.0 - dLTCSpecFres);
dDiffuseLight += (attenDiffuse * dAtten) * lightColor;
// punctual light
dDiffuseLight += (dAtten * lightColor) * (1.0 - litArgs_specularity);
dDiffuseLight += dAtten * lightColor;
// specular lighting
ccSpecularLight += ccLTCSpecFres * getRectLightSpecular(litArgs_clearcoat_worldNormal, dViewDirW) * dAtten * lightColor;
ccSpecularLight += ccLTCSpecFres * getDiskLightSpecular(litArgs_clearcoat_worldNormal, dViewDirW) * dAtten * lightColor;
ccSpecularLight += ccLTCSpecFres * getSphereLightSpecular(litArgs_clearcoat_worldNormal, dViewDirW) * dAtten * lightColor;
dSpecularLight += dLTCSpecFres * getRectLightSpecular(litArgs_worldNormal, dViewDirW) * dAtten * lightColor;
dSpecularLight += dLTCSpecFres * getDiskLightSpecular(litArgs_worldNormal, dViewDirW) * dAtten * lightColor;
dSpecularLight += dLTCSpecFres * getSphereLightSpecular(litArgs_worldNormal, dViewDirW) * dAtten * lightColor;
// is fresnel needed
vec3 halfDirW = normalize(-dLightDirNormW + dViewDirW);
// if LTC lights are present, specular must be accumulated with specularity (specularity is pre multiplied by punctual light fresnel)
vec3 lightspecularCC = getLightSpecular(halfDirW, ccReflDirW, litArgs_clearcoat_worldNormal, dViewDirW, dLightDirNormW, litArgs_clearcoat_gloss, dTBN) * dAtten * lightColor;
lightspecularCC *= getFresnelCC(dot(dViewDirW, halfDirW));
ccSpecularLight += lightspecularCC;
sSpecularLight += getLightSpecularSheen(halfDirW, litArgs_worldNormal, dViewDirW, dLightDirNormW, litArgs_sheen_gloss) * dAtten * lightColor;
vec3 lightSpecular = getLightSpecular(halfDirW, dReflDirW, litArgs_worldNormal, dViewDirW, dLightDirNormW, litArgs_gloss, dTBN) * dAtten * lightColor;
lightSpecular *= getFresnel(dot(dViewDirW, halfDirW), litArgs_gloss, litArgs_specularity, iridescenceFresnel, litArgs_iridescence_intensity);
lightSpecular *= getFresnel(dot(dViewDirW, halfDirW), litArgs_gloss, litArgs_specularity);
lightSpecular *= litArgs_specularity;
dSpecularLight += lightSpecular;
}
`
);
export {
lightFunctionLight_default as default
};