Previous topicNext topic

GLSL NODE CUSTOM VAIBLES

Questions, comments, feedback, etc.
Post Reply
bareimage
Posts: 24
Joined: Wed Sep 02, 2015 5:14 am

GLSL NODE CUSTOM VAIBLES

Post by bareimage »

Hello, does any one know if it is possible to have custom variables in GLSL node. I mostly do my work in VDMX, because there it is possible to create ISF files that have custom variables. It would be supper cool if it is possible in MAGIC as well.

Also it would be nice to be able to process non video data. Like Alfa numeric, strings, and have Javascript logic module.

Sorry asking to much...
Magic
Site Admin
Posts: 3440
Joined: Wed Apr 09, 2014 9:28 pm

Re: GLSL NODE CUSTOM VAIBLES

Post by Magic »

Hello, does any one know if it is possible to have custom variables in GLSL node. I mostly do my work in VDMX, because there it is possible to create ISF files that have custom variables. It would be supper cool if it is possible in MAGIC as well.
Yes, it is possible -- Magic supports ISF. Check out this topic for more information: viewtopic.php?f=3&t=412
Also it would be nice to be able to process non video data. Like Alfa numeric, strings, and have Javascript logic module.
I'm not sure what you mean here. Can you describe it in any more detail? And what would be the function of a JavaScript module?
bareimage
Posts: 24
Joined: Wed Sep 02, 2015 5:14 am

Re: GLSL NODE CUSTOM VAIBLES

Post by bareimage »

Super! Thank you for the heads up.

As to answer your question regarding need for the javascript node... I am an avid user of Max Msp / Isadora. I use these programs often for creating performances and interactive installations. I find Magic much quicker program for doing vissual idea sketching an prototyping my visuals. One of the two issues that I face is that I can not do advanced data processing within Magic and forced to use Max Msp / PD for data processing and then routing my information as MIDI into Magic.

If we would have the following OSC inputs, CSV or JASON file input options, as well as internall JAVASCRIPT processingl. It would be easier to do awsome work
Magic
Site Admin
Posts: 3440
Joined: Wed Apr 09, 2014 9:28 pm

Re: GLSL NODE CUSTOM VAIBLES

Post by Magic »

Ok, I guess I still don't understand exactly what you mean by "advanced data processing" though. What kind of things do you need to do? Can you give an example? Be very specific :).

Keep in mind that, at least in the current version of Magic, modules can only create graphics. They can't generate data values. This kind of simplicity is exactly why Magic is quicker and easier in many situations, as you mentioned. If modules had many different functions, things would be much slower and complicated to create. I don't intend to duplicate the functionality of programs like Max/MSP and Isadora, which are much bigger and more expensive. They are good for what they are, and they have dedicated user bases. I want to keep Magic clean, focused, and fast -- that's its specialty.

There is a possibility in the future that I will allow for custom data sources in the Audio/MIDI window. This might get you closer to what you are looking for. I do plan to add OSC support also. Additionally, I've thought about developing a module which would let you load JavaScript code that draws graphics. Maybe this is along the lines of what you meant?
bareimage
Posts: 24
Joined: Wed Sep 02, 2015 5:14 am

Re: GLSL NODE CUSTOM VAIBLES

Post by bareimage »

Almost! I would also love Javascript module to be able to send out integers, float, bull and etc. And it would be cool if this can control data sources in other modules. The big problem with max that it is cumbersome because people rely on really cumbersome data flow objects to do even the easiest of data processing. Isadora just introduced javascript module that does simple data processing for control of other modules.

So basically to recap... I would love to have Java Script Module that can process visual data, and or alpha numeric data with ability for alpha numeric data to control variables of other modules.

On the other note, this ISF generator crashes Magic, any ideas?

Code: Select all

/*
{
  "CATEGORIES": [
    "Automatically Converted"
  ],
  "DESCRIPTION": "Automatically converted from https://www.shadertoy.com/view/Ms2SD1",
  "IMPORTED": [
    
  ],
  "INPUTS": [
    {
      "NAME": "iMouse",
      "TYPE": "point2D"
    },
    {
      "NAME": "SEA_FREQ",
      "MIN": 0.0,
      "MAX": 1.0,
      "TYPE": "float",
      "DEFAULT": 0.16
    },
    {
      "NAME": "SEA_CHOPPY",
      "MIN": 0.0,
      "MAX": 8.0,
      "TYPE": "float",
      "DEFAULT": 4.0
    },
    {
      "NAME": "SEA_HEIGHT",
      "MIN": 0.0,
      "MAX": 3.0,
      "TYPE": "float",
      "DEFAULT": 0.6
    },
    {
      "NAME": "SEA_SPEED",
      "MIN": 0.0,
      "MAX": 2.0,
      "TYPE": "float",
      "DEFAULT": 0.8
    },
	{
		"NAME": "SEA_BASE",
		"TYPE": "color",
		"DEFAULT": [
			0.1,
			0.19,
			0.22,
			1.0
		]
	},
	{
		"NAME": "SEA_WATER_COLOR",
		"TYPE": "color",
		"DEFAULT": [
			0.8,
			0.9,
			0.6,
			1.0
		]
	}	
  ]
}
*/


// "Seascape" by Alexander Alekseev aka TDM - 2014
// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.

const int NUM_STEPS = 8;
const float PI	 	= 3.1415;
const float EPSILON	= 1e-3;
float EPSILON_NRM	= 0.1 / RENDERSIZE.x;

// sea
const int ITER_GEOMETRY = 3;
const int ITER_FRAGMENT = 5;
//const float SEA_HEIGHT = 0.6;
//const float SEA_CHOPPY = 4.0;
//const float SEA_SPEED = 0.8;
//const float SEA_FREQ = 0.16;
//const vec3 SEA_BASE = vec3(0.1,0.19,0.22);
//const vec3 SEA_WATER_COLOR = vec3(0.8,0.9,0.6);
float SEA_TIME = TIME * SEA_SPEED;
mat2 octave_m = mat2(1.6,1.2,-1.2,1.6);

// math
mat3 fromEuler(vec3 ang) {
	vec2 a1 = vec2(sin(ang.x),cos(ang.x));
    vec2 a2 = vec2(sin(ang.y),cos(ang.y));
    vec2 a3 = vec2(sin(ang.z),cos(ang.z));
    mat3 m;
    m[0] = vec3(a1.y*a3.y+a1.x*a2.x*a3.x,a1.y*a2.x*a3.x+a3.y*a1.x,-a2.y*a3.x);
	m[1] = vec3(-a2.y*a1.x,a1.y*a2.y,a2.x);
	m[2] = vec3(a3.y*a1.x*a2.x+a1.y*a3.x,a1.x*a3.x-a1.y*a3.y*a2.x,a2.y*a3.y);
	return m;
}
float hash( vec2 p ) {
	float h = dot(p,vec2(127.1,311.7));	
    return fract(sin(h)*43758.5453123);
}
float noise( in vec2 p ) {
    vec2 i = floor( p );
    vec2 f = fract( p );	
	vec2 u = f*f*(3.0-2.0*f);
    return -1.0+2.0*mix( mix( hash( i + vec2(0.0,0.0) ), 
                     hash( i + vec2(1.0,0.0) ), u.x),
                mix( hash( i + vec2(0.0,1.0) ), 
                     hash( i + vec2(1.0,1.0) ), u.x), u.y);
}

// lighting
float diffuse(vec3 n,vec3 l,float p) {
    return pow(dot(n,l) * 0.4 + 0.6,p);
}
float specular(vec3 n,vec3 l,vec3 e,float s) {    
    float nrm = (s + 8.0) / (3.1415 * 8.0);
    return pow(max(dot(reflect(e,n),l),0.0),s) * nrm;
}

// sky
vec3 getSkyColor(vec3 e) {
    e.y = max(e.y,0.0);
    vec3 ret;
    ret.x = pow(1.0-e.y,2.0);
    ret.y = 1.0-e.y;
    ret.z = 0.6+(1.0-e.y)*0.4;
    return ret;
}

// sea
float sea_octave(vec2 uv, float choppy) {
    uv += noise(uv);        
    vec2 wv = 1.0-abs(sin(uv));
    vec2 swv = abs(cos(uv));    
    wv = mix(wv,swv,wv);
    return pow(1.0-pow(wv.x * wv.y,0.65),choppy);
}

float map(vec3 p) {
    float freq = SEA_FREQ;
    float amp = SEA_HEIGHT;
    float choppy = SEA_CHOPPY;
    vec2 uv = p.xz; uv.x *= 0.75;
    
    float d, h = 0.0;    
    for(int i = 0; i < ITER_GEOMETRY; i++) {        
    	d = sea_octave((uv+SEA_TIME)*freq,choppy);
    	d += sea_octave((uv-SEA_TIME)*freq,choppy);
        h += d * amp;        
    	uv *= octave_m; freq *= 1.9; amp *= 0.22;
        choppy = mix(choppy,1.0,0.2);
    }
    return p.y - h;
}

float map_detailed(vec3 p) {
    float freq = SEA_FREQ;
    float amp = SEA_HEIGHT;
    float choppy = SEA_CHOPPY;
    vec2 uv = p.xz; uv.x *= 0.75;
    
    float d, h = 0.0;    
    for(int i = 0; i < ITER_FRAGMENT; i++) {        
    	d = sea_octave((uv+SEA_TIME)*freq,choppy);
    	d += sea_octave((uv-SEA_TIME)*freq,choppy);
        h += d * amp;        
    	uv *= octave_m; freq *= 1.9; amp *= 0.22;
        choppy = mix(choppy,1.0,0.2);
    }
    return p.y - h;
}

vec3 getSeaColor(vec3 p, vec3 n, vec3 l, vec3 eye, vec3 dist) {  
    float fresnel = 1.0 - max(dot(n,-eye),0.0);
    fresnel = pow(fresnel,3.0) * 0.65;
        
    vec3 reflected = getSkyColor(reflect(eye,n));    
    vec3 refracted = SEA_BASE.rgb + diffuse(n,l,80.0) * SEA_WATER_COLOR.rgb * 0.12; 
    
    vec3 color = mix(refracted,reflected,fresnel);
    
    float atten = max(1.0 - dot(dist,dist) * 0.001, 0.0);
    color += SEA_WATER_COLOR.rgb * (p.y - SEA_HEIGHT) * 0.18 * atten;
    
    color += vec3(specular(n,l,eye,60.0));
    
    return color;
}

// tracing
vec3 getNormal(vec3 p, float eps) {
    vec3 n;
    n.y = map_detailed(p);    
    n.x = map_detailed(vec3(p.x+eps,p.y,p.z)) - n.y;
    n.z = map_detailed(vec3(p.x,p.y,p.z+eps)) - n.y;
    n.y = eps;
    return normalize(n);
}

float heightMapTracing(vec3 ori, vec3 dir, out vec3 p) {  
    float tm = 0.0;
    float tx = 1000.0;    
    float hx = map(ori + dir * tx);
    if(hx > 0.0) return tx;   
    float hm = map(ori + dir * tm);    
    float tmid = 0.0;
    for(int i = 0; i < NUM_STEPS; i++) {
        tmid = mix(tm,tx, hm/(hm-hx));                   
        p = ori + dir * tmid;                   
    	float hmid = map(p);
		if(hmid < 0.0) {
        	tx = tmid;
            hx = hmid;
        } else {
            tm = tmid;
            hm = hmid;
        }
    }
    return tmid;
}

// main
void main(){
	vec2 uv = gl_FragCoord.xy / RENDERSIZE.xy;
    uv = uv * 2.0 - 1.0;
    uv.x *= RENDERSIZE.x / RENDERSIZE.y;    
    float time = TIME * 0.3 + iMouse.x*0.01;
        
    // ray
    vec3 ang = vec3(sin(time*3.0)*0.1,sin(time)*0.2+0.3,time);    
    vec3 ori = vec3(0.0,3.5,time*5.0);
    vec3 dir = normalize(vec3(uv.xy,-2.0)); dir.z += length(uv) * 0.15;
    dir = normalize(dir) * fromEuler(ang);
    
    // tracing
    vec3 p;
    heightMapTracing(ori,dir,p);
    vec3 dist = p - ori;
    vec3 n = getNormal(p, dot(dist,dist) * EPSILON_NRM);
    vec3 light = normalize(vec3(0.0,1.0,0.8)); 
             
    // color
    vec3 color = mix(
        getSkyColor(dir),
        getSeaColor(p,n,light,dir,dist),
    	pow(smoothstep(0.0,-0.05,dir.y),0.3));
        
    // post
	gl_FragColor = vec4(pow(color,vec3(0.75)), 1.0);
}
Magic
Site Admin
Posts: 3440
Joined: Wed Apr 09, 2014 9:28 pm

Re: GLSL NODE CUSTOM VAIBLES

Post by Magic »

I would also love Javascript module to be able to send out integers, float, bull and etc. And it would be cool if this can control data sources in other modules.
As I mentioned, modules don't send out data to control variables of other modules. That's not how Magic is designed. But as I also mentioned, there is a possibility in the future that I will allow for custom data sources in the Audio/MIDI window. A JavaScript source would achieve what you are looking for, I think.
On the other note, this ISF generator crashes Magic, any ideas?
Magic shouldn't crash, so I will fix that. But the problem is that ISF requires specifying a DEFAULT value for every variable, and it was missing for the iMouse variable. Try this:

Code: Select all

/*
{
  "CATEGORIES": [
    "Automatically Converted"
  ],
  "DESCRIPTION": "Automatically converted from https://www.shadertoy.com/view/Ms2SD1",
  "IMPORTED": [
    
  ],
  "INPUTS": [
    {
      "NAME": "iMouse",
      "TYPE": "point2D",
	  "DEFAULT": [
		0.0,
		0.0
	  ]
    },
    {
      "NAME": "SEA_FREQ",
      "MIN": 0.0,
      "MAX": 1.0,
      "TYPE": "float",
      "DEFAULT": 0.16
    },
    {
      "NAME": "SEA_CHOPPY",
      "MIN": 0.0,
      "MAX": 8.0,
      "TYPE": "float",
      "DEFAULT": 4.0
    },
    {
      "NAME": "SEA_HEIGHT",
      "MIN": 0.0,
      "MAX": 3.0,
      "TYPE": "float",
      "DEFAULT": 0.6
    },
    {
      "NAME": "SEA_SPEED",
      "MIN": 0.0,
      "MAX": 2.0,
      "TYPE": "float",
      "DEFAULT": 0.8
    },
   {
      "NAME": "SEA_BASE",
      "TYPE": "color",
      "DEFAULT": [
         0.1,
         0.19,
         0.22,
         1.0
      ]
   },
   {
      "NAME": "SEA_WATER_COLOR",
      "TYPE": "color",
      "DEFAULT": [
         0.8,
         0.9,
         0.6,
         1.0
      ]
   }   
  ]
}
*/


// "Seascape" by Alexander Alekseev aka TDM - 2014
// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.

const int NUM_STEPS = 8;
const float PI       = 3.1415;
const float EPSILON   = 1e-3;
float EPSILON_NRM   = 0.1 / RENDERSIZE.x;

// sea
const int ITER_GEOMETRY = 3;
const int ITER_FRAGMENT = 5;
//const float SEA_HEIGHT = 0.6;
//const float SEA_CHOPPY = 4.0;
//const float SEA_SPEED = 0.8;
//const float SEA_FREQ = 0.16;
//const vec3 SEA_BASE = vec3(0.1,0.19,0.22);
//const vec3 SEA_WATER_COLOR = vec3(0.8,0.9,0.6);
float SEA_TIME = TIME * SEA_SPEED;
mat2 octave_m = mat2(1.6,1.2,-1.2,1.6);

// math
mat3 fromEuler(vec3 ang) {
   vec2 a1 = vec2(sin(ang.x),cos(ang.x));
    vec2 a2 = vec2(sin(ang.y),cos(ang.y));
    vec2 a3 = vec2(sin(ang.z),cos(ang.z));
    mat3 m;
    m[0] = vec3(a1.y*a3.y+a1.x*a2.x*a3.x,a1.y*a2.x*a3.x+a3.y*a1.x,-a2.y*a3.x);
   m[1] = vec3(-a2.y*a1.x,a1.y*a2.y,a2.x);
   m[2] = vec3(a3.y*a1.x*a2.x+a1.y*a3.x,a1.x*a3.x-a1.y*a3.y*a2.x,a2.y*a3.y);
   return m;
}
float hash( vec2 p ) {
   float h = dot(p,vec2(127.1,311.7));   
    return fract(sin(h)*43758.5453123);
}
float noise( in vec2 p ) {
    vec2 i = floor( p );
    vec2 f = fract( p );   
   vec2 u = f*f*(3.0-2.0*f);
    return -1.0+2.0*mix( mix( hash( i + vec2(0.0,0.0) ), 
                     hash( i + vec2(1.0,0.0) ), u.x),
                mix( hash( i + vec2(0.0,1.0) ), 
                     hash( i + vec2(1.0,1.0) ), u.x), u.y);
}

// lighting
float diffuse(vec3 n,vec3 l,float p) {
    return pow(dot(n,l) * 0.4 + 0.6,p);
}
float specular(vec3 n,vec3 l,vec3 e,float s) {    
    float nrm = (s + 8.0) / (3.1415 * 8.0);
    return pow(max(dot(reflect(e,n),l),0.0),s) * nrm;
}

// sky
vec3 getSkyColor(vec3 e) {
    e.y = max(e.y,0.0);
    vec3 ret;
    ret.x = pow(1.0-e.y,2.0);
    ret.y = 1.0-e.y;
    ret.z = 0.6+(1.0-e.y)*0.4;
    return ret;
}

// sea
float sea_octave(vec2 uv, float choppy) {
    uv += noise(uv);        
    vec2 wv = 1.0-abs(sin(uv));
    vec2 swv = abs(cos(uv));    
    wv = mix(wv,swv,wv);
    return pow(1.0-pow(wv.x * wv.y,0.65),choppy);
}

float map(vec3 p) {
    float freq = SEA_FREQ;
    float amp = SEA_HEIGHT;
    float choppy = SEA_CHOPPY;
    vec2 uv = p.xz; uv.x *= 0.75;
    
    float d, h = 0.0;    
    for(int i = 0; i < ITER_GEOMETRY; i++) {        
       d = sea_octave((uv+SEA_TIME)*freq,choppy);
       d += sea_octave((uv-SEA_TIME)*freq,choppy);
        h += d * amp;        
       uv *= octave_m; freq *= 1.9; amp *= 0.22;
        choppy = mix(choppy,1.0,0.2);
    }
    return p.y - h;
}

float map_detailed(vec3 p) {
    float freq = SEA_FREQ;
    float amp = SEA_HEIGHT;
    float choppy = SEA_CHOPPY;
    vec2 uv = p.xz; uv.x *= 0.75;
    
    float d, h = 0.0;    
    for(int i = 0; i < ITER_FRAGMENT; i++) {        
       d = sea_octave((uv+SEA_TIME)*freq,choppy);
       d += sea_octave((uv-SEA_TIME)*freq,choppy);
        h += d * amp;        
       uv *= octave_m; freq *= 1.9; amp *= 0.22;
        choppy = mix(choppy,1.0,0.2);
    }
    return p.y - h;
}

vec3 getSeaColor(vec3 p, vec3 n, vec3 l, vec3 eye, vec3 dist) {  
    float fresnel = 1.0 - max(dot(n,-eye),0.0);
    fresnel = pow(fresnel,3.0) * 0.65;
        
    vec3 reflected = getSkyColor(reflect(eye,n));    
    vec3 refracted = SEA_BASE.rgb + diffuse(n,l,80.0) * SEA_WATER_COLOR.rgb * 0.12; 
    
    vec3 color = mix(refracted,reflected,fresnel);
    
    float atten = max(1.0 - dot(dist,dist) * 0.001, 0.0);
    color += SEA_WATER_COLOR.rgb * (p.y - SEA_HEIGHT) * 0.18 * atten;
    
    color += vec3(specular(n,l,eye,60.0));
    
    return color;
}

// tracing
vec3 getNormal(vec3 p, float eps) {
    vec3 n;
    n.y = map_detailed(p);    
    n.x = map_detailed(vec3(p.x+eps,p.y,p.z)) - n.y;
    n.z = map_detailed(vec3(p.x,p.y,p.z+eps)) - n.y;
    n.y = eps;
    return normalize(n);
}

float heightMapTracing(vec3 ori, vec3 dir, out vec3 p) {  
    float tm = 0.0;
    float tx = 1000.0;    
    float hx = map(ori + dir * tx);
    if(hx > 0.0) return tx;   
    float hm = map(ori + dir * tm);    
    float tmid = 0.0;
    for(int i = 0; i < NUM_STEPS; i++) {
        tmid = mix(tm,tx, hm/(hm-hx));                   
        p = ori + dir * tmid;                   
       float hmid = map(p);
      if(hmid < 0.0) {
           tx = tmid;
            hx = hmid;
        } else {
            tm = tmid;
            hm = hmid;
        }
    }
    return tmid;
}

// main
void main(){
   vec2 uv = gl_FragCoord.xy / RENDERSIZE.xy;
    uv = uv * 2.0 - 1.0;
    uv.x *= RENDERSIZE.x / RENDERSIZE.y;    
    float time = TIME * 0.3 + iMouse.x*0.01;
        
    // ray
    vec3 ang = vec3(sin(time*3.0)*0.1,sin(time)*0.2+0.3,time);    
    vec3 ori = vec3(0.0,3.5,time*5.0);
    vec3 dir = normalize(vec3(uv.xy,-2.0)); dir.z += length(uv) * 0.15;
    dir = normalize(dir) * fromEuler(ang);
    
    // tracing
    vec3 p;
    heightMapTracing(ori,dir,p);
    vec3 dist = p - ori;
    vec3 n = getNormal(p, dot(dist,dist) * EPSILON_NRM);
    vec3 light = normalize(vec3(0.0,1.0,0.8)); 
             
    // color
    vec3 color = mix(
        getSkyColor(dir),
        getSeaColor(p,n,light,dir,dist),
       pow(smoothstep(0.0,-0.05,dir.y),0.3));
        
    // post
   gl_FragColor = vec4(pow(color,vec3(0.75)), 1.0);
}
bareimage
Posts: 24
Joined: Wed Sep 02, 2015 5:14 am

Re: GLSL NODE CUSTOM VAIBLES

Post by bareimage »

It works! Thanks a lot.

Found another issue, well not really issue, but if some one will try to load FS file into GLSL node it will crash the software. Just for people to know...
Magic
Site Admin
Posts: 3440
Joined: Wed Apr 09, 2014 9:28 pm

Re: GLSL NODE CUSTOM VAIBLES

Post by Magic »

Hmm, can you attach a file that crashes it? I can't get it to crash.
Post Reply