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(),
|
shadowTraceCount: settings.shadowTraceCount.toString(),
|
||||||
intensityInsideRatio: settings.lightPenetrationRatio,
|
intensityInsideRatio: settings.lightPenetrationRatio,
|
||||||
|
lightOverlapReduction: settings.lightOverlapReduction,
|
||||||
floatLinearEnabled: this.gl.insights.floatInterpolationEnabled ? '1' : '0',
|
floatLinearEnabled: this.gl.insights.floatInterpolationEnabled ? '1' : '0',
|
||||||
backgroundColor: colorToString(settings.backgroundColor),
|
backgroundColor: colorToString(settings.backgroundColor),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ export const defaultStartupSettings: StartupSettings = {
|
||||||
ignoreWebGL2: false,
|
ignoreWebGL2: false,
|
||||||
backgroundColor: vec4.fromValues(1, 1, 1, 1),
|
backgroundColor: vec4.fromValues(1, 1, 1, 1),
|
||||||
lightPenetrationRatio: 0.75,
|
lightPenetrationRatio: 0.75,
|
||||||
|
lightOverlapReduction: 0,
|
||||||
enableStopwatch: false,
|
enableStopwatch: false,
|
||||||
enableContextLostSimulator: false,
|
enableContextLostSimulator: false,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,19 @@ export interface StartupSettings {
|
||||||
*/
|
*/
|
||||||
lightPenetrationRatio: number;
|
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.
|
* Gives the number of possible object colors for the scene.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,9 @@ precision lowp float;
|
||||||
|
|
||||||
#define INTENSITY_INSIDE_RATIO {intensityInsideRatio}
|
#define INTENSITY_INSIDE_RATIO {intensityInsideRatio}
|
||||||
#define SHADOW_TRACE_COUNT {shadowTraceCount}
|
#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}
|
{macroDefinitions}
|
||||||
|
|
||||||
|
|
@ -65,8 +68,15 @@ void main() {
|
||||||
|
|
||||||
vec3 colorAtPosition = rgbaColorAtPosition.rgb;
|
vec3 colorAtPosition = rgbaColorAtPosition.rgb;
|
||||||
|
|
||||||
vec3 lighting = ambientLight;
|
// Each light contributes to two accumulators: an additive sum (overlaps
|
||||||
vec3 lightingInside = ambientLight;
|
// 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
|
#ifdef CIRCLE_LIGHT_COUNT
|
||||||
#if CIRCLE_LIGHT_COUNT > 0
|
#if CIRCLE_LIGHT_COUNT > 0
|
||||||
|
|
@ -78,13 +88,16 @@ void main() {
|
||||||
);
|
);
|
||||||
|
|
||||||
vec2 direction = normalize(circleLightCenters[i] - position) / squareToAspectRatioTimes2;
|
vec2 direction = normalize(circleLightCenters[i] - position) / squareToAspectRatioTimes2;
|
||||||
lighting += lightColorAtPosition * shadowTransparency(
|
vec3 shadowed = lightColorAtPosition * shadowTransparency(
|
||||||
startingDistance,
|
startingDistance,
|
||||||
lightCenterDistance,
|
lightCenterDistance,
|
||||||
direction
|
direction
|
||||||
);
|
);
|
||||||
|
|
||||||
lightingInside += lightColorAtPosition;
|
lightSum += shadowed;
|
||||||
|
lightMax = max(lightMax, shadowed);
|
||||||
|
lightSumInside += lightColorAtPosition;
|
||||||
|
lightMaxInside = max(lightMaxInside, lightColorAtPosition);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -107,17 +120,24 @@ void main() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
lighting += lightColorAtPosition * shadowTransparency(
|
vec3 shadowed = lightColorAtPosition * shadowTransparency(
|
||||||
startingDistance,
|
startingDistance,
|
||||||
lightCenterDistance,
|
lightCenterDistance,
|
||||||
direction
|
direction
|
||||||
);
|
);
|
||||||
|
|
||||||
lightingInside += lightColorAtPosition;
|
lightSum += shadowed;
|
||||||
|
lightMax = max(lightMax, shadowed);
|
||||||
|
lightSumInside += lightColorAtPosition;
|
||||||
|
lightMaxInside = max(lightMaxInside, lightColorAtPosition);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#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 outsideColor = {backgroundColor}.rgb * lighting;
|
||||||
vec3 insideColor = colorAtPosition * lightingInside * INTENSITY_INSIDE_RATIO;
|
vec3 insideColor = colorAtPosition * lightingInside * INTENSITY_INSIDE_RATIO;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,9 @@ precision lowp float;
|
||||||
#define INTENSITY_INSIDE_RATIO {intensityInsideRatio}
|
#define INTENSITY_INSIDE_RATIO {intensityInsideRatio}
|
||||||
#define SHADOW_TRACE_COUNT {shadowTraceCount}
|
#define SHADOW_TRACE_COUNT {shadowTraceCount}
|
||||||
#define FLOAT_LINEAR_ENABLED {floatLinearEnabled}
|
#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}
|
{macroDefinitions}
|
||||||
|
|
||||||
|
|
@ -87,8 +90,15 @@ void main() {
|
||||||
|
|
||||||
float startingDistance = getDistance(uvCoordinates);
|
float startingDistance = getDistance(uvCoordinates);
|
||||||
|
|
||||||
vec3 lighting = ambientLight;
|
// Each light contributes to two accumulators: an additive sum (overlaps
|
||||||
vec3 lightingInside = ambientLight;
|
// 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
|
#ifdef CIRCLE_LIGHT_COUNT
|
||||||
#if CIRCLE_LIGHT_COUNT > 0
|
#if CIRCLE_LIGHT_COUNT > 0
|
||||||
|
|
@ -97,13 +107,16 @@ void main() {
|
||||||
vec3 lightColorAtPosition = colorInPosition(i, lightCenterDistance);
|
vec3 lightColorAtPosition = colorInPosition(i, lightCenterDistance);
|
||||||
|
|
||||||
vec2 direction = normalize(circleLightCenters[i] - position) / squareToAspectRatioTimes2;
|
vec2 direction = normalize(circleLightCenters[i] - position) / squareToAspectRatioTimes2;
|
||||||
lighting += lightColorAtPosition * shadowTransparency(
|
vec3 shadowed = lightColorAtPosition * shadowTransparency(
|
||||||
startingDistance,
|
startingDistance,
|
||||||
lightCenterDistance,
|
lightCenterDistance,
|
||||||
direction
|
direction
|
||||||
);
|
);
|
||||||
|
|
||||||
lightingInside += lightColorAtPosition;
|
lightSum += shadowed;
|
||||||
|
lightMax = max(lightMax, shadowed);
|
||||||
|
lightSumInside += lightColorAtPosition;
|
||||||
|
lightMaxInside = max(lightMaxInside, lightColorAtPosition);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -130,17 +143,24 @@ void main() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
lighting += lightColorAtPosition * shadowTransparency(
|
vec3 shadowed = lightColorAtPosition * shadowTransparency(
|
||||||
startingDistance,
|
startingDistance,
|
||||||
lightCenterDistance,
|
lightCenterDistance,
|
||||||
direction
|
direction
|
||||||
);
|
);
|
||||||
|
|
||||||
lightingInside += lightColorAtPosition;
|
lightSum += shadowed;
|
||||||
|
lightMax = max(lightMax, shadowed);
|
||||||
|
lightSumInside += lightColorAtPosition;
|
||||||
|
lightMaxInside = max(lightMaxInside, lightColorAtPosition);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#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 outsideColor = {backgroundColor}.rgb * lighting;
|
||||||
vec3 insideColor = colorAtPosition * lightingInside * INTENSITY_INSIDE_RATIO;
|
vec3 insideColor = colorAtPosition * lightingInside * INTENSITY_INSIDE_RATIO;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue