Do some more refactoring
This commit is contained in:
parent
c892ca2d01
commit
24cc572e47
29 changed files with 191 additions and 152 deletions
|
|
@ -7,58 +7,43 @@ precision mediump float;
|
|||
#define MIN_STEP 1.0
|
||||
#define AMBIENT_LIGHT vec3(0.15)
|
||||
|
||||
#define LIGHT_COUNT {lightCount}
|
||||
#define CIRCLE_LIGHT_COUNT {circleLightCount}
|
||||
#define POINT_LIGHT_COUNT {pointLightCount}
|
||||
#define DISTANCE_SCALE {distanceScale}
|
||||
#define DISTANCE_OFFSET {distanceOffset}
|
||||
#define EDGE_SMOOTHING {edgeSmoothing}
|
||||
|
||||
#if LIGHT_COUNT > 0
|
||||
uniform struct Light {
|
||||
uniform sampler2D distanceTexture;
|
||||
uniform vec2 viewBoxSize;
|
||||
|
||||
float getDistance(in vec2 target, out vec3 color) {
|
||||
vec4 values = texture(distanceTexture, target);
|
||||
color = values.rgb;
|
||||
return (values.w - DISTANCE_OFFSET) * DISTANCE_SCALE;
|
||||
}
|
||||
|
||||
float getDistance(in vec2 target) {
|
||||
return (texture(distanceTexture, target).w - DISTANCE_OFFSET) * DISTANCE_SCALE;
|
||||
}
|
||||
|
||||
#if CIRCLE_LIGHT_COUNT > 0
|
||||
uniform struct CircleLight {
|
||||
vec2 center;
|
||||
float radius;
|
||||
vec3 value;
|
||||
}[LIGHT_COUNT] lights;
|
||||
}[CIRCLE_LIGHT_COUNT] circleLights;
|
||||
|
||||
uniform sampler2D distanceTexture;
|
||||
uniform vec2 viewBoxSize;
|
||||
in vec2[CIRCLE_LIGHT_COUNT] circleLightDirections;
|
||||
#endif
|
||||
|
||||
in vec2[LIGHT_COUNT] directions;
|
||||
#if POINT_LIGHT_COUNT > 0
|
||||
uniform struct PointLight {
|
||||
vec2 center;
|
||||
float radius;
|
||||
vec3 value;
|
||||
}[POINT_LIGHT_COUNT] pointLights;
|
||||
|
||||
float getDistance(in vec2 target, out vec3 color) {
|
||||
vec4 values = texture(distanceTexture, target);
|
||||
color = values.rgb;
|
||||
return values.w * DISTANCE_SCALE;
|
||||
}
|
||||
|
||||
float getDistance(in vec2 target) {
|
||||
return texture(distanceTexture, target).w * DISTANCE_SCALE;
|
||||
}
|
||||
|
||||
float getFractionOfLightArriving(
|
||||
in vec2 target,
|
||||
in vec2 direction,
|
||||
in float startingDistance,
|
||||
in float lightDistance,
|
||||
in float lightRadius
|
||||
) {
|
||||
float q = 1.0;
|
||||
float rayLength = startingDistance;
|
||||
float movingAverageMeanDistance = startingDistance;
|
||||
|
||||
direction /= viewBoxSize;
|
||||
|
||||
for (int j = 0; j < 48; j++) {
|
||||
float minDistance = getDistance(target + direction * rayLength);
|
||||
movingAverageMeanDistance = movingAverageMeanDistance / 2.0 + minDistance / 2.0;
|
||||
q = min(q, movingAverageMeanDistance / rayLength);
|
||||
|
||||
rayLength += max(MIN_STEP, minDistance);
|
||||
if (rayLength > lightDistance) {
|
||||
return clamp(q * (lightDistance + lightRadius) / lightRadius, 0.0, 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
in vec2[POINT_LIGHT_COUNT] pointLightDirections;
|
||||
#endif
|
||||
|
||||
in vec2 worldCoordinates;
|
||||
|
|
@ -66,35 +51,65 @@ in vec2 uvCoordinates;
|
|||
out vec4 fragmentColor;
|
||||
|
||||
void main() {
|
||||
#if LIGHT_COUNT > 0
|
||||
vec3 colorAtPosition;
|
||||
float startingDistance = getDistance(uvCoordinates, colorAtPosition);
|
||||
vec3 ligthing = AMBIENT_LIGHT;
|
||||
|
||||
vec3 colorAtPosition;
|
||||
float startingDistance = getDistance(uvCoordinates, colorAtPosition);
|
||||
#if CIRCLE_LIGHT_COUNT > 0
|
||||
for (int i = 0; i < CIRCLE_LIGHT_COUNT; i++) {
|
||||
float lightCenterDistance = distance(circleLights[i].center, worldCoordinates);
|
||||
vec3 lightColorAtPosition = circleLights[i].value / pow(lightCenterDistance / LIGHT_DROP + 1.0, 2.0);
|
||||
|
||||
vec3 ligthing = vec3(0.0);
|
||||
|
||||
for (int i = 0; i < LIGHT_COUNT; i++) {
|
||||
Light light = lights[i];
|
||||
float lightDistance = distance(light.center, worldCoordinates);
|
||||
float q = INFINITY;
|
||||
float rayLength = startingDistance;
|
||||
float exponentialDecayDistance = rayLength;
|
||||
vec2 direction = normalize(circleLightDirections[i]) / viewBoxSize;
|
||||
|
||||
float r = (lightDistance + light.radius) / LIGHT_DROP + 1.0;
|
||||
vec3 lightColorAtPosition = light.value / (r * r);
|
||||
for (int j = 0; j < 48; j++) {
|
||||
if (rayLength > lightCenterDistance) {
|
||||
ligthing += lightColorAtPosition * clamp(
|
||||
q / circleLights[i].radius * (lightCenterDistance + 1.0), 0.0, 1.0
|
||||
) * step(circleLights[i].radius, getDistance(uvCoordinates + direction * lightCenterDistance));
|
||||
break;
|
||||
}
|
||||
|
||||
float fractionOfLightArriving = getFractionOfLightArriving(
|
||||
uvCoordinates, normalize(directions[i]), startingDistance,
|
||||
lightDistance, light.radius
|
||||
float minDistance = getDistance(uvCoordinates + direction * rayLength);
|
||||
exponentialDecayDistance = (exponentialDecayDistance + minDistance) / 2.0;
|
||||
q = min(q, exponentialDecayDistance / rayLength);
|
||||
rayLength += max(MIN_STEP, minDistance);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if POINT_LIGHT_COUNT > 0
|
||||
for (int i = 0; i < POINT_LIGHT_COUNT; i++) {
|
||||
float lightDistance = distance(pointLights[i].center, worldCoordinates);
|
||||
|
||||
vec3 lightColorAtPosition = mix(
|
||||
pointLights[i].value,
|
||||
vec3(0.0),
|
||||
sqrt(clamp(lightDistance / pointLights[i].radius, 0.0, 1.0))
|
||||
);
|
||||
|
||||
ligthing += lightColorAtPosition * fractionOfLightArriving;
|
||||
|
||||
float q = INFINITY;
|
||||
float rayLength = startingDistance;
|
||||
float exponentialDecayDistance = startingDistance;
|
||||
vec2 direction = normalize(pointLightDirections[i]) / viewBoxSize;
|
||||
|
||||
for (int j = 0; j < 48; j++) {
|
||||
if (rayLength > lightDistance) {
|
||||
ligthing += lightColorAtPosition * step(0.0, q);
|
||||
break;
|
||||
}
|
||||
|
||||
float minDistance = getDistance(uvCoordinates + direction * rayLength);
|
||||
exponentialDecayDistance = (exponentialDecayDistance + minDistance) / 2.0;
|
||||
q = min(q, exponentialDecayDistance);
|
||||
rayLength += max(MIN_STEP, minDistance);
|
||||
}
|
||||
}
|
||||
|
||||
fragmentColor = vec4(
|
||||
colorAtPosition * (AMBIENT_LIGHT +
|
||||
step(EDGE_SMOOTHING / 2.0, clamp(startingDistance, 0.0, EDGE_SMOOTHING)) * ligthing),
|
||||
1.0
|
||||
);
|
||||
|
||||
#else
|
||||
fragmentColor = vec4(1.0);
|
||||
#endif
|
||||
|
||||
fragmentColor = vec4(colorAtPosition * ligthing * clamp(startingDistance, 0.0, 1.0), 1.0);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue