Week 9 Homework

I ported a few GLSL shaders to unity. It was pretty difficult for me as I can’t really do the complicated UI of those sorts of programs. I prefer to just stick to code. I was able to follow some other tutorials and get some help and got this scene working. You can tap and select a shader to view. Eventually, I want this to become a full app where I can show my shader and motion art. It’s a long way from there though.

Here’s some screenshots of the scene:

_week9

I also tried (and succeeded) to do this in glslViewer directly, and here is a GIF of that… (its my circles moving back and forth thing)

Week 10 Homework

I progressed on my gold shader to include cubemaps and reflections. This was a bit challenging for me. I used GlslViewer to code and compile/render. Some notes:

– I had to use 3D noise instead of 2D noise. This allowed for the flow of the noise to go around the corner of the cube. When using 3D shapes for this shader, up until now I had been using just 2D noise on each face, sort of “cheating”. Now it is a proper flowing 3D noise cube.

– I took away the gold colouring so that only the reflections remained, this caused me to have to really amp the specular value so that you could actually see the reflections

– I would like it if each face of the cube, the noise animated not in any direction but just on the face itself. it’s hard for me to describe. on the top and bottom faces, the noise animates exactly how I want, but on the other sides it sort of “flows” toward an edge. i’d rather it not do this but I couldn’t figure out how

to run this shader, you need glslViewer installed on your machine and then just run this command from within the shaders file folder

glslviewer shader.frag cube.obj -C cubemap.png

View the code and file son gitlab:
https://gitlab.com/nicolevella_ocad/cubemap-shader

screenshot

Midterm – The Time Knife by Ryan Boyd & Joshua Linton

For the mid-term, Joshua Linton & I decided to create a digital mirror that resembled the description of the Time Knife given in the show, The Good Place, which is an extra dimensional concept illustrated as, “a trillion different realities folding onto each other like tiny sheets of metal forming a single blade.”  Our shader explores this concept by taking the webcam capture and turning it into strings of frames stacked on top of each other, phasing at high speed into a void in a sort of sine-like shape, while the scene rotates.  We also decided to create a 3 dimensional reference point to add depth to the scene, which rotates at the speed at which the point of view is rotated in the void, as if the viewer is orbiting this sphere in physical space.  Furthermore, we added interactivity by mapping the x and y position of the mouse, so that when you move your mouse left or right, the scene rotates forward or backward (on top of its own passive rotation), and also increases the speed of the phasing images based on mouse y position.  Finally, we mapped the rotation of the sphere to match the mouse x rotation, and also translated the sphere up and down as well as changed the stroke/fill based on mouse y position.   I created the base webcam capture sketch & grid tiles, mapped the mouse positions and created the push pop sphere while Joshua created the fragment shader that alters the image and ultimately creates the void.  This experiment was an extremely intriguing exploration into metaphysical extra-dimensions in 2d space.

p5 sketch:
https://editor.p5js.org/ryanmackboyd/sketches/WwGKhoyUW

Full screen:

https://editor.p5js.org/ryanmackboyd/full/WwGKhoyUW

mid1 mid2 mid3

Week 10

For this week I was pretty amazed at how easy shader graph makes things.

2021-04-18-20_08_38-5-unity-magma-shader-youtube

Magma Shader

I created this Magma shader after experimenting with a rock texture I found online. I had originally wanted to make a sphere have cracks with energy seeping out of them, but then I got the idea to make magma instead. I’m also using some bloom to achieve the bright spots.

2021-04-18-20_08_01-5-unity-cloaking-shader-youtube

Cloaking Shader

I got inspired to make a shader depicting a common game mechanic of “cloaking” after watching the alpha clip lesson.

Week 9

2021-04-18-01_00_11-shaderart-week9-image-homework-pc-mac-linux-standalone-unity-2019-4-24f

For this weeks homework it was eye opening to finally be able to port our shaders to Unity as well as learn more about how rendering in Unity works. Previously the graphics and shader side of Unity has kind of been a black box to me but it was great finally being able to understand it all.

I found it a bit confusing converting my shaders to HLSL, having to get used to the new structure as well as all the new keywords and functions.

Pictured is some primitives with different surface shaders applied and the top cube is one of my Week 1 shaders converted to HLSL.

 

Week 3

This week I had a lot of fun working with simplex noise and adding randomness to my sketches. I experimented with the complex shape function I used in my previous sketches and integrated noise into it, I found it started to look really interesting so I kept on messing around until I got to what you see below. Noise and randomness are very powerful tools to add complexity to a shader and I’m excited to see what else is possible.


// Author: Brian Nguyen
// Title: Random Noise Shape without Grid

#ifdef GL_ES
precision mediump float;
#endif

uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;
#define PI 3.14159265359
#define TWO_PI 6.28318530718

float random (vec2 st) {
return fract(sin(dot(st.xy,
vec2(12.9898,78.233)))*
43758.5453123);
}

vec3 permute(vec3 x) { return mod(((x*34.0)+1.0)*x, 289.0); }
float snoise(vec2 v){
const vec4 C = vec4(0.211324865405187, 0.366025403784439,
-0.577350269189626, 0.024390243902439);
vec2 i = floor(v + dot(v, C.yy) );
vec2 x0 = v - i + dot(i, C.xx);
vec2 i1;
i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
vec4 x12 = x0.xyxy + C.xxzz;
x12.xy -= i1;
i = mod(i, 289.0);
vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 ))
+ i.x + vec3(0.0, i1.x, 1.0 ));
vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy),
dot(x12.zw,x12.zw)), 0.0);
m = m*m ;
m = m*m ;
vec3 x = 2.0 * fract(p * C.www) - 1.0;
vec3 h = abs(x) - 0.5;
vec3 ox = floor(x + 0.5);
vec3 a0 = x - ox;
m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h );
vec3 g;
g.x = a0.x * x0.x + h.x * x0.y;
g.yz = a0.yz * x12.xz + h.yz * x12.yw;
return 130.0 * dot(m, g);
}

float drawSidedShape(vec2 st, vec2 pos, float size, int sides, vec2 indices) {
float d = 0.0;
// st = st *2.-1.;
st -= pos;

// Number of sides of your shape
int N = sides;

// Angle and radius from the current pixel
float a = atan(st.x,st.y)+PI;
float r = TWO_PI/float(N);

// Shaping function that modulate the distance
d = cos(floor(sin(u_time+snoise(st + indices)*2.096)*1.0+a/r)*r-a)*length(st);

d = smoothstep( 0.734 ,1.0-size, 1.0-d);

return d;
}

vec3 hsv2rgb(vec3 c)
{
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}

void main() {

vec2 st = gl_FragCoord.xy/u_resolution.xy;
st.x *= u_resolution.x/u_resolution.y;

vec2 indices;

// st = createGrid( st, vec2(5.), indices);

vec3 color = vec3(0.);

float r = 0.0;
r += drawSidedShape(st,vec2(.5,.5),0.016,9, indices);
float bg = snoise(st+vec2(u_time+snoise(st), u_time+snoise(st)))*0.2-0.1;

color = mix( color, hsv2rgb(vec3(float(st.y+u_time),1.0,1.00)), bg);
color = mix( color, hsv2rgb(vec3(float(st.x),0.336,1.00)), r);

gl_FragColor = vec4(color,1.0);
}

Week 2

For this shader I tried out a lot of different patterns and shapes. I started with using rectangles that span across cells but I later turned to circles as I thought they were more mesmerizing especially when in motion.

While working on it I got more comfortable with the 4 cell system where at first it was kind of confusing me.

// Author: Brian Nguyen
// Title: 2D Pattern

#ifdef GL_ES
precision mediump float;
#endif

uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;

#define PI 3.14159265359
#define TWO_PI 6.28318530718

vec2 createGrid(in vec2 st,in vec2 grid,out vec2 indices){
 
 // multiply by the number of cells
 // [0,1] range => [0,10] (for example)
 st*=grid;
 
 // get the cell indices
 // for example, in a grid of 10x10:
 // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
 indices=floor(st);
 
 // use fract to get the fractional amount of st
 // 9.5 => 0.5
 // shows the xy coordinate in each cell
 st=fract(st);
 
 return st;
}

float drawSidedShape(vec2 st,vec2 pos,float size,int sides,vec2 indices){
 float d=0.;
 // st = st *2.-1.;
 st-=pos;
 
 // Number of sides of your shape
 int N=sides;
 
 // Angle and radius from the current pixel
 float a=atan(st.x,st.y)+PI;
 float r=TWO_PI/float(N);
 
 // Shaping function that modulate the distance
 d=cos(floor(sin(u_time)*1.+a/r)*r-a)*length(st);
 
 d=smoothstep(.734,1.-size,1.-d);
 
 return d;
}

float drawCircle(vec2 st,vec2 pos,float size){
 float d=distance(st,pos);
 // step shows values > argument 1, and we want the opposite
 // so we invert the results by subtraction 1.0 - the value
 return 1.-step(size,d);
}
void main(){
 
 vec2 st=gl_FragCoord.xy/u_resolution.xy;
 st.x*=u_resolution.x/u_resolution.y;
 
 vec2 indices;
 
 st=createGrid(st,vec2(5.),indices);
 
 vec3 color=vec3(0.);
 
 if(mod(indices.x,2.)==0.&&mod(indices.y,2.)==0.){
 
 // lower left cell - triangle fan
 
 color=vec3(0.);
 float r=0.;
 r+=drawSidedShape(st,vec2(.5,.5),.016,3,indices);
 color=mix(color,vec3(1.),r);
 
 }else if(mod(indices.x,2.)==1.&&mod(indices.y,2.)==0.){
 
 // lower right cell - orange bg with blue circles
 color=vec3(.945,.549,.001);
 float r=0.;
 
 for(int k=0;k<20;k++){
 for(int i=0;i<20;i++){
 r+=drawCircle(st,vec2(0.+float(i)*.2,0.+float(k)*.2)+vec2(0.,sin(u_time))-1.,.05);
 }
 
 }
 
 color=mix(color,vec3(.023,.530,.905),r);
 
 }else if(mod(indices.x,2.)==0.&&mod(indices.y,2.)==1.){
 
 // upper left - cyan with blue scircles
 color=vec3(.320,.945,.733);
 float r=0.;
 
 for(int k=0;k<20;k++){
 for(int i=0;i<20;i++){
 r+=drawCircle(st,vec2(0.+float(i)*.2,0.+float(k)*.2)+vec2(0.,sin(u_time))-1.,.05);
 }
 
 }
 
 color=mix(color,vec3(.023,.530,.905),r);
 
 }else{
 
 // upper right - white bg with black circles
 
 color=vec3(.940,.940,.940);
 float r=0.;
 
 for(int k=0;k<20;k++){
 for(int i=0;i<20;i++){
 r+=drawCircle(st,vec2(0.+float(i)*.2,0.+float(k)*.2)+vec2(0.,sin(u_time))-1.,.05);
 }
 
 }
 
 color=mix(color,vec3(0.),r);
 }
 
 gl_FragColor=vec4(color,1.);
}

Week 1

This week I got an overall re-introduction into shaders and having to re-learn concepts and understanding of the basic functions. One part I particularly struggled on was the exercise on the colors chapter where you’re supposed to make a flag. My code wasn’t working when I was sure it was supposed to. It turned out to be a problem with the order of operations.

My favorite shader was created was after creating an HSV gradient and then experimenting with different shaping functions. Eventually I settled on an interesting combination using sin() to control the mixing and mixing between HSV functions. One of the functions is influenced by the y axis, and the other by the x axis which resulted in some interesting combinations when they were mixed. This shader incorporates a lot of motion and creates new random patterns overtime that can’t be experienced from screenshots so I recommend loading it up yourself.


// Author: Brian Nguyen
// Title: Gradient Shader Trippy 2

#ifdef GL_ES
precision mediump float;
#endif

#define PI 3.14159265359

uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;

vec3 colorA = vec3(0.155,0.903,0.912);
vec3 colorB = vec3(0.983,0.029,1.000);

vec3 hsb2rgb( in vec3 c ){
vec3 rgb = clamp(abs(mod(c.x*6.0+vec3(0.0,4.0,2.0),
6.0)-3.0)-1.0,
0.0,
1.0 );
rgb = rgb*rgb*(3.0-2.0*rgb);
return c.z * mix(vec3(1.0), rgb, c.y);
}

void main() {
vec2 st = gl_FragCoord.xy/u_resolution.xy;
vec3 color = vec3(0.0);
color = mix(hsb2rgb(vec3(st.x - u_time * 0.1,1.0,1.0)), hsb2rgb(vec3(st.y + u_time * 0.1,1.0,1.0)), sin(u_time * 1.0) * 10.0);
color = mix(color, vec3(0.905,0.008,0.138), sin(u_time * 2.0) * 10.0);
gl_FragColor = vec4(color,1.0);
}

 

My second shader also incorporates motion but I somehow ended up creating an effect of the colors looping over themselves.

// Author: Brian Nguyen
// Title: Gradient Shader HSV - Wild 3

#ifdef GL_ES
precision mediump float;
#endif

#define PI 3.14159265359

uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;

vec3 colorA = vec3(0.155,0.903,0.912);
vec3 colorB = vec3(0.983,0.029,1.000);

vec3 hsb2rgb( in vec3 c ){
 vec3 rgb = clamp(abs(mod(c.x*6.0+vec3(0.0,4.0,2.0),
 6.0)-3.0)-1.0,
 0.0,
 1.0 );
 rgb = rgb*rgb*(3.0-2.0*rgb);
 return c.z * mix(vec3(1.0), rgb, c.y);
}

void main() {
 vec2 st = gl_FragCoord.xy/u_resolution.xy;
 vec3 color = vec3(0.0);

 vec3 pct = vec3(st.x);

 // pct.r = smoothstep(0.0,1.0, st.x);
 // pct.g = sin(st.x*PI);
 // pct.b = pow(st.x,0.5);

 color = mix(hsb2rgb(vec3(u_time,1.0,3.776)), hsb2rgb(vec3(st.y + u_time,1.0,4.496)), pct);



 gl_FragColor = vec4(color,1.0);
}

My third shader is a mix of two color functions moving in opposite vertical directions and then I’m using sin() to fade the sketch in and out.

// Author: Brian Nguyen
// Title: Gradient Shader Fading

#ifdef GL_ES
precision mediump float;
#endif

#define PI 3.14159265359

uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;

vec3 colorA = vec3(0.155,0.903,0.912);
vec3 colorB = vec3(0.983,0.029,1.000);

vec3 hsb2rgb( in vec3 c ){
 vec3 rgb = clamp(abs(mod(c.x*6.0+vec3(0.0,4.0,2.0),
 6.0)-3.0)-1.0,
 0.0,
 1.0 );
 rgb = rgb*rgb*(3.0-2.0*rgb);
 return c.z * mix(vec3(1.0), rgb, c.y);
}

void main() {
 vec2 st = gl_FragCoord.xy/u_resolution.xy;
 vec3 color = vec3(0.0);

 vec3 pct = vec3(st.x);

 // pct.r = smoothstep(0.0,1.0, st.x);
 // pct.g = sin(st.x*PI);
 // pct.b = pow(st.x,0.5);

 color = mix(hsb2rgb(vec3(st.y - u_time,1.0,1.0)), hsb2rgb(vec3(st.y + u_time * 2.0,1.0,1.0)), pct);
 color = color * abs(sin(u_time));


 gl_FragColor = vec4(color,1.0);
}