Browse Source

wip, lighting improvements

- set light direction
- set light color
- set ambient color
Alexander Rose 3 years ago
parent
commit
e5dcc8e54f

+ 4 - 3
src/mol-gl/renderable/schema.ts

@@ -141,12 +141,13 @@ export const GlobalUniformSchema = {
     uClipObjectRotation: UniformSpec('v4[]'),
     uClipObjectScale: UniformSpec('v3[]'),
 
+    uLightDirection: UniformSpec('v3'),
+    uLightColor: UniformSpec('v3'),
+    uAmbientColor: UniformSpec('v3'),
+
     // all the following could in principle be per object
     // as a kind of 'material' parameter set
     // would need to test performance implications
-    uLightIntensity: UniformSpec('f'),
-    uAmbientIntensity: UniformSpec('f'),
-
     uMetalness: UniformSpec('f'),
     uRoughness: UniformSpec('f'),
     uReflectivity: UniformSpec('f'),

+ 49 - 5
src/mol-gl/renderer.ts

@@ -85,6 +85,11 @@ export const RendererParams = {
 
     xrayEdgeFalloff: PD.Numeric(1, { min: 0.0, max: 3.0, step: 0.1 }),
 
+    lightInclination: PD.Numeric(180, { min: 0, max: 180, step: 1 }),
+    lightAzimuth: PD.Numeric(0, { min: 0, max: 360, step: 1 }),
+    lightColor: PD.Color(Color.fromNormalizedRgb(1.0, 1.0, 1.0)),
+    ambientColor: PD.Color(Color.fromNormalizedRgb(1.0, 1.0, 1.0)),
+
     style: PD.MappedStatic('matte', {
         custom: PD.Group({
             lightIntensity: PD.Numeric(0.6, { min: 0.0, max: 1.0, step: 0.01 }),
@@ -220,6 +225,14 @@ namespace Renderer {
         const cameraDir = Vec3();
         const viewOffset = Vec2();
 
+        const lightDirection = Vec3();
+        Vec3.directionFromSpherical(lightDirection, degToRad(p.lightInclination), degToRad(p.lightAzimuth), 1);
+
+        const lightColor = Color.toVec3Normalized(Vec3(), p.lightColor);
+        Vec3.scale(lightColor, lightColor, style.lightIntensity);
+        const ambientColor = Color.toVec3Normalized(Vec3(), p.ambientColor);
+        Vec3.scale(ambientColor, ambientColor, style.ambientIntensity);
+
         const globalUniforms: GlobalUniformValues = {
             uModel: ValueCell.create(Mat4.identity()),
             uView: ValueCell.create(view),
@@ -257,10 +270,11 @@ namespace Renderer {
             uClipObjectRotation: ValueCell.create(clip.objects.rotation),
             uClipObjectScale: ValueCell.create(clip.objects.scale),
 
-            // the following are general 'material' uniforms
-            uLightIntensity: ValueCell.create(style.lightIntensity),
-            uAmbientIntensity: ValueCell.create(style.ambientIntensity),
+            uLightDirection: ValueCell.create(lightDirection),
+            uLightColor: ValueCell.create(lightColor),
+            uAmbientColor: ValueCell.create(ambientColor),
 
+            // the following 3 are general 'material' uniforms
             uMetalness: ValueCell.create(style.metalness),
             uRoughness: ValueCell.create(style.roughness),
             uReflectivity: ValueCell.create(style.reflectivity),
@@ -682,11 +696,41 @@ namespace Renderer {
                     ValueCell.update(globalUniforms.uXrayEdgeFalloff, p.xrayEdgeFalloff);
                 }
 
+                if (props.lightInclination !== undefined && props.lightInclination !== p.lightInclination) {
+                    p.lightInclination = props.lightInclination;
+                    Vec3.directionFromSpherical(lightDirection, degToRad(p.lightInclination), degToRad(p.lightAzimuth), 1);
+                    ValueCell.update(globalUniforms.uLightDirection, lightDirection);
+                }
+                if (props.lightAzimuth !== undefined && props.lightAzimuth !== p.lightAzimuth) {
+                    p.lightAzimuth = props.lightAzimuth;
+                    Vec3.directionFromSpherical(lightDirection, degToRad(p.lightInclination), degToRad(p.lightAzimuth), 1);
+                    ValueCell.update(globalUniforms.uLightDirection, lightDirection);
+                }
+
+                if (props.lightColor !== undefined && props.lightColor !== p.lightColor) {
+                    p.lightColor = props.lightColor;
+                    Color.toVec3Normalized(lightColor, p.lightColor);
+                    Vec3.scale(lightColor, lightColor, style.lightIntensity);
+                    ValueCell.update(globalUniforms.uLightColor, lightColor);
+                }
+                if (props.ambientColor !== undefined && props.ambientColor !== p.ambientColor) {
+                    p.ambientColor = props.ambientColor;
+                    Color.toVec3Normalized(ambientColor, p.ambientColor);
+                    Vec3.scale(ambientColor, ambientColor, style.ambientIntensity);
+                    ValueCell.update(globalUniforms.uAmbientColor, ambientColor);
+                }
+
                 if (props.style !== undefined) {
                     p.style = props.style;
                     Object.assign(style, getStyle(props.style));
-                    ValueCell.updateIfChanged(globalUniforms.uLightIntensity, style.lightIntensity);
-                    ValueCell.updateIfChanged(globalUniforms.uAmbientIntensity, style.ambientIntensity);
+
+                    Color.toVec3Normalized(lightColor, p.lightColor);
+                    Vec3.scale(lightColor, lightColor, style.lightIntensity);
+                    ValueCell.update(globalUniforms.uLightColor, lightColor);
+                    Color.toVec3Normalized(ambientColor, p.ambientColor);
+                    Vec3.scale(ambientColor, ambientColor, style.ambientIntensity);
+                    ValueCell.update(globalUniforms.uAmbientColor, ambientColor);
+
                     ValueCell.updateIfChanged(globalUniforms.uMetalness, style.metalness);
                     ValueCell.updateIfChanged(globalUniforms.uRoughness, style.roughness);
                     ValueCell.updateIfChanged(globalUniforms.uReflectivity, style.reflectivity);

+ 4 - 4
src/mol-gl/shader/chunks/apply-light-color.glsl.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2017-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2017-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  *
@@ -36,12 +36,12 @@ geometry.normal = normal;
 geometry.viewDir = normalize(vViewPosition);
 
 IncidentLight directLight;
-directLight.direction = vec3(0.0, 0.0, -1.0);
-directLight.color = vec3(uLightIntensity);
+directLight.direction = uLightDirection;
+directLight.color = uLightColor;
 
 RE_Direct_Physical(directLight, geometry, physicalMaterial, reflectedLight);
 
-vec3 irradiance = vec3(uAmbientIntensity) * PI;
+vec3 irradiance = uAmbientColor * PI;
 RE_IndirectDiffuse_Physical(irradiance, geometry, physicalMaterial, reflectedLight);
 
 vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular;

+ 5 - 3
src/mol-gl/shader/chunks/light-frag-params.glsl.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2017-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2017-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  *
@@ -8,8 +8,10 @@
  */
 
 export const light_frag_params = `
-uniform float uLightIntensity;
-uniform float uAmbientIntensity;
+uniform vec3 uLightDirection;
+uniform vec3 uLightColor;
+uniform vec3 uAmbientColor;
+
 uniform float uReflectivity;
 uniform float uMetalness;
 uniform float uRoughness;

+ 13 - 0
src/mol-math/linear-algebra/3d/vec3.ts

@@ -504,6 +504,19 @@ namespace Vec3 {
         return dot(tmp_dh_cb, tmp_dh_cross) > 0 ? _angle : -_angle;
     }
 
+    /**
+     * @param inclination in radians [0, PI]
+     * @param azimuth in radians [0, 2 * PI]
+     * @param radius [0, +Inf]
+     */
+    export function directionFromSpherical(out: Vec3, inclination: number, azimuth: number, radius: number): Vec3 {
+        return Vec3.set(out,
+            radius * Math.cos(azimuth) * Math.sin(inclination),
+            radius * Math.sin(azimuth) * Math.sin(inclination),
+            radius * Math.cos(inclination)
+        );
+    }
+
     /**
      * Returns whether or not the vectors have exactly the same elements in the same position (when compared with ===)
      */