Skip to content

Commit

Permalink
Merge branch '#865-linear-color-space' into #865-upgrade-three-js
Browse files Browse the repository at this point in the history
  • Loading branch information
ppillot committed Dec 11, 2023
2 parents 8627b6c + b4cee3f commit c9cc1d1
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 90 deletions.
4 changes: 2 additions & 2 deletions examples/js/gui.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,9 @@ NGL.Preferences = function (id, defaultParams) {
cameraFov: 40,
cameraType: 'perspective',
lightColor: 0xdddddd,
lightIntensity: 1.0,
lightIntensity: 3.14,
ambientColor: 0xdddddd,
ambientIntensity: 0.2,
ambientIntensity: 0.63,
hoverTimeout: 0
}

Expand Down
30 changes: 3 additions & 27 deletions src/color/colormaker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,6 @@ import AtomProxy from '../proxy/atom-proxy'
import BondProxy from '../proxy/bond-proxy'

export type ColorMode = 'rgb'|'hsv'|'hsl'|'hsi'|'lab'|'hcl'
export type ColorSpace = 'sRGB' | 'linear'

/**
* Internal color space for all colors (global).
* Colors are always specified as sRGB; if this is set to
* 'linear' then colors get linearized when used internally
* as vertex or texture colors.
* @see setColorSpace/getColorSpace.
*/
var colorSpace: ColorSpace = 'sRGB' // default: don't linearize

/** Set the global internal color space for colormakers */
export function setColorSpace(space: ColorSpace) {
colorSpace = space
}

/** Get the global internal color space for colormakers */
export function getColorSpace() {
return colorSpace
}

export const ScaleDefaultParameters = {
scale: 'uniform' as string|string[],
Expand Down Expand Up @@ -73,13 +53,9 @@ export function manageColor<T extends {parameters: ColormakerParameters}>
const originalMethod = descriptor.value
const linearize: colorFuncType = function (this: T, value: any, fromTo?: boolean) {
let result = originalMethod!.bind(this, value, fromTo)()
if (colorSpace == 'linear') {
tmpColor.set(result)
tmpColor.convertSRGBToLinear()
return tmpColor.getHex()
} else {
return result
}
tmpColor.set(result)
tmpColor.convertSRGBToLinear()
return tmpColor.getHex()
}
descriptor.value = linearize
return descriptor
Expand Down
1 change: 1 addition & 0 deletions src/shader/Quad.frag
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ void main() {

vec4 foreground = texture2D( tForeground, vUv );
gl_FragColor = foreground * scale;
#include colorspace_fragment

}
11 changes: 6 additions & 5 deletions src/stage/stage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import Surface from '../surface/surface'
import Volume from '../surface/volume'
import Shape from '../geometry/shape'
import Script from '../script'
import { GenericColor } from '../types'

function matchName (name: string|RegExp, object: { name: string }) {
if (name instanceof RegExp) {
Expand Down Expand Up @@ -123,7 +124,7 @@ export const StageDefaultParameters = {
quality: 'medium' as RenderQualityType,
workerDefault: true,
sampleLevel: 0,
backgroundColor: 'black' as string|number,
backgroundColor: 'black' as GenericColor,
rotateSpeed: 2.0,
zoomSpeed: 1.2,
panSpeed: 1.0,
Expand All @@ -137,10 +138,10 @@ export const StageDefaultParameters = {
cameraFov: 40,
cameraEyeSep: 0.3,
cameraType: 'perspective' as 'perspective'|'orthographic'|'stereo',
lightColor: 0xdddddd as string|number,
lightIntensity: 1.0,
ambientColor: 0xdddddd as string|number,
ambientIntensity: 0.2,
lightColor: 0xdddddd as GenericColor,
lightIntensity: 3.14,
ambientColor: 0xdddddd as GenericColor,
ambientIntensity: 0.63,
hoverTimeout: 0,
tooltip: true,
mousePreset: 'default' as MouseControlPreset
Expand Down
66 changes: 10 additions & 56 deletions src/viewer/viewer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ import {
ShaderMaterial,
PlaneGeometry,
Scene, Mesh, Group, Object3D, Uniform,
Fog, SpotLight, AmbientLight,
Fog, DirectionalLight, AmbientLight,
BufferGeometry, BufferAttribute,
LineSegments, ColorSpace
LineSegments
} from 'three'
import '../shader/BasicLine.vert'
import '../shader/BasicLine.frag'
Expand All @@ -30,7 +30,6 @@ import {
import { degToRad } from '../math/math-utils'
import Stats from './stats'
import { getShader } from '../shader/shader-utils'
import { setColorSpace } from '../color/colormaker'
import { JitterVectors } from './viewer-constants'
import {
makeImage, ImageParameters,
Expand Down Expand Up @@ -162,8 +161,6 @@ export interface ViewerParameters {
ambientIntensity: number

sampleLevel: number

outputColorSpace: ColorSpace // default is three.LinearEncoding; three.sRGBEncoding gives more correct results
}

export interface BufferInstance {
Expand Down Expand Up @@ -203,7 +200,7 @@ export default class Viewer {
height: number

scene: Scene
private spotLight: SpotLight
private directionalLight: DirectionalLight
private ambientLight: AmbientLight
rotationGroup: Group
translationGroup: Group
Expand Down Expand Up @@ -320,14 +317,11 @@ export default class Viewer {
clipScale: 'relative',

lightColor: new Color(0xdddddd),
lightIntensity: 1.0,
lightIntensity: 3.14,
ambientColor: new Color(0xdddddd),
ambientIntensity: 0.2,
ambientIntensity: 0.63,

sampleLevel: 0,

// output encoding: use srgb for a linear internal workflow, srgb-linear for traditional sRGB workflow.
outputColorSpace: 'srgb-linear',
}
}

Expand Down Expand Up @@ -402,10 +396,10 @@ export default class Viewer {

// light

this.spotLight = new SpotLight(
this.directionalLight = new DirectionalLight(
this.parameters.lightColor.getHex(), this.parameters.lightIntensity
)
this.scene.add(this.spotLight)
this.scene.add(this.directionalLight)

this.ambientLight = new AmbientLight(
this.parameters.ambientColor.getHex(), this.parameters.ambientIntensity
Expand All @@ -431,8 +425,6 @@ export default class Viewer {
this.renderer.setSize(width, height)
this.renderer.autoClear = false
this.renderer.sortObjects = true
this.renderer.outputColorSpace = this.parameters.outputColorSpace
this.renderer.useLegacyLights = true

const gl = this.renderer.getContext()
// console.log(gl.getContextAttributes().antialias)
Expand Down Expand Up @@ -505,7 +497,6 @@ export default class Viewer {
}
)
this.pickingTarget.texture.generateMipmaps = false
this.pickingTarget.texture.colorSpace = this.parameters.outputColorSpace

// workaround to reset the gl state after using testTextureSupport
// fixes some bug where nothing is rendered to the canvas
Expand All @@ -524,7 +515,6 @@ export default class Viewer {
format: RGBAFormat
}
)
this.sampleTarget.texture.colorSpace = this.parameters.outputColorSpace

this.holdTarget = new WebGLRenderTarget(
dprWidth, dprHeight,
Expand All @@ -539,7 +529,6 @@ export default class Viewer {
// )
}
)
this.holdTarget.texture.colorSpace = this.parameters.outputColorSpace

this.compositeUniforms = {
'tForeground': new Uniform(this.sampleTarget.texture),
Expand Down Expand Up @@ -858,41 +847,6 @@ export default class Viewer {
this.requestRender()
}

/**
* Set the output color encoding, i.e. how the renderer translates
* colorspaces as it renders to the screen.
* The default is LinearEncoding, because the internals of NGL are
* already sRGB so no translation is needed to show sRGB colors.
* Set to sRGBEncoding to create a linear workflow, and also call
* `setColorEncoding(LinearEncoding)` to linearize colors on input.
* @see setColorEncoding
*/
private setOutputEncoding (colorspace: ColorSpace) {
this.parameters.outputColorSpace = colorspace
this.renderer.outputColorSpace = colorspace
this.pickingTarget.texture.colorSpace = colorspace
this.sampleTarget.texture.colorSpace = colorspace
this.holdTarget.texture.colorSpace = colorspace
}

/**
* Set the internal color workflow, linear or sRGB.
* sRGB, the default, is more "vibrant" at the cost of accuracy.
* Linear gives more accurate results, especially for transparent objects.
* In all cases, the output is always sRGB; this just affects how colors are computed internally.
* Call this just after creating the viewer, before loading any models.
*/
setColorWorkflow (colorspace: ColorSpace) {
if (colorspace != 'srgb-linear' && colorspace != 'srgb')
throw new Error(`setColorWorkflow: invalid color workflow ${colorspace}`)
setColorSpace(colorspace == 'srgb-linear' ? 'linear' : 'sRGB')
this.setOutputEncoding(colorspace == 'srgb-linear' ? 'srgb' : 'srgb-linear')
// Note: this doesn't rebuild models, so existing geometry will have
// the old color encoding.
this.requestRender()
}

setCamera (type: CameraType, fov?: number, eyeSep?: number) {
const p = this.parameters

Expand Down Expand Up @@ -1226,11 +1180,11 @@ export default class Viewer {
}

private __updateLights () {
this.spotLight.color.set(this.parameters.lightColor)
this.spotLight.intensity = this.parameters.lightIntensity
this.directionalLight.color.set(this.parameters.lightColor)
this.directionalLight.intensity = this.parameters.lightIntensity

this.distVector.copy(this.camera.position).setLength(this.boundingBoxLength * 100)
this.spotLight.position.copy(this.camera.position).add(this.distVector)
this.directionalLight.position.copy(this.camera.position).add(this.distVector)

this.ambientLight.color.set(this.parameters.ambientColor)
this.ambientLight.intensity = this.parameters.ambientIntensity
Expand Down

0 comments on commit c9cc1d1

Please sign in to comment.