OmarShehata / webgl-outlines

Implementation of a post process outline shader in ThreeJS & PlayCanvas.
MIT License
360 stars 39 forks source link

can we set the outline linewidth ? #11

Closed zhiqunDLUT closed 1 year ago

zhiqunDLUT commented 1 year ago

image It seems too width sometime, the outline looks like 2 pixels, so i want to set linewidth, how to set?

OmarShehata commented 1 year ago

There isn't an easy way to change the line thickness. What determines whether a line is drawn at each pixel is whether it passes the thresholds for a difference in normal & depth with the neighboring pixels. So one thing you could try to reduce the thickness is reduce the amount of neighbors you check for.

So in this function: https://github.com/OmarShehata/webgl-outlines/blob/42e210346abdb2dab78de20df9dffc369297340f/threejs/src/CustomOutlinePass.js#L181

float getSufaceIdDiff(vec3 surfaceValue) {
    float surfaceIdDiff = 0.0;
    surfaceIdDiff += distance(surfaceValue, getSurfaceValue(1, 0));
    surfaceIdDiff += distance(surfaceValue, getSurfaceValue(0, 1));
    surfaceIdDiff += distance(surfaceValue, getSurfaceValue(0, 1));
    surfaceIdDiff += distance(surfaceValue, getSurfaceValue(0, -1));
    surfaceIdDiff += distance(surfaceValue, getSurfaceValue(1, 1));
    surfaceIdDiff += distance(surfaceValue, getSurfaceValue(1, -1));
    surfaceIdDiff += distance(surfaceValue, getSurfaceValue(-1, 1));
    surfaceIdDiff += distance(surfaceValue, getSurfaceValue(-1, -1));
    return surfaceIdDiff;
}

You could remove the diagonal pixel checks, so it could be:

float getSufaceIdDiff(vec3 surfaceValue) {
    float surfaceIdDiff = 0.0;
    surfaceIdDiff += distance(surfaceValue, getSurfaceValue(1, 0));
    surfaceIdDiff += distance(surfaceValue, getSurfaceValue(0, 1));
    surfaceIdDiff += distance(surfaceValue, getSurfaceValue(-1, 0));
    surfaceIdDiff += distance(surfaceValue, getSurfaceValue(0, -1));
    return surfaceIdDiff;
}

And I think that should reduce the line thickness a bit.

OmarShehata commented 1 year ago

For a thicker outline you can extend this to check not just 1 neighboring pixel in each direction, but 2 neighboring pixels, or 3 etc in every direction (obviously this becomes expensive pretty quickly as you do a lot more texture lookups)