Light overlap
This commit is contained in:
parent
62ee692291
commit
8220095e4e
5 changed files with 79 additions and 24 deletions
|
|
@ -167,6 +167,7 @@ export class RendererImplementation implements Renderer {
|
|||
{
|
||||
shadowTraceCount: settings.shadowTraceCount.toString(),
|
||||
intensityInsideRatio: settings.lightPenetrationRatio,
|
||||
lightOverlapReduction: settings.lightOverlapReduction,
|
||||
floatLinearEnabled: this.gl.insights.floatInterpolationEnabled ? '1' : '0',
|
||||
backgroundColor: colorToString(settings.backgroundColor),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ export const defaultStartupSettings: StartupSettings = {
|
|||
ignoreWebGL2: false,
|
||||
backgroundColor: vec4.fromValues(1, 1, 1, 1),
|
||||
lightPenetrationRatio: 0.75,
|
||||
lightOverlapReduction: 0,
|
||||
enableStopwatch: false,
|
||||
enableContextLostSimulator: false,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -32,6 +32,19 @@ export interface StartupSettings {
|
|||
*/
|
||||
lightPenetrationRatio: number;
|
||||
|
||||
/**
|
||||
* Controls how overlapping lights combine.
|
||||
*
|
||||
* At `0` lights are summed additively (the physically-correct default):
|
||||
* two nearby lights brighten their overlap and their glows merge into a
|
||||
* shape larger than either alone. At `1` overlapping lights instead take
|
||||
* the per-channel maximum, so a combination never reads brighter or larger
|
||||
* than its strongest contributor. Values in between blend the two.
|
||||
*
|
||||
* A single light looks the same at any value. Should be between 0 and 1.
|
||||
*/
|
||||
lightOverlapReduction: number;
|
||||
|
||||
/**
|
||||
* Gives the number of possible object colors for the scene.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@ precision lowp float;
|
|||
|
||||
#define INTENSITY_INSIDE_RATIO {intensityInsideRatio}
|
||||
#define SHADOW_TRACE_COUNT {shadowTraceCount}
|
||||
// 0.0 == lights add (overlaps brighten & merge); 1.0 == lights take the
|
||||
// per-channel max (overlaps never exceed the brighter light). See main().
|
||||
#define LIGHT_OVERLAP_REDUCTION float({lightOverlapReduction})
|
||||
|
||||
{macroDefinitions}
|
||||
|
||||
|
|
@ -65,8 +68,15 @@ void main() {
|
|||
|
||||
vec3 colorAtPosition = rgbaColorAtPosition.rgb;
|
||||
|
||||
vec3 lighting = ambientLight;
|
||||
vec3 lightingInside = ambientLight;
|
||||
// Each light contributes to two accumulators: an additive sum (overlaps
|
||||
// brighten and glows bridge into one another) and a per-channel max
|
||||
// (overlaps read as just the brightest light). LIGHT_OVERLAP_REDUCTION
|
||||
// blends between them. Ambient stays a separate additive base, so a single
|
||||
// light is identical to pure-additive (sum == max for one light).
|
||||
vec3 lightSum = vec3(0.0);
|
||||
vec3 lightMax = vec3(0.0);
|
||||
vec3 lightSumInside = vec3(0.0);
|
||||
vec3 lightMaxInside = vec3(0.0);
|
||||
|
||||
#ifdef CIRCLE_LIGHT_COUNT
|
||||
#if CIRCLE_LIGHT_COUNT > 0
|
||||
|
|
@ -78,13 +88,16 @@ void main() {
|
|||
);
|
||||
|
||||
vec2 direction = normalize(circleLightCenters[i] - position) / squareToAspectRatioTimes2;
|
||||
lighting += lightColorAtPosition * shadowTransparency(
|
||||
vec3 shadowed = lightColorAtPosition * shadowTransparency(
|
||||
startingDistance,
|
||||
lightCenterDistance,
|
||||
direction
|
||||
);
|
||||
|
||||
lightingInside += lightColorAtPosition;
|
||||
lightSum += shadowed;
|
||||
lightMax = max(lightMax, shadowed);
|
||||
lightSumInside += lightColorAtPosition;
|
||||
lightMaxInside = max(lightMaxInside, lightColorAtPosition);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
@ -107,17 +120,24 @@ void main() {
|
|||
continue;
|
||||
}
|
||||
|
||||
lighting += lightColorAtPosition * shadowTransparency(
|
||||
vec3 shadowed = lightColorAtPosition * shadowTransparency(
|
||||
startingDistance,
|
||||
lightCenterDistance,
|
||||
direction
|
||||
);
|
||||
|
||||
lightingInside += lightColorAtPosition;
|
||||
lightSum += shadowed;
|
||||
lightMax = max(lightMax, shadowed);
|
||||
lightSumInside += lightColorAtPosition;
|
||||
lightMaxInside = max(lightMaxInside, lightColorAtPosition);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
vec3 lighting = ambientLight + mix(lightSum, lightMax, LIGHT_OVERLAP_REDUCTION);
|
||||
vec3 lightingInside =
|
||||
ambientLight + mix(lightSumInside, lightMaxInside, LIGHT_OVERLAP_REDUCTION);
|
||||
|
||||
vec3 outsideColor = {backgroundColor}.rgb * lighting;
|
||||
vec3 insideColor = colorAtPosition * lightingInside * INTENSITY_INSIDE_RATIO;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,9 @@ precision lowp float;
|
|||
#define INTENSITY_INSIDE_RATIO {intensityInsideRatio}
|
||||
#define SHADOW_TRACE_COUNT {shadowTraceCount}
|
||||
#define FLOAT_LINEAR_ENABLED {floatLinearEnabled}
|
||||
// 0.0 == lights add (overlaps brighten & merge); 1.0 == lights take the
|
||||
// per-channel max (overlaps never exceed the brighter light). See main().
|
||||
#define LIGHT_OVERLAP_REDUCTION float({lightOverlapReduction})
|
||||
|
||||
{macroDefinitions}
|
||||
|
||||
|
|
@ -87,8 +90,15 @@ void main() {
|
|||
|
||||
float startingDistance = getDistance(uvCoordinates);
|
||||
|
||||
vec3 lighting = ambientLight;
|
||||
vec3 lightingInside = ambientLight;
|
||||
// Each light contributes to two accumulators: an additive sum (overlaps
|
||||
// brighten and glows bridge into one another) and a per-channel max
|
||||
// (overlaps read as just the brightest light). LIGHT_OVERLAP_REDUCTION
|
||||
// blends between them. Ambient stays a separate additive base, so a single
|
||||
// light is identical to pure-additive (sum == max for one light).
|
||||
vec3 lightSum = vec3(0.0);
|
||||
vec3 lightMax = vec3(0.0);
|
||||
vec3 lightSumInside = vec3(0.0);
|
||||
vec3 lightMaxInside = vec3(0.0);
|
||||
|
||||
#ifdef CIRCLE_LIGHT_COUNT
|
||||
#if CIRCLE_LIGHT_COUNT > 0
|
||||
|
|
@ -97,13 +107,16 @@ void main() {
|
|||
vec3 lightColorAtPosition = colorInPosition(i, lightCenterDistance);
|
||||
|
||||
vec2 direction = normalize(circleLightCenters[i] - position) / squareToAspectRatioTimes2;
|
||||
lighting += lightColorAtPosition * shadowTransparency(
|
||||
vec3 shadowed = lightColorAtPosition * shadowTransparency(
|
||||
startingDistance,
|
||||
lightCenterDistance,
|
||||
direction
|
||||
);
|
||||
|
||||
lightingInside += lightColorAtPosition;
|
||||
lightSum += shadowed;
|
||||
lightMax = max(lightMax, shadowed);
|
||||
lightSumInside += lightColorAtPosition;
|
||||
lightMaxInside = max(lightMaxInside, lightColorAtPosition);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
@ -130,17 +143,24 @@ void main() {
|
|||
continue;
|
||||
}
|
||||
|
||||
lighting += lightColorAtPosition * shadowTransparency(
|
||||
vec3 shadowed = lightColorAtPosition * shadowTransparency(
|
||||
startingDistance,
|
||||
lightCenterDistance,
|
||||
direction
|
||||
);
|
||||
|
||||
lightingInside += lightColorAtPosition;
|
||||
lightSum += shadowed;
|
||||
lightMax = max(lightMax, shadowed);
|
||||
lightSumInside += lightColorAtPosition;
|
||||
lightMaxInside = max(lightMaxInside, lightColorAtPosition);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
vec3 lighting = ambientLight + mix(lightSum, lightMax, LIGHT_OVERLAP_REDUCTION);
|
||||
vec3 lightingInside =
|
||||
ambientLight + mix(lightSumInside, lightMaxInside, LIGHT_OVERLAP_REDUCTION);
|
||||
|
||||
vec3 outsideColor = {backgroundColor}.rgb * lighting;
|
||||
vec3 insideColor = colorAtPosition * lightingInside * INTENSITY_INSIDE_RATIO;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue