Last active
June 3, 2022 12:59
-
-
Save UuuNyaa/f5b1f166e7d6db1e85b991e1aa15744e to your computer and use it in GitHub Desktop.
RGB/HSV converter shader block for Babylon.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class RGBtoHSVBlock extends NodeMaterialBlock { | |
| /** | |
| * Creates a new RGBtoHSVBlock | |
| * @param name defines the block name | |
| */ | |
| public constructor(name: string) { | |
| super(name, NodeMaterialBlockTargets.Fragment) | |
| this.registerInput("rgb", NodeMaterialBlockConnectionPointTypes.Color3) | |
| this.registerOutput("hsv", NodeMaterialBlockConnectionPointTypes.Color3) | |
| } | |
| /** | |
| * Gets the current class name | |
| * @returns the class name | |
| */ | |
| public getClassName() { | |
| return "RGBtoHSVBlock"; | |
| } | |
| /** | |
| * Gets the rgb input | |
| */ | |
| public get rgbIn(): NodeMaterialConnectionPoint { | |
| return this._inputs[0]; | |
| } | |
| /** | |
| * Gets the hsv output | |
| */ | |
| public get hsvOut(): NodeMaterialConnectionPoint { | |
| return this._outputs[0]; | |
| } | |
| protected _buildBlock(state: NodeMaterialBuildState) { | |
| super._buildBlock(state); | |
| const rgb = this.rgbIn.associatedVariableName | |
| const hsv = this.hsvOut | |
| const K = state._getFreeVariableName('K'); | |
| const p = state._getFreeVariableName('p'); | |
| const q = state._getFreeVariableName('q'); | |
| const d = state._getFreeVariableName('d'); | |
| const e = state._getFreeVariableName('e'); | |
| state.compilationString += ` | |
| vec4 ${K} = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); | |
| vec4 ${p} = mix(vec4(${rgb}.bg, ${K}.wz), vec4(${rgb}.gb, ${K}.xy), step(${rgb}.b, ${rgb}.g)); | |
| vec4 ${q} = mix(vec4(${p}.xyw, ${rgb}.r), vec4(${rgb}.r, ${p}.yzx), step(${p}.x, ${rgb}.r)); | |
| float ${d} = ${q}.x - min(${q}.w, ${q}.y); | |
| float ${e} = 1.0e-10; | |
| ${this._declareOutput(hsv, state)} = vec3(abs(${q}.z + (${q}.w - ${q}.y) / (6.0 * ${d} + ${e})), ${d} / (${q}.x + ${e}), ${q}.x); | |
| ` | |
| return this; | |
| } | |
| } | |
| # using CustomBlock | |
| const rgb2hsv = new CustomBlock("RGB to HSV") as any as { rgb: NodeMaterialConnectionPoint, hsv: NodeMaterialConnectionPoint, options: any } | |
| rgb2hsv.options = { | |
| "name": "RGB to HSV", | |
| "comments": "", | |
| "target": "Neutral", | |
| "inParameters": [ | |
| { "name": "rgb", "type": "Vector3" } | |
| ], | |
| "outParameters": [ | |
| { "name": "hsv", "type": "Vector3" } | |
| ], | |
| "functionName": "rgb2hsv", | |
| "code": [` | |
| void rgb2hsv(vec3 rgb, out vec3 hsv) { | |
| vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); | |
| vec4 p = mix(vec4(rgb.bg, K.wz), vec4(rgb.gb, K.xy), step(rgb.b, rgb.g)); | |
| vec4 q = mix(vec4(p.xyw, rgb.r), vec4(rgb.r, p.yzx), step(p.x, rgb.r)); | |
| float d = q.x - min(q.w, q.y); | |
| float e = 1.0e-10; | |
| hsv = vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); | |
| } | |
| `] | |
| } | |
| const hsv2rgb = new CustomBlock("HSV to RGB") as any as { hsv: NodeMaterialConnectionPoint, rgb: NodeMaterialConnectionPoint, options: any } | |
| hsv2rgb.options = { | |
| "name": "HSV to RGB", | |
| "comments": "", | |
| "target": "Neutral", | |
| "inParameters": [ | |
| { "name": "hsv", "type": "Vector3" } | |
| ], | |
| "outParameters": [ | |
| { "name": "rgb", "type": "Vector3" } | |
| ], | |
| "functionName": "hsv2rgb", | |
| "code": [` | |
| void hsv2rgb(vec3 hsv, out vec3 rgb) { | |
| vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); | |
| vec3 p = abs(fract(hsv.xxx + K.xyz) * 6.0 - K.www); | |
| rgb = hsv.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), hsv.y); | |
| } | |
| `] | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment