Skip to content

Simplify lighting structs in shaders #76

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Documentation:

Internals:
- Update minify to version 8
- Simplify lighting structs in shaders (#76)

Bug fixes:
- Correctly calculate the bounding box for primitives with scaled coordinates and radius bigger than the bounding box (#60)
Expand Down
70 changes: 17 additions & 53 deletions src/primitives/cuboid.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,69 +155,39 @@ export default function ({ color, coords, edgeForm = {}, opacity = 1 }, extent)
vec3 direction;
};

float getDistanceAttenuation(const in float lightDistance, const in float cutoffDistance, const in float decayExponent) {
if (cutoffDistance > 0.0 && decayExponent > 0.0) {
return pow(saturate(-lightDistance / cutoffDistance + 1.0), decayExponent);
}
return 1.0;
}

#if NUM_DIR_LIGHTS > 0
struct DirectionalLight {
vec3 direction;
vec3 color;
};

uniform DirectionalLight directionalLights[NUM_DIR_LIGHTS];

void getDirectionalLightInfo(const in DirectionalLight directionalLight, out IncidentLight light) {
light.color = directionalLight.color;
light.direction = directionalLight.direction;
}
uniform IncidentLight directionalLights[NUM_DIR_LIGHTS];
#endif
#if NUM_POINT_LIGHTS > 0
struct PointLight {
vec3 position;
vec3 color;
float distance;
float decay;
vec3 position;
};

uniform PointLight pointLights[NUM_POINT_LIGHTS];

void getPointLightInfo(const in PointLight pointLight, out IncidentLight light) {
vec3 lVector = pointLight.position + vViewPosition;

light.direction = normalize(lVector);
light.color = pointLight.color + getDistanceAttenuation(length(lVector), pointLight.distance, pointLight.decay);
light.direction = normalize(pointLight.position + vViewPosition);
light.color = pointLight.color + 1.0;
}
#endif
#if NUM_SPOT_LIGHTS > 0
struct SpotLight {
vec3 position;
vec3 direction;
vec3 color;
float distance;
float decay;
float coneCos;
float penumbraCos;
vec3 direction;
vec3 position;
};

float getSpotAttenuation(const in float coneCosine, const in float penumbraCosine, const in float angleCosine) {
return smoothstep(coneCosine, penumbraCosine, angleCosine);
}

uniform SpotLight spotLights[NUM_SPOT_LIGHTS];

void getSpotLightInfo(const in SpotLight spotLight, out IncidentLight light) {
vec3 lVector = spotLight.position + vViewPosition;
light.direction = normalize(lVector);
light.direction = normalize(spotLight.position + vViewPosition);

float angleCos = dot(light.direction, spotLight.direction);
float spotAttenuation = getSpotAttenuation(spotLight.coneCos, spotLight.penumbraCos, angleCos);

if (spotAttenuation > 0.0) {
light.color = spotLight.color * spotAttenuation + getDistanceAttenuation(length(lVector), spotLight.distance, spotLight.decay);
if (angleCos > 0.0) {
light.color = spotLight.color * angleCos + 1.0;
} else {
light.color = vec3(0.0);
}
Expand Down Expand Up @@ -247,27 +217,21 @@ export default function ({ color, coords, edgeForm = {}, opacity = 1 }, extent)
vec3 reflectedLight = vec3(0.0);

IncidentLight directLight;

#if NUM_DIR_LIGHTS > 0
for (int i = 0; i < NUM_DIR_LIGHTS; i++) {
reflectedLight += RE_Direct(directionalLights[i], normal, diffuseColor);
}
#endif
#if NUM_POINT_LIGHTS > 0
PointLight pointLight;
for (int i = 0; i < NUM_POINT_LIGHTS; i++) {
pointLight = pointLights[i];
getPointLightInfo(pointLight, directLight);
getPointLightInfo(pointLights[i], directLight);
reflectedLight += RE_Direct(directLight, normal, diffuseColor);
}
#endif
#if NUM_SPOT_LIGHTS > 0
SpotLight spotLight;
for (int i = 0; i < NUM_SPOT_LIGHTS; i++) {
spotLight = spotLights[i];
getSpotLightInfo(spotLight, directLight);
reflectedLight += RE_Direct(directLight, normal, diffuseColor);
}
#endif
#if NUM_DIR_LIGHTS > 0
DirectionalLight directionalLight;
for (int i = 0; i < NUM_DIR_LIGHTS; i++) {
directionalLight = directionalLights[i];
getDirectionalLightInfo(directionalLight, directLight);
getSpotLightInfo(spotLights[i], directLight);
reflectedLight += RE_Direct(directLight, normal, diffuseColor);
}
#endif
Expand Down
73 changes: 15 additions & 58 deletions src/primitives/polygon.js
Original file line number Diff line number Diff line change
Expand Up @@ -207,71 +207,35 @@ export default function ({ color, coords, edgeForm = {}, opacity = 1, vertexNorm
vec3 direction;
};

float getDistanceAttenuation(const in float lightDistance, const in float cutoffDistance, const in float decayExponent) {
if (cutoffDistance > 0.0 && decayExponent > 0.0) {
return pow(saturate(-lightDistance / cutoffDistance + 1.0), decayExponent);
}
return 1.0;
}

float getSpotAttenuation(const in float coneCosine, const in float penumbraCosine, const in float angleCosine) {
return smoothstep(coneCosine, penumbraCosine, angleCosine);
}

#if NUM_DIR_LIGHTS > 0
struct DirectionalLight {
vec3 direction;
vec3 color;
};

uniform DirectionalLight directionalLights[NUM_DIR_LIGHTS];

void getDirectionalLightInfo(const in DirectionalLight directionalLight, out IncidentLight light) {
light.color = directionalLight.color;
light.direction = directionalLight.direction;
}
uniform IncidentLight directionalLights[NUM_DIR_LIGHTS];
#endif
#if NUM_POINT_LIGHTS > 0
struct PointLight {
vec3 position;
vec3 color;
float distance;
float decay;
vec3 position;
};

uniform PointLight pointLights[NUM_POINT_LIGHTS];

void getPointLightInfo(const in PointLight pointLight, out IncidentLight light) {
vec3 lVector = pointLight.position + vViewPosition;
light.direction = normalize(lVector);
float lightDistance = length(lVector);
light.color = pointLight.color * getDistanceAttenuation(lightDistance, pointLight.distance, pointLight.decay);
light.direction = normalize(pointLight.position + vViewPosition);
light.color = pointLight.color;
}
#endif
#if NUM_SPOT_LIGHTS > 0
struct SpotLight {
vec3 position;
vec3 direction;
vec3 color;
float distance;
float decay;
float coneCos;
float penumbraCos;
vec3 direction;
vec3 position;
};

uniform SpotLight spotLights[NUM_SPOT_LIGHTS];

void getSpotLightInfo(const in SpotLight spotLight, out IncidentLight light) {
vec3 lVector = spotLight.position + vViewPosition;
light.direction = normalize(lVector);
float angleCos = dot(light.direction, spotLight.direction);
float spotAttenuation = getSpotAttenuation(spotLight.coneCos, spotLight.penumbraCos, angleCos);
if (spotAttenuation > 0.0) {
float lightDistance = length(lVector);
light.color = spotLight.color * spotAttenuation * getDistanceAttenuation(lightDistance, spotLight.distance, spotLight.decay);
} else {
light.color = vec3(0.0);
}
light.direction = normalize(spotLight.position + vViewPosition);
light.color = spotLight.color * max(dot(light.direction, spotLight.direction), 0.0);
}
#endif

Expand All @@ -289,27 +253,20 @@ export default function ({ color, coords, edgeForm = {}, opacity = 1, vertexNorm

IncidentLight directLight;

#if NUM_DIR_LIGHTS > 0
for (int i = 0; i < NUM_DIR_LIGHTS; i++) {
reflectedLight += RE_Direct(directionalLights[i], normal);
}
#endif
#if NUM_POINT_LIGHTS > 0
PointLight pointLight;
for (int i = 0; i < NUM_POINT_LIGHTS; i++) {
pointLight = pointLights[i];
getPointLightInfo(pointLight, directLight);
getPointLightInfo(pointLights[i], directLight);
reflectedLight += RE_Direct(directLight, normal);
}
#endif
#if NUM_SPOT_LIGHTS > 0
SpotLight spotLight;
for (int i = 0; i < NUM_SPOT_LIGHTS; i++) {
spotLight = spotLights[i];
getSpotLightInfo(spotLight, directLight);
reflectedLight += RE_Direct(directLight, normal);
}
#endif
#if NUM_DIR_LIGHTS > 0
DirectionalLight directionalLight;
for (int i = 0; i < NUM_DIR_LIGHTS; i++) {
directionalLight = directionalLights[i];
getDirectionalLightInfo(directionalLight, directLight);
getSpotLightInfo(spotLight, spotLights[i]);
reflectedLight += RE_Direct(directLight, normal);
}
#endif
Expand Down
67 changes: 13 additions & 54 deletions src/primitives/sphere.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,74 +60,35 @@ export default function ({ color, coords, opacity = 1, radius = 1 }, extent) {
vec3 normal;
};

float getDistanceAttenuation(const in float lightDistance, const in float cutoffDistance, const in float decayExponent) {
if (cutoffDistance > 0.0 && decayExponent > 0.0) {
return pow(saturate(- lightDistance / cutoffDistance + 1.0), decayExponent);
}
return 1.0;
}

#if NUM_DIR_LIGHTS > 0
struct DirectionalLight {
vec3 direction;
vec3 color;
};

uniform DirectionalLight directionalLights[NUM_DIR_LIGHTS];

void getDirectionalLightInfo(const in DirectionalLight directionalLight, out IncidentLight light) {
light.color = directionalLight.color;
light.direction = directionalLight.direction;
}
uniform IncidentLight directionalLights[NUM_DIR_LIGHTS];
#endif
#if NUM_POINT_LIGHTS > 0
struct PointLight {
vec3 position;
vec3 color;
float distance;
float decay;
vec3 position;
};

uniform PointLight pointLights[NUM_POINT_LIGHTS];

void getPointLightInfo(const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight light) {
vec3 lVector = pointLight.position - geometry.position;

light.direction = normalize(lVector);
light.color = pointLight.color * getDistanceAttenuation(length(lVector), pointLight.distance, pointLight.decay);
light.direction = normalize(pointLight.position - geometry.position);
light.color = pointLight.color;
}
#endif
#if NUM_SPOT_LIGHTS > 0
struct SpotLight {
vec3 position;
vec3 direction;
vec3 color;
float distance;
float decay;
float coneCos;
float penumbraCos;
vec3 direction;
vec3 position;
};

uniform SpotLight spotLights[NUM_SPOT_LIGHTS];

float getSpotAttenuation(const in float coneCosine, const in float penumbraCosine, const in float angleCosine) {
return smoothstep(coneCosine, penumbraCosine, angleCosine);
}

void getSpotLightInfo(const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight light) {
vec3 lVector = spotLight.position - geometry.position;

light.direction = normalize(lVector);

float angleCos = dot(light.direction, spotLight.direction);

float spotAttenuation = getSpotAttenuation(spotLight.coneCos, spotLight.penumbraCos, angleCos);

if (spotAttenuation > 0.0) {
light.color = spotLight.color * spotAttenuation * getDistanceAttenuation(length(lVector), spotLight.distance, spotLight.decay);
} else {
light.color = vec3(0.0);
}
light.direction = normalize(spotLight.position - geometry.position);
light.color = spotLight.color * max(dot(light.direction, spotLight.direction), 0.0);
}
#endif

Expand All @@ -145,6 +106,11 @@ export default function ({ color, coords, opacity = 1, radius = 1 }, extent) {

IncidentLight directLight;

#if NUM_DIR_LIGHTS > 0
for (int i = 0; i < NUM_DIR_LIGHTS; i++) {
light += saturate(dot(geometry.normal, directionalLights[i].direction)) * directionalLights[i].color;
}
#endif
#if NUM_POINT_LIGHTS > 0
for (int i = 0; i < NUM_POINT_LIGHTS; i++) {
getPointLightInfo(pointLights[i], geometry, directLight);
Expand All @@ -159,13 +125,6 @@ export default function ({ color, coords, opacity = 1, radius = 1 }, extent) {
light += saturate(dot(geometry.normal, directLight.direction)) * directLight.color;
}
#endif
#if NUM_DIR_LIGHTS > 0
for (int i = 0; i < NUM_DIR_LIGHTS; i++) {
getDirectionalLightInfo(directionalLights[i], directLight);

light += saturate(dot(geometry.normal, directLight.direction)) * directLight.color;
}
#endif

vColor = vec4(light * diffuse * RECIPROCAL_PI, opacity);
}
Expand Down
Loading