Skip to content
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

LUT: Fix color definition and sampling. #23589

Merged
merged 1 commit into from
Feb 25, 2022
Merged

LUT: Fix color definition and sampling. #23589

merged 1 commit into from
Feb 25, 2022

Conversation

Mugen87
Copy link
Collaborator

@Mugen87 Mugen87 commented Feb 25, 2022

Fixed #23549.

Description

Fixes getColor() and setColorMap(). Improves updateCanvas().

@dcriado @scurest Does this look better to you?

@scurest
Copy link

scurest commented Feb 25, 2022

No, sorry. Maybe I wasn't clear, but rounding is the right thing to do. Here's an example:

Let's add a keyword 'blacktowhite': [[ 0.0, 0x000000 ], [ 1.0, 0xFFFFFF ]]. This is easy to understand since sampling at alpha ideally produces r=g=b=alpha.

With this PR's Lut:

>>> const l = new Lut("blacktowhite", 4);

// this returns lut[1] (0.25), it should return lut[2] (0.5)
// since 0.48 is closer to 0.5 than 0.25
>>> l.getColor(0.48)
Object { r: 0.25, g: 0.25, b: 0.25 }

// behavior for alpha near 1
>>> l.getColor(0.999)
Object { r: 0.75, g: 0.75, b: 0.75 }  // bad
>>> l.getColor(1)
Object { r: 1, g: 1, b: 1 }  // good!

With dev's Lut:

// this is correct
>>> l.getColor(0.48)
Object { r: 0.5, g: 0.5, b: 0.5 }

// the only "problem" is for alpha near 1 the color at
// the very end of the ramp doesn't get returned
// (essentially the lut[n] bucket is missing/unused)
>>> l.getColor(0.999)
Object { r: 0.75, g: 0.75, b: 0.75 }
>>> l.getColor(1)
Object { r: 0.75, g: 0.75, b: 0.75 }

// contrast with alpha near 0, where the color at
// the beginning DOES get returned
>>> l.getColor(0.001)
Object { r: 0, g: 0, b: 0 }

@Mugen87
Copy link
Collaborator Author

Mugen87 commented Feb 25, 2022

Okay, I've updated the PR.

@scurest
Copy link

scurest commented Feb 25, 2022

Cool, getColor looks right to me.

For setColorMap:

The loop doesn't always make n+1 elements in lut. For n=11 for example, i ends up being > 1 at the end of the loop, so there is no lut[11] and getColor(1) returns undefined.

IMO it would be easier to do something like this

// sample at 0
this.lut.push(this.map[0][1])

// sample at 1/n, ..., (n-1)/n
let j = 0;
for (i = 1; i !== n; i++) {  // use integer loop counter
    const alpha = i * step;

    // advance j until alpha is in the right range
    ...

    const color = lerp(...)

    // every iteration unconditionally pushes one element
    this.lut.push(color)
}

// sample at 1
this.lut.push(this.map[this.map.length - 1][1])

@Mugen87
Copy link
Collaborator Author

Mugen87 commented Feb 25, 2022

Slightly changed your code listing but the result should be okay now.

@scurest
Copy link

scurest commented Feb 25, 2022

Okay. As far as I can tell, it's right now.

@mrdoob mrdoob added this to the r139 milestone Feb 25, 2022
@mrdoob mrdoob merged commit cc5bf08 into mrdoob:dev Feb 25, 2022
@mrdoob
Copy link
Owner

mrdoob commented Feb 25, 2022

Thanks!

@dcriado
Copy link

dcriado commented Feb 28, 2022

Sorry guys, I could not have a look at this until now. It really looks good now! Thank you so much @Mugen87!!

donmccurdy pushed a commit to donmccurdy/three.js that referenced this pull request Mar 10, 2022
abernier pushed a commit to abernier/three.js that referenced this pull request Sep 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Lookup Table's Lut.getColor() should use Math.floor instead of Math.round
4 participants