WebGL support

Subgraph support
FX nodes moved from gltexture to glfx
Improves in gltexture
This commit is contained in:
tamat
2014-10-02 15:38:19 +02:00
parent 2e9b4a3f77
commit 6248dd4e0f
17 changed files with 5784 additions and 836 deletions

View File

@@ -2,78 +2,27 @@
(function(){
//Input for a subgraph
function GlobalInput()
{
this.title = "Input";
//random name to avoid problems with other outputs when added
var genname = "input_" + (Math.random()*1000).toFixed();
this.properties = { name: genname, type: "number" };
this.addOutput("value",0);
}
GlobalInput.title = "Input";
GlobalInput.desc = "Input of the graph";
GlobalInput.prototype.onAdded = function()
{
this.graph.addGlobalInput( this.properties.name, this.properties.type );
}
GlobalInput.prototype.onExecute = function()
{
var name = this.properties.name;
//read from global input
var data = this.graph.global_inputs[name];
if(!data) return;
//put through output
this.setOutputData(0,data.value);
}
LiteGraph.registerNodeType("graph/input", GlobalInput);
//Output for a subgraph
function GlobalOutput()
{
this.title = "Output";
//random name to avoid problems with other outputs when added
var genname = "output_" + (Math.random()*1000).toFixed();
this.properties = { name: genname, type: "number" };
this.addInput("value","number");
}
GlobalOutput.title = "Ouput";
GlobalOutput.desc = "Output of the graph";
GlobalOutput.prototype.onAdded = function()
{
var name = this.graph.addGlobalOutput( this.properties.name, this.properties.type );
}
GlobalOutput.prototype.onExecute = function()
{
this.graph.setGlobalOutputData( this.properties.name, this.getInputData(0) );
}
LiteGraph.registerNodeType("graph/output", GlobalOutput);
//Subgraph: a node that contains a graph
function Subgraph()
{
var that = this;
this.size = [120,60];
//create inner graph
this.subgraph = new LGraph();
this.subgraph._subgraph_node = this;
this.subgraph._is_subgraph = true;
this.subgraph.onGlobalInputAdded = this.onSubgraphNewGlobalInput.bind(this);
this.subgraph.onGlobalOutputAdded = this.onSubgraphNewGlobalOutput.bind(this);
this.bgcolor = "#FA3";
this.subgraph.onGlobalInputAdded = this.onSubgraphNewGlobalInput.bind(this);
this.subgraph.onGlobalInputRenamed = this.onSubgraphRenamedGlobalInput.bind(this);
this.subgraph.onGlobalInputTypeChanged = this.onSubgraphTypeChangeGlobalInput.bind(this);
this.subgraph.onGlobalOutputAdded = this.onSubgraphNewGlobalOutput.bind(this);
this.subgraph.onGlobalOutputRenamed = this.onSubgraphRenamedGlobalOutput.bind(this);
this.subgraph.onGlobalOutputTypeChanged = this.onSubgraphTypeChangeGlobalOutput.bind(this);
this.bgcolor = "#940";
}
Subgraph.title = "Subgraph";
@@ -81,14 +30,55 @@ Subgraph.desc = "Graph inside a node";
Subgraph.prototype.onSubgraphNewGlobalInput = function(name, type)
{
//add input to the node
this.addInput(name, type);
}
Subgraph.prototype.onSubgraphRenamedGlobalInput = function(oldname, name)
{
var slot = this.findInputSlot( oldname );
if(slot == -1)
return;
var info = this.getInputInfo(slot);
info.name = name;
}
Subgraph.prototype.onSubgraphTypeChangeGlobalInput = function(name, type)
{
var slot = this.findInputSlot( name );
if(slot == -1)
return;
var info = this.getInputInfo(slot);
info.type = type;
}
Subgraph.prototype.onSubgraphNewGlobalOutput = function(name, type)
{
//add output to the node
this.addOutput(name, type);
}
Subgraph.prototype.onSubgraphRenamedGlobalOutput = function(oldname, name)
{
var slot = this.findOutputSlot( oldname );
if(slot == -1)
return;
var info = this.getOutputInfo(slot);
info.name = name;
}
Subgraph.prototype.onSubgraphTypeChangeGlobalOutput = function(name, type)
{
var slot = this.findOutputSlot( name );
if(slot == -1)
return;
var info = this.getOutputInfo(slot);
info.type = type;
}
Subgraph.prototype.getExtraMenuOptions = function(graphcanvas)
{
var that = this;
@@ -136,10 +126,147 @@ Subgraph.prototype.serialize = function()
return data;
}
Subgraph.prototype.clone = function()
{
var node = LiteGraph.createNode(this.type);
var data = this.serialize();
delete data["id"];
delete data["inputs"];
delete data["outputs"];
node.configure(data);
return node;
}
LiteGraph.registerNodeType("graph/subgraph", Subgraph);
//Input for a subgraph
function GlobalInput()
{
//random name to avoid problems with other outputs when added
var input_name = "input_" + (Math.random()*1000).toFixed();
this.addOutput(input_name, null );
this.properties = {name: input_name, type: null };
var that = this;
Object.defineProperty(this.properties, "name", {
get: function() {
return input_name;
},
set: function(v) {
if(v == "")
return;
var info = that.getOutputInfo(0);
if(info.name == v)
return;
info.name = v;
if(that.graph)
that.graph.renameGlobalInput(input_name, v);
input_name = v;
},
enumerable: true
});
Object.defineProperty(this.properties, "type", {
get: function() { return that.outputs[0].type; },
set: function(v) {
that.outputs[0].type = v;
if(that.graph)
that.graph.changeGlobalInputType(input_name, that.outputs[0].type);
},
enumerable: true
});
}
GlobalInput.title = "Input";
GlobalInput.desc = "Input of the graph";
//When added to graph tell the graph this is a new global input
GlobalInput.prototype.onAdded = function()
{
this.graph.addGlobalInput( this.properties.name, this.properties.type );
}
GlobalInput.prototype.onExecute = function()
{
var name = this.properties.name;
//read from global input
var data = this.graph.global_inputs[name];
if(!data) return;
//put through output
this.setOutputData(0,data.value);
}
LiteGraph.registerNodeType("graph/input", GlobalInput);
//Output for a subgraph
function GlobalOutput()
{
//random name to avoid problems with other outputs when added
var output_name = "output_" + (Math.random()*1000).toFixed();
this.addInput(output_name, null);
this.properties = {name: output_name, type: null };
var that = this;
Object.defineProperty(this.properties, "name", {
get: function() {
return output_name;
},
set: function(v) {
if(v == "")
return;
var info = that.getInputInfo(0);
if(info.name == v)
return;
info.name = v;
if(that.graph)
that.graph.renameGlobalOutput(output_name, v);
output_name = v;
},
enumerable: true
});
Object.defineProperty(this.properties, "type", {
get: function() { return that.inputs[0].type; },
set: function(v) {
that.inputs[0].type = v;
if(that.graph)
that.graph.changeGlobalInputType( output_name, that.inputs[0].type );
},
enumerable: true
});
}
GlobalOutput.title = "Ouput";
GlobalOutput.desc = "Output of the graph";
GlobalOutput.prototype.onAdded = function()
{
var name = this.graph.addGlobalOutput( this.properties.name, this.properties.type );
}
GlobalOutput.prototype.onExecute = function()
{
this.graph.setGlobalOutputData( this.properties.name, this.getInputData(0) );
}
LiteGraph.registerNodeType("graph/output", GlobalOutput);
//Constant
function Constant()

538
src/nodes/glfx.js Normal file
View File

@@ -0,0 +1,538 @@
//Works with Litegl.js to create WebGL nodes
if(typeof(LiteGraph) != "undefined")
{
// Texture Lens *****************************************
function LGraphFXLens()
{
this.addInput("Texture","Texture");
this.addInput("Aberration","number");
this.addInput("Distortion","number");
this.addInput("Blur","number");
this.addOutput("Texture","Texture");
this.properties = { aberration:1.0, distortion: 1.0, blur: 1.0, precision: LGraphTexture.DEFAULT };
if(!LGraphFXLens._shader)
LGraphFXLens._shader = new GL.Shader( Shader.SCREEN_VERTEX_SHADER, LGraphFXLens.pixel_shader );
}
LGraphFXLens.title = "Lens";
LGraphFXLens.desc = "Camera Lens distortion";
LGraphFXLens.widgets_info = {
"precision": { widget:"combo", values: LGraphTexture.MODE_VALUES }
};
LGraphFXLens.prototype.onExecute = function()
{
var tex = this.getInputData(0);
if(this.properties.precision === LGraphTexture.PASS_THROUGH )
{
this.setOutputData(0,tex);
return;
}
if(!tex) return;
this._tex = LGraphTexture.getTargetTexture( tex, this._tex, this.properties.precision );
//iterations
var aberration = this.properties.aberration;
if( this.isInputConnected(1) )
{
aberration = this.getInputData(1);
this.properties.aberration = aberration;
}
var distortion = this.properties.distortion;
if( this.isInputConnected(2) )
{
distortion = this.getInputData(2);
this.properties.distortion = distortion;
}
var blur = this.properties.blur;
if( this.isInputConnected(3) )
{
blur = this.getInputData(3);
this.properties.blur = blur;
}
gl.disable( gl.BLEND );
gl.disable( gl.DEPTH_TEST );
var mesh = Mesh.getScreenQuad();
var shader = LGraphFXLens._shader;
var camera = Renderer._current_camera;
this._tex.drawTo( function() {
tex.bind(0);
shader.uniforms({u_texture:0, u_aberration: aberration, u_distortion: distortion, u_blur: blur })
.draw(mesh);
});
this.setOutputData(0, this._tex);
}
LGraphFXLens.pixel_shader = "precision highp float;\n\
precision highp float;\n\
varying vec2 v_coord;\n\
uniform sampler2D u_texture;\n\
uniform vec2 u_camera_planes;\n\
uniform float u_aberration;\n\
uniform float u_distortion;\n\
uniform float u_blur;\n\
\n\
void main() {\n\
vec2 coord = v_coord;\n\
float dist = distance(vec2(0.5), coord);\n\
vec2 dist_coord = coord - vec2(0.5);\n\
float percent = 1.0 + ((0.5 - dist) / 0.5) * u_distortion;\n\
dist_coord *= percent;\n\
coord = dist_coord + vec2(0.5);\n\
vec4 color = texture2D(u_texture,coord, u_blur * dist);\n\
color.r = texture2D(u_texture,vec2(0.5) + dist_coord * (1.0+0.01*u_aberration), u_blur * dist ).r;\n\
color.b = texture2D(u_texture,vec2(0.5) + dist_coord * (1.0-0.01*u_aberration), u_blur * dist ).b;\n\
gl_FragColor = color;\n\
}\n\
";
/*
float normalized_tunable_sigmoid(float xs, float k)\n\
{\n\
xs = xs * 2.0 - 1.0;\n\
float signx = sign(xs);\n\
float absx = abs(xs);\n\
return signx * ((-k - 1.0)*absx)/(2.0*(-2.0*k*absx+k-1.0)) + 0.5;\n\
}\n\
*/
LiteGraph.registerNodeType("fx/lens", LGraphFXLens );
window.LGraphFXLens = LGraphFXLens;
//*******************************************************
function LGraphFXBokeh()
{
this.addInput("Texture","Texture");
this.addInput("Blurred","Texture");
this.addInput("Mask","Texture");
this.addInput("Threshold","number");
this.addOutput("Texture","Texture");
this.properties = { shape: "", size: 10, alpha: 1.0, threshold: 1.0, high_precision: false };
}
LGraphFXBokeh.title = "Bokeh";
LGraphFXBokeh.desc = "applies an Bokeh effect";
LGraphFXBokeh.widgets_info = {"shape": { widget:"texture" }};
LGraphFXBokeh.prototype.onExecute = function()
{
var tex = this.getInputData(0);
var blurred_tex = this.getInputData(1);
var mask_tex = this.getInputData(2);
if(!tex || !mask_tex || !this.properties.shape)
{
this.setOutputData(0, tex);
return;
}
if(!blurred_tex)
blurred_tex = tex;
var shape_tex = LGraphTexture.getTexture( this.properties.shape );
if(!shape_tex)
return;
var threshold = this.properties.threshold;
if( this.isInputConnected(3) )
{
threshold = this.getInputData(3);
this.properties.threshold = threshold;
}
var precision = gl.UNSIGNED_BYTE;
if(this.properties.high_precision)
precision = gl.half_float_ext ? gl.HALF_FLOAT_OES : gl.FLOAT;
if(!this._temp_texture || this._temp_texture.type != precision ||
this._temp_texture.width != tex.width || this._temp_texture.height != tex.height)
this._temp_texture = new GL.Texture( tex.width, tex.height, { type: precision, format: gl.RGBA, filter: gl.LINEAR });
//iterations
var size = this.properties.size;
var first_shader = LGraphFXBokeh._first_shader;
if(!first_shader)
first_shader = LGraphFXBokeh._first_shader = new GL.Shader( Shader.SCREEN_VERTEX_SHADER, LGraphFXBokeh._first_pixel_shader );
var second_shader = LGraphFXBokeh._second_shader;
if(!second_shader)
second_shader = LGraphFXBokeh._second_shader = new GL.Shader( LGraphFXBokeh._second_vertex_shader, LGraphFXBokeh._second_pixel_shader );
var points_mesh = this._points_mesh;
if(!points_mesh || points_mesh._width != tex.width || points_mesh._height != tex.height || points_mesh._spacing != 2)
points_mesh = this.createPointsMesh( tex.width, tex.height, 2 );
var screen_mesh = Mesh.getScreenQuad();
var point_size = this.properties.size;
var min_light = this.properties.min_light;
var alpha = this.properties.alpha;
gl.disable( gl.DEPTH_TEST );
gl.disable( gl.BLEND );
this._temp_texture.drawTo( function() {
tex.bind(0);
blurred_tex.bind(1);
mask_tex.bind(2);
first_shader.uniforms({u_texture:0, u_texture_blur:1, u_mask: 2, u_texsize: [tex.width, tex.height] })
.draw(screen_mesh);
});
this._temp_texture.drawTo( function() {
//clear because we use blending
//gl.clearColor(0.0,0.0,0.0,1.0);
//gl.clear( gl.COLOR_BUFFER_BIT );
gl.enable( gl.BLEND );
gl.blendFunc( gl.ONE, gl.ONE );
tex.bind(0);
shape_tex.bind(3);
second_shader.uniforms({u_texture:0, u_mask: 2, u_shape:3, u_alpha: alpha, u_threshold: threshold, u_pointSize: point_size, u_itexsize: [1.0/tex.width, 1.0/tex.height] })
.draw(points_mesh, gl.POINTS);
});
this.setOutputData(0, this._temp_texture);
}
LGraphFXBokeh.prototype.createPointsMesh = function(width, height, spacing)
{
var nwidth = Math.round(width / spacing);
var nheight = Math.round(height / spacing);
var vertices = new Float32Array(nwidth * nheight * 2);
var ny = -1;
var dx = 2/width * spacing;
var dy = 2/height * spacing;
for(var y = 0; y < nheight; ++y )
{
var nx = -1;
for(var x = 0; x < nwidth; ++x )
{
var pos = y*nwidth*2 + x*2;
vertices[pos] = nx;
vertices[pos+1] = ny;
nx += dx;
}
ny += dy;
}
this._points_mesh = GL.Mesh.load({vertices2D: vertices});
this._points_mesh._width = width;
this._points_mesh._height = height;
this._points_mesh._spacing = spacing;
return this._points_mesh;
}
/*
LGraphTextureBokeh._pixel_shader = "precision highp float;\n\
varying vec2 a_coord;\n\
uniform sampler2D u_texture;\n\
uniform sampler2D u_shape;\n\
\n\
void main() {\n\
vec4 color = texture2D( u_texture, gl_PointCoord );\n\
color *= v_color * u_alpha;\n\
gl_FragColor = color;\n\
}\n";
*/
LGraphFXBokeh._first_pixel_shader = "precision highp float;\n\
precision highp float;\n\
varying vec2 v_coord;\n\
uniform sampler2D u_texture;\n\
uniform sampler2D u_texture_blur;\n\
uniform sampler2D u_mask;\n\
\n\
void main() {\n\
vec4 color = texture2D(u_texture, v_coord);\n\
vec4 blurred_color = texture2D(u_texture_blur, v_coord);\n\
float mask = texture2D(u_mask, v_coord).x;\n\
gl_FragColor = mix(color, blurred_color, mask);\n\
}\n\
";
LGraphFXBokeh._second_vertex_shader = "precision highp float;\n\
attribute vec2 a_vertex2D;\n\
varying vec4 v_color;\n\
uniform sampler2D u_texture;\n\
uniform sampler2D u_mask;\n\
uniform vec2 u_itexsize;\n\
uniform float u_pointSize;\n\
uniform float u_threshold;\n\
void main() {\n\
vec2 coord = a_vertex2D * 0.5 + 0.5;\n\
v_color = texture2D( u_texture, coord );\n\
v_color += texture2D( u_texture, coord + vec2(u_itexsize.x, 0.0) );\n\
v_color += texture2D( u_texture, coord + vec2(0.0, u_itexsize.y));\n\
v_color += texture2D( u_texture, coord + u_itexsize);\n\
v_color *= 0.25;\n\
float mask = texture2D(u_mask, coord).x;\n\
float luminance = length(v_color) * mask;\n\
/*luminance /= (u_pointSize*u_pointSize)*0.01 */;\n\
luminance -= u_threshold;\n\
if(luminance < 0.0)\n\
{\n\
gl_Position.x = -100.0;\n\
return;\n\
}\n\
gl_PointSize = u_pointSize;\n\
gl_Position = vec4(a_vertex2D,0.0,1.0);\n\
}\n\
";
LGraphFXBokeh._second_pixel_shader = "precision highp float;\n\
varying vec4 v_color;\n\
uniform sampler2D u_shape;\n\
uniform float u_alpha;\n\
\n\
void main() {\n\
vec4 color = texture2D( u_shape, gl_PointCoord );\n\
color *= v_color * u_alpha;\n\
gl_FragColor = color;\n\
}\n";
LiteGraph.registerNodeType("fx/bokeh", LGraphFXBokeh );
window.LGraphFXBokeh = LGraphFXBokeh;
//************************************************
function LGraphFXGeneric()
{
this.addInput("Texture","Texture");
this.addInput("value1","number");
this.addInput("value2","number");
this.addOutput("Texture","Texture");
this.properties = { fx: "halftone", value1: 1, value2: 1, precision: LGraphTexture.DEFAULT };
}
LGraphFXGeneric.title = "FX";
LGraphFXGeneric.desc = "applies an FX from a list";
LGraphFXGeneric.widgets_info = {
"fx": { widget:"combo", values:["halftone","pixelate","lowpalette","noise"] },
"precision": { widget:"combo", values: LGraphTexture.MODE_VALUES }
};
LGraphFXGeneric.shaders = {};
LGraphFXGeneric.prototype.onExecute = function()
{
var tex = this.getInputData(0);
if(this.properties.precision === LGraphTexture.PASS_THROUGH )
{
this.setOutputData(0,tex);
return;
}
if(!tex) return;
this._tex = LGraphTexture.getTargetTexture( tex, this._tex, this.properties.precision );
//iterations
var value1 = this.properties.value1;
if( this.isInputConnected(1) )
{
value1 = this.getInputData(1);
this.properties.value1 = value1;
}
var value2 = this.properties.value2;
if( this.isInputConnected(2) )
{
value2 = this.getInputData(2);
this.properties.value2 = value2;
}
var fx = this.properties.fx;
var shader = LGraphFXGeneric.shaders[ fx ];
if(!shader)
{
var pixel_shader_code = LGraphFXGeneric["pixel_shader_" + fx ];
if(!pixel_shader_code)
return;
shader = LGraphFXGeneric.shaders[ fx ] = new GL.Shader( Shader.SCREEN_VERTEX_SHADER, pixel_shader_code );
}
gl.disable( gl.BLEND );
gl.disable( gl.DEPTH_TEST );
var mesh = Mesh.getScreenQuad();
var camera = Renderer._current_camera;
var noise = null;
if(fx == "noise")
noise = LGraphTexture.getNoiseTexture();
this._tex.drawTo( function() {
tex.bind(0);
if(fx == "noise")
noise.bind(1);
shader.uniforms({u_texture:0, u_noise:1, u_size: [tex.width, tex.height], u_rand:[ Math.random(), Math.random() ], u_value1: value1, u_value2: value2, u_camera_planes: [Renderer._current_camera.near,Renderer._current_camera.far] })
.draw(mesh);
});
this.setOutputData(0, this._tex);
}
LGraphFXGeneric.pixel_shader_halftone = "precision highp float;\n\
varying vec2 v_coord;\n\
uniform sampler2D u_texture;\n\
uniform vec2 u_camera_planes;\n\
uniform vec2 u_size;\n\
uniform float u_value1;\n\
uniform float u_value2;\n\
\n\
float pattern() {\n\
float s = sin(u_value1 * 3.1415), c = cos(u_value1 * 3.1415);\n\
vec2 tex = v_coord * u_size.xy;\n\
vec2 point = vec2(\n\
c * tex.x - s * tex.y ,\n\
s * tex.x + c * tex.y \n\
) * u_value2;\n\
return (sin(point.x) * sin(point.y)) * 4.0;\n\
}\n\
void main() {\n\
vec4 color = texture2D(u_texture, v_coord);\n\
float average = (color.r + color.g + color.b) / 3.0;\n\
gl_FragColor = vec4(vec3(average * 10.0 - 5.0 + pattern()), color.a);\n\
}\n";
LGraphFXGeneric.pixel_shader_pixelate = "precision highp float;\n\
varying vec2 v_coord;\n\
uniform sampler2D u_texture;\n\
uniform vec2 u_camera_planes;\n\
uniform vec2 u_size;\n\
uniform float u_value1;\n\
uniform float u_value2;\n\
\n\
void main() {\n\
vec2 coord = vec2( floor(v_coord.x * u_value1) / u_value1, floor(v_coord.y * u_value2) / u_value2 );\n\
vec4 color = texture2D(u_texture, coord);\n\
gl_FragColor = color;\n\
}\n";
LGraphFXGeneric.pixel_shader_lowpalette = "precision highp float;\n\
varying vec2 v_coord;\n\
uniform sampler2D u_texture;\n\
uniform vec2 u_camera_planes;\n\
uniform vec2 u_size;\n\
uniform float u_value1;\n\
uniform float u_value2;\n\
\n\
void main() {\n\
vec4 color = texture2D(u_texture, v_coord);\n\
gl_FragColor = floor(color * u_value1) / u_value1;\n\
}\n";
LGraphFXGeneric.pixel_shader_noise = "precision highp float;\n\
varying vec2 v_coord;\n\
uniform sampler2D u_texture;\n\
uniform sampler2D u_noise;\n\
uniform vec2 u_size;\n\
uniform float u_value1;\n\
uniform float u_value2;\n\
uniform vec2 u_rand;\n\
\n\
void main() {\n\
vec4 color = texture2D(u_texture, v_coord);\n\
vec3 noise = texture2D(u_noise, v_coord * vec2(u_size.x / 512.0, u_size.y / 512.0) + u_rand).xyz - vec3(0.5);\n\
gl_FragColor = vec4( color.xyz + noise * u_value1, color.a );\n\
}\n";
LiteGraph.registerNodeType("fx/generic", LGraphFXGeneric );
window.LGraphFXGeneric = LGraphFXGeneric;
// Vigneting ************************************
function LGraphFXVigneting()
{
this.addInput("Tex.","Texture");
this.addInput("intensity","number");
this.addOutput("Texture","Texture");
this.properties = { intensity: 1, invert: false, precision: LGraphTexture.DEFAULT };
if(!LGraphFXVigneting._shader)
LGraphFXVigneting._shader = new GL.Shader( Shader.SCREEN_VERTEX_SHADER, LGraphFXVigneting.pixel_shader );
}
LGraphFXVigneting.title = "Vigneting";
LGraphFXVigneting.desc = "Vigneting";
LGraphFXVigneting.widgets_info = {
"precision": { widget:"combo", values: LGraphTexture.MODE_VALUES }
};
LGraphFXVigneting.prototype.onExecute = function()
{
var tex = this.getInputData(0);
if(this.properties.precision === LGraphTexture.PASS_THROUGH )
{
this.setOutputData(0,tex);
return;
}
if(!tex) return;
this._tex = LGraphTexture.getTargetTexture( tex, this._tex, this.properties.precision );
var intensity = this.properties.intensity;
if( this.isInputConnected(1) )
{
intensity = this.getInputData(1);
this.properties.intensity = intensity;
}
gl.disable( gl.BLEND );
gl.disable( gl.DEPTH_TEST );
var mesh = Mesh.getScreenQuad();
var shader = LGraphFXVigneting._shader;
var invert = this.properties.invert;
this._tex.drawTo( function() {
tex.bind(0);
shader.uniforms({u_texture:0, u_intensity: intensity, u_isize:[1/tex.width,1/tex.height], u_invert: invert ? 1 : 0}).draw(mesh);
});
this.setOutputData(0, this._tex);
}
LGraphFXVigneting.pixel_shader = "precision highp float;\n\
precision highp float;\n\
varying vec2 v_coord;\n\
uniform sampler2D u_texture;\n\
uniform float u_intensity;\n\
uniform int u_invert;\n\
\n\
void main() {\n\
float luminance = 1.0 - length( v_coord - vec2(0.5) ) * 1.414;\n\
vec4 color = texture2D(u_texture, v_coord);\n\
if(u_invert == 1)\n\
luminance = 1.0 - luminance;\n\
luminance = mix(1.0, luminance, u_intensity);\n\
gl_FragColor = vec4( luminance * color.xyz, color.a);\n\
}\n\
";
LiteGraph.registerNodeType("fx/vigneting", LGraphFXVigneting );
window.LGraphFXVigneting = LGraphFXVigneting;
}

1506
src/nodes/gltextures.js Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,105 @@
(function(){
function GraphicsImage()
{
this.inputs = [];
this.addOutput("frame","image");
this.properties = {"url":""};
}
GraphicsImage.title = "Image";
GraphicsImage.desc = "Image loader";
GraphicsImage.widgets = [{name:"load",text:"Load",type:"button"}];
GraphicsImage.prototype.onAdded = function()
{
if(this.properties["url"] != "" && this.img == null)
{
this.loadImage(this.properties["url"]);
}
}
GraphicsImage.prototype.onDrawBackground = function(ctx)
{
if(this.img && this.size[0] > 5 && this.size[1] > 5)
ctx.drawImage(this.img, 0,0,this.size[0],this.size[1]);
}
GraphicsImage.prototype.onExecute = function()
{
if(!this.img)
this.boxcolor = "#000";
if(this.img && this.img.width)
this.setOutputData(0,this.img);
else
this.setOutputData(0,null);
if(this.img && this.img.dirty)
this.img.dirty = false;
}
GraphicsImage.prototype.onPropertyChange = function(name,value)
{
this.properties[name] = value;
if (name == "url" && value != "")
this.loadImage(value);
return true;
}
GraphicsImage.prototype.onDropFile = function(file, filename)
{
var img = new Image();
img.src = file;
this.img = img;
}
GraphicsImage.prototype.loadImage = function(url)
{
if(url == "")
{
this.img = null;
return;
}
this.trace("loading image...");
this.img = document.createElement("img");
var url = name;
if(url.substr(0,7) == "http://")
{
if(LiteGraph.proxy) //proxy external files
url = LiteGraph.proxy + url.substr(7);
}
this.img.src = url;
this.boxcolor = "#F95";
var that = this;
this.img.onload = function()
{
that.trace("Image loaded, size: " + that.img.width + "x" + that.img.height );
this.dirty = true;
that.boxcolor = "#9F9";
that.setDirtyCanvas(true);
}
}
GraphicsImage.prototype.onWidget = function(e,widget)
{
if(widget.name == "load")
{
this.loadImage(this.properties["url"]);
}
}
LiteGraph.registerNodeType("graphics/image", GraphicsImage);
function ColorPalette()
{
this.addInput("f","number");
@@ -263,81 +362,6 @@ ImageFade.prototype.onExecute = function()
LiteGraph.registerNodeType("graphics/imagefade", ImageFade);
function GraphicsImage()
{
this.inputs = [];
this.addOutput("frame","image");
this.properties = {"url":""};
}
GraphicsImage.title = "Image";
GraphicsImage.desc = "Image loader";
GraphicsImage.widgets = [{name:"load",text:"Load",type:"button"}];
GraphicsImage.prototype.onAdded = function()
{
if(this.properties["url"] != "" && this.img == null)
{
this.loadImage(this.properties["url"]);
}
}
GraphicsImage.prototype.onExecute = function()
{
if(!this.img)
this.boxcolor = "#000";
if(this.img && this.img.width)
this.setOutputData(0,this.img);
else
this.setOutputData(0,null);
if(this.img.dirty)
this.img.dirty = false;
}
GraphicsImage.prototype.onPropertyChange = function(name,value)
{
this.properties[name] = value;
if (name == "url" && value != "")
this.loadImage(value);
return true;
}
GraphicsImage.prototype.loadImage = function(url)
{
if(url == "")
{
this.img = null;
return;
}
this.trace("loading image...");
this.img = document.createElement("img");
this.img.src = "miniproxy.php?url=" + url;
this.boxcolor = "#F95";
var that = this;
this.img.onload = function()
{
that.trace("Image loaded, size: " + that.img.width + "x" + that.img.height );
this.dirty = true;
that.boxcolor = "#9F9";
that.setDirtyCanvas(true);
}
}
GraphicsImage.prototype.onWidget = function(e,widget)
{
if(widget.name == "load")
{
this.loadImage(this.properties["url"]);
}
}
LiteGraph.registerNodeType("graphics/image", GraphicsImage);
function ImageCrop()
{