mirror of
https://github.com/overte-org/overte.git
synced 2025-04-29 18:22:38 +02:00
147 lines
5.2 KiB
Text
147 lines
5.2 KiB
Text
// Generated on <$_SCRIBE_DATE$>
|
|
//
|
|
// Created by Olivier Prat on 15/01/18.
|
|
// Copyright 2018 High Fidelity, Inc.
|
|
//
|
|
// Distributed under the Apache License, Version 2.0.
|
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
//
|
|
|
|
// Everything about light
|
|
<@include graphics/Light.slh@>
|
|
<@include LightingModel.slh@>
|
|
<@include LightPoint.slh@>
|
|
<@include LightSpot.slh@>
|
|
<@include LightClusterGrid.slh@>
|
|
|
|
<$declareLightBuffer(256)$>
|
|
<$declareLightingPoint(supportScattering)$>
|
|
<$declareLightingSpot(supportScattering)$>
|
|
|
|
vec4 evalLocalLighting(ivec3 cluster, int numLights, vec3 fragWorldPos, SurfaceData surface,
|
|
float fragMetallic, vec3 fragFresnel, vec3 fragAlbedo, float fragScattering,
|
|
vec4 midNormalCurvature, vec4 lowNormalCurvature, float opacity) {
|
|
vec4 fragColor = vec4(0.0);
|
|
vec3 fragSpecular = vec3(0.0);
|
|
vec3 fragDiffuse = vec3(0.0);
|
|
int lightClusterOffset = cluster.z;
|
|
|
|
// Compute the rougness into gloss2 once:
|
|
bool withScattering = (fragScattering * isScatteringEnabled() > 0.0);
|
|
|
|
int numLightTouching = 0;
|
|
for (int i = 0; i < cluster.x; i++) {
|
|
// Need the light now
|
|
int theLightIndex = clusterGrid_getClusterLightId(i, lightClusterOffset);
|
|
Light light = getLight(theLightIndex);
|
|
|
|
// Clip againgst the light volume and Make the Light vector going from fragment to light center in world space
|
|
vec4 fragLightVecLen2;
|
|
vec4 fragLightDirLen;
|
|
|
|
if (!lightVolume_clipFragToLightVolumePoint(light.volume, fragWorldPos.xyz, fragLightVecLen2)) {
|
|
continue;
|
|
}
|
|
|
|
// Allright we re in the light sphere volume
|
|
fragLightDirLen.w = length(fragLightVecLen2.xyz);
|
|
fragLightDirLen.xyz = fragLightVecLen2.xyz / fragLightDirLen.w;
|
|
if (dot(surface.normal, fragLightDirLen.xyz) < 0.0) {
|
|
continue;
|
|
}
|
|
|
|
numLightTouching++;
|
|
|
|
vec3 diffuse = vec3(1.0);
|
|
vec3 specular = vec3(0.1);
|
|
|
|
// Allright we re valid in the volume
|
|
float fragLightDistance = fragLightDirLen.w;
|
|
vec3 fragLightDir = fragLightDirLen.xyz;
|
|
|
|
updateSurfaceDataWithLight(surface, fragLightDir);
|
|
|
|
// Eval attenuation
|
|
float radialAttenuation = lightIrradiance_evalLightAttenuation(light.irradiance, fragLightDistance);
|
|
vec3 lightEnergy = radialAttenuation * getLightIrradiance(light);
|
|
|
|
// Eval shading
|
|
if (withScattering) {
|
|
evalFragShadingScattering(diffuse, specular, fragMetallic, fragFresnel, surface, fragAlbedo,
|
|
fragScattering, midNormalCurvature, lowNormalCurvature );
|
|
} else {
|
|
evalFragShadingGloss(diffuse, specular, fragMetallic, fragFresnel, surface, fragAlbedo);
|
|
}
|
|
|
|
diffuse *= lightEnergy;
|
|
specular *= lightEnergy;
|
|
|
|
fragDiffuse.rgb += diffuse;
|
|
fragSpecular.rgb += specular;
|
|
}
|
|
|
|
for (int i = cluster.x; i < numLights; i++) {
|
|
// Need the light now
|
|
int theLightIndex = clusterGrid_getClusterLightId(i, lightClusterOffset);
|
|
Light light = getLight(theLightIndex);
|
|
|
|
// Clip againgst the light volume and Make the Light vector going from fragment to light center in world space
|
|
vec4 fragLightVecLen2;
|
|
vec4 fragLightDirLen;
|
|
float cosSpotAngle;
|
|
|
|
if (!lightVolume_clipFragToLightVolumePoint(light.volume, fragWorldPos.xyz, fragLightVecLen2)) {
|
|
continue;
|
|
}
|
|
|
|
// Allright we re in the light sphere volume
|
|
fragLightDirLen.w = length(fragLightVecLen2.xyz);
|
|
fragLightDirLen.xyz = fragLightVecLen2.xyz / fragLightDirLen.w;
|
|
if (dot(surface.normal, fragLightDirLen.xyz) < 0.0) {
|
|
continue;
|
|
}
|
|
|
|
// Check spot
|
|
if (!lightVolume_clipFragToLightVolumeSpotSide(light.volume, fragLightDirLen, cosSpotAngle)) {
|
|
continue;
|
|
}
|
|
|
|
numLightTouching++;
|
|
|
|
vec3 diffuse = vec3(1.0);
|
|
vec3 specular = vec3(0.1);
|
|
|
|
// Allright we re valid in the volume
|
|
float fragLightDistance = fragLightDirLen.w;
|
|
vec3 fragLightDir = fragLightDirLen.xyz;
|
|
|
|
updateSurfaceDataWithLight(surface, fragLightDir);
|
|
|
|
// Eval attenuation
|
|
float radialAttenuation = lightIrradiance_evalLightAttenuation(light.irradiance, fragLightDistance);
|
|
float angularAttenuation = lightIrradiance_evalLightSpotAttenuation(light.irradiance, cosSpotAngle);
|
|
vec3 lightEnergy = radialAttenuation * angularAttenuation * getLightIrradiance(light);
|
|
|
|
// Eval shading
|
|
if (withScattering) {
|
|
evalFragShadingScattering(diffuse, specular, fragMetallic, fragFresnel, surface, fragAlbedo,
|
|
fragScattering, midNormalCurvature, lowNormalCurvature );
|
|
} else {
|
|
evalFragShadingGloss(diffuse, specular, fragMetallic, fragFresnel, surface, fragAlbedo);
|
|
}
|
|
|
|
diffuse *= lightEnergy;
|
|
specular *= lightEnergy;
|
|
|
|
fragDiffuse.rgb += diffuse;
|
|
fragSpecular.rgb += specular;
|
|
}
|
|
|
|
fragDiffuse *= isDiffuseEnabled();
|
|
fragSpecular *= isSpecularEnabled();
|
|
|
|
fragColor.rgb += fragDiffuse;
|
|
fragColor.rgb += evalSpecularWithOpacity(fragSpecular, opacity);
|
|
return fragColor;
|
|
}
|
|
|