From e5dcc8e54f2907ff1a3f6fa5a70c93dd79546c9c Mon Sep 17 00:00:00 2001 From: Alexander Rose <alexander.rose@weirdbyte.de> Date: Sun, 31 Oct 2021 14:59:19 -0700 Subject: [PATCH] wip, lighting improvements - set light direction - set light color - set ambient color --- src/mol-gl/renderable/schema.ts | 7 +-- src/mol-gl/renderer.ts | 54 +++++++++++++++++-- .../shader/chunks/apply-light-color.glsl.ts | 8 +-- .../shader/chunks/light-frag-params.glsl.ts | 8 +-- src/mol-math/linear-algebra/3d/vec3.ts | 13 +++++ 5 files changed, 75 insertions(+), 15 deletions(-) diff --git a/src/mol-gl/renderable/schema.ts b/src/mol-gl/renderable/schema.ts index 2b2bf6a5e..11e8fe217 100644 --- a/src/mol-gl/renderable/schema.ts +++ b/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'), diff --git a/src/mol-gl/renderer.ts b/src/mol-gl/renderer.ts index 0cdb2112f..01df14c7a 100644 --- a/src/mol-gl/renderer.ts +++ b/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); diff --git a/src/mol-gl/shader/chunks/apply-light-color.glsl.ts b/src/mol-gl/shader/chunks/apply-light-color.glsl.ts index d398e4d15..29b0f1f3f 100644 --- a/src/mol-gl/shader/chunks/apply-light-color.glsl.ts +++ b/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; diff --git a/src/mol-gl/shader/chunks/light-frag-params.glsl.ts b/src/mol-gl/shader/chunks/light-frag-params.glsl.ts index bb6e9a999..dad65065a 100644 --- a/src/mol-gl/shader/chunks/light-frag-params.glsl.ts +++ b/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; diff --git a/src/mol-math/linear-algebra/3d/vec3.ts b/src/mol-math/linear-algebra/3d/vec3.ts index c0bf8b04f..5c5e39f21 100644 --- a/src/mol-math/linear-algebra/3d/vec3.ts +++ b/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 ===) */ -- GitLab