Skip to content

Instantly share code, notes, and snippets.

@UuuNyaa
Last active June 3, 2022 12:59
Show Gist options
  • Select an option

  • Save UuuNyaa/f5b1f166e7d6db1e85b991e1aa15744e to your computer and use it in GitHub Desktop.

Select an option

Save UuuNyaa/f5b1f166e7d6db1e85b991e1aa15744e to your computer and use it in GitHub Desktop.
RGB/HSV converter shader block for Babylon.js
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