Pārlūkot izejas kodu

ADDED: Missing GLSL120 shaders

Ray 1 mēnesi atpakaļ
vecāks
revīzija
8dae39fbda
22 mainītis faili ar 1141 papildinājumiem un 0 dzēšanām
  1. 86 0
      examples/shaders/resources/shaders/glsl100/shadowmap.fs
  2. 32 0
      examples/shaders/resources/shaders/glsl100/shadowmap.vs
  3. 24 0
      examples/shaders/resources/shaders/glsl120/color_mix.fs
  4. 58 0
      examples/shaders/resources/shaders/glsl120/cubes_panning.fs
  5. 57 0
      examples/shaders/resources/shaders/glsl120/deferred_shading.fs
  6. 16 0
      examples/shaders/resources/shaders/glsl120/deferred_shading.vs
  7. 58 0
      examples/shaders/resources/shaders/glsl120/eratosthenes.fs
  8. 34 0
      examples/shaders/resources/shaders/glsl120/gbuffer.fs
  9. 60 0
      examples/shaders/resources/shaders/glsl120/gbuffer.vs
  10. 17 0
      examples/shaders/resources/shaders/glsl120/hybrid_raster.fs
  11. 291 0
      examples/shaders/resources/shaders/glsl120/hybrid_raymarch.fs
  12. 80 0
      examples/shaders/resources/shaders/glsl120/julia_set.fs
  13. 36 0
      examples/shaders/resources/shaders/glsl120/lighting_instancing.vs
  14. 22 0
      examples/shaders/resources/shaders/glsl120/mask.fs
  15. 32 0
      examples/shaders/resources/shaders/glsl120/outline.fs
  16. 37 0
      examples/shaders/resources/shaders/glsl120/reload.fs
  17. 75 0
      examples/shaders/resources/shaders/glsl120/spotlight.fs
  18. 19 0
      examples/shaders/resources/shaders/glsl120/tiling.fs
  19. 15 0
      examples/shaders/resources/shaders/glsl120/vertex_displacement.fs
  20. 43 0
      examples/shaders/resources/shaders/glsl120/vertex_displacement.vs
  21. 32 0
      examples/shaders/resources/shaders/glsl120/wave.fs
  22. 17 0
      examples/shaders/resources/shaders/glsl120/write_depth.fs

+ 86 - 0
examples/shaders/resources/shaders/glsl100/shadowmap.fs

@@ -0,0 +1,86 @@
+#version 100
+
+precision mediump float;
+
+// This shader is based on the basic lighting shader
+// This only supports one light, which is directional, and it (of course) supports shadows
+
+// Input vertex attributes (from vertex shader)
+varying vec3 fragPosition;
+varying vec2 fragTexCoord;
+//varying in vec4 fragColor;
+varying vec3 fragNormal;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+// Input lighting values
+uniform vec3 lightDir;
+uniform vec4 lightColor;
+uniform vec4 ambient;
+uniform vec3 viewPos;
+
+// Input shadowmapping values
+uniform mat4 lightVP; // Light source view-projection matrix
+uniform sampler2D shadowMap;
+
+uniform int shadowMapResolution;
+
+void main()
+{
+    // Texel color fetching from texture sampler
+    vec4 texelColor = texture2D(texture0, fragTexCoord);
+    vec3 lightDot = vec3(0.0);
+    vec3 normal = normalize(fragNormal);
+    vec3 viewD = normalize(viewPos - fragPosition);
+    vec3 specular = vec3(0.0);
+
+    vec3 l = -lightDir;
+
+    float NdotL = max(dot(normal, l), 0.0);
+    lightDot += lightColor.rgb*NdotL;
+
+    float specCo = 0.0;
+    if (NdotL > 0.0) specCo = pow(max(0.0, dot(viewD, reflect(-(l), normal))), 16.0); // 16 refers to shine
+    specular += specCo;
+
+    vec4 finalColor = (texelColor*((colDiffuse + vec4(specular, 1.0))*vec4(lightDot, 1.0)));
+
+    // Shadow calculations
+    vec4 fragPosLightSpace = lightVP*vec4(fragPosition, 1);
+    fragPosLightSpace.xyz /= fragPosLightSpace.w; // Perform the perspective division
+    fragPosLightSpace.xyz = (fragPosLightSpace.xyz + 1.0)/2.0; // Transform from [-1, 1] range to [0, 1] range
+    vec2 sampleCoords = fragPosLightSpace.xy;
+    float curDepth = fragPosLightSpace.z;
+
+    // Slope-scale depth bias: depth biasing reduces "shadow acne" artifacts, where dark stripes appear all over the scene
+    // The solution is adding a small bias to the depth
+    // In this case, the bias is proportional to the slope of the surface, relative to the light
+    float bias = max(0.0008*(1.0 - dot(normal, l)), 0.00008);
+    int shadowCounter = 0;
+    const int numSamples = 9;
+    
+    // PCF (percentage-closer filtering) algorithm:
+    // Instead of testing if just one point is closer to the current point,
+    // we test the surrounding points as well
+    // This blurs shadow edges, hiding aliasing artifacts
+    vec2 texelSize = vec2(1.0/float(shadowMapResolution));
+    for (int x = -1; x <= 1; x++)
+    {
+        for (int y = -1; y <= 1; y++)
+        {
+            float sampleDepth = texture2D(shadowMap, sampleCoords + texelSize*vec2(x, y)).r;
+            if (curDepth - bias > sampleDepth) shadowCounter++;
+        }
+    }
+    
+    finalColor = mix(finalColor, vec4(0, 0, 0, 1), float(shadowCounter)/float(numSamples));
+
+    // Add ambient lighting whether in shadow or not
+    finalColor += texelColor*(ambient/10.0)*colDiffuse;
+
+    // Gamma correction
+    finalColor = pow(finalColor, vec4(1.0/2.2));
+    gl_FragColor = finalColor;
+}

+ 32 - 0
examples/shaders/resources/shaders/glsl100/shadowmap.vs

@@ -0,0 +1,32 @@
+#version 100
+
+// Input vertex attributes
+attribute vec3 vertexPosition;
+attribute vec2 vertexTexCoord;
+attribute vec3 vertexNormal;
+attribute vec4 vertexColor;
+
+// Input uniform values
+uniform mat4 mvp;
+uniform mat4 matModel;
+uniform mat4 matNormal;
+
+// Output vertex attributes (to fragment shader)
+varying vec3 fragPosition;
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+varying vec3 fragNormal;
+
+// NOTE: Add your custom variables here
+
+void main()
+{
+    // Send vertex attributes to fragment shader
+    fragPosition = vec3(matModel*vec4(vertexPosition, 1.0));
+    fragTexCoord = vertexTexCoord;
+    fragColor = vertexColor;
+    fragNormal = normalize(vec3(matNormal*vec4(vertexNormal, 1.0)));
+
+    // Calculate final vertex position
+    gl_Position = mvp*vec4(vertexPosition, 1.0);
+}

+ 24 - 0
examples/shaders/resources/shaders/glsl120/color_mix.fs

@@ -0,0 +1,24 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform sampler2D texture1;
+uniform vec4 colDiffuse;
+
+uniform float divider;
+
+void main()
+{
+    // Texel color fetching from texture sampler
+    vec4 texelColor0 = texture2D(texture0, fragTexCoord);
+    vec4 texelColor1 = texture2D(texture1, fragTexCoord);
+
+    float x = fract(fragTexCoord.s);
+    float final = smoothstep(divider - 0.1, divider + 0.1, x);
+
+    gl_FragColor = mix(texelColor0, texelColor1, final);
+}

+ 58 - 0
examples/shaders/resources/shaders/glsl120/cubes_panning.fs

@@ -0,0 +1,58 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Custom variables
+const float PI = 3.14159265358979323846;
+uniform float uTime;
+
+float divisions = 5.0;
+float angle = 0.0;
+
+vec2 VectorRotateTime(vec2 v, float speed)
+{
+    float time = uTime*speed;
+    float localTime = fract(time);  // The time domain this works on is 1 sec
+
+    if ((localTime >= 0.0) && (localTime < 0.25)) angle = 0.0;
+    else if ((localTime >= 0.25) && (localTime < 0.50)) angle = PI/4.0*sin(2.0*PI*localTime - PI/2.0);
+    else if ((localTime >= 0.50) && (localTime < 0.75)) angle = PI*0.25;
+    else if ((localTime >= 0.75) && (localTime < 1.00)) angle = PI/4.0*sin(2.0*PI*localTime);
+
+    // Rotate vector by angle
+    v -= 0.5;
+    v =  mat2(cos(angle), -sin(angle), sin(angle), cos(angle))*v;
+    v += 0.5;
+
+    return v;
+}
+
+float Rectangle(in vec2 st, in float size, in float fill)
+{
+  float roundSize = 0.5 - size/2.0;
+  float left = step(roundSize, st.x);
+  float top = step(roundSize, st.y);
+  float bottom = step(roundSize, 1.0 - st.y);
+  float right = step(roundSize, 1.0 - st.x);
+
+  return (left*bottom*right*top)*fill;
+}
+
+void main()
+{
+    vec2 fragPos = fragTexCoord;
+    fragPos.xy += uTime/9.0;
+
+    fragPos *= divisions;
+    vec2 ipos = floor(fragPos);  // Get the integer coords
+    vec2 fpos = fract(fragPos);  // Get the fractional coords
+
+    fpos = VectorRotateTime(fpos, 0.2);
+
+    float alpha = Rectangle(fpos, 0.216, 1.0);
+    vec3 color = vec3(0.3, 0.3, 0.3);
+
+    gl_FragColor = vec4(color, alpha);
+}

+ 57 - 0
examples/shaders/resources/shaders/glsl120/deferred_shading.fs

@@ -0,0 +1,57 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D gPosition;
+uniform sampler2D gNormal;
+uniform sampler2D gAlbedoSpec;
+
+struct Light {
+    int enabled;
+    int type;       // Unused in this demo
+    vec3 position;
+    vec3 target;    // Unused in this demo
+    vec4 color;
+};
+
+const int NR_LIGHTS = 4;
+uniform Light lights[NR_LIGHTS];
+uniform vec3 viewPosition;
+
+const float QUADRATIC = 0.032;
+const float LINEAR = 0.09;
+
+void main()
+{
+    vec3 fragPosition = texture2D(gPosition, fragTexCoord).rgb;
+    vec3 normal = texture2D(gNormal, fragTexCoord).rgb;
+    vec3 albedo = texture2D(gAlbedoSpec, fragTexCoord).rgb;
+    float specular = texture2D(gAlbedoSpec, fragTexCoord).a;
+
+    vec3 ambient = albedo*vec3(0.1);
+    vec3 viewDirection = normalize(viewPosition - fragPosition);
+
+    for (int i = 0; i < NR_LIGHTS; ++i)
+    {
+        if (lights[i].enabled == 0) continue;
+        vec3 lightDirection = lights[i].position - fragPosition;
+        vec3 diffuse = max(dot(normal, lightDirection), 0.0)*albedo*lights[i].color.xyz;
+
+        vec3 halfwayDirection = normalize(lightDirection + viewDirection);
+        float spec = pow(max(dot(normal, halfwayDirection), 0.0), 32.0);
+        vec3 specular = specular*spec*lights[i].color.xyz;
+
+        // Attenuation
+        float distance = length(lights[i].position - fragPosition);
+        float attenuation = 1.0/(1.0 + LINEAR*distance + QUADRATIC*distance*distance);
+        diffuse *= attenuation;
+        specular *= attenuation;
+        ambient += diffuse + specular;
+    }
+
+    gl_FragColor = vec4(ambient, 1.0);
+}
+

+ 16 - 0
examples/shaders/resources/shaders/glsl120/deferred_shading.vs

@@ -0,0 +1,16 @@
+#version 120
+
+// Input vertex attributes
+attribute vec3 vertexPosition;
+attribute vec2 vertexTexCoord;
+
+// Output vertex attributes (to fragment shader)
+varying vec2 fragTexCoord;
+
+void main()
+{
+    fragTexCoord = vertexTexCoord;
+
+    // Calculate final vertex position
+    gl_Position = vec4(vertexPosition, 1.0);    
+}

+ 58 - 0
examples/shaders/resources/shaders/glsl120/eratosthenes.fs

@@ -0,0 +1,58 @@
+#version 120
+
+/*************************************************************************************
+
+  The Sieve of Eratosthenes -- a simple shader by ProfJski
+  An early prime number sieve: https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
+
+  The screen is divided into a square grid of boxes, each representing an integer value
+  Each integer is tested to see if it is a prime number.  Primes are colored white
+  Non-primes are colored with a color that indicates the smallest factor which evenly divdes our integer
+
+  You can change the scale variable to make a larger or smaller grid
+  Total number of integers displayed = scale squared, so scale = 100 tests the first 10,000 integers
+
+  WARNING: If you make scale too large, your GPU may bog down!
+
+***************************************************************************************/
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Make a nice spectrum of colors based on counter and maxSize
+vec4 Colorizer(float counter, float maxSize)
+{
+    float red = 0.0, green = 0.0, blue = 0.0;
+    float normsize = counter/maxSize;
+
+    red = smoothstep(0.3, 0.7, normsize);
+    green = sin(3.14159*normsize);
+    blue = 1.0 - smoothstep(0.0, 0.4, normsize);
+
+    return vec4(0.8*red, 0.8*green, 0.8*blue, 1.0);
+}
+
+void main()
+{
+    vec4 color = vec4(1.0);
+    float scale = 1000.0; // Makes 100x100 square grid. Change this variable to make a smaller or larger grid
+    float value = scale*floor(fragTexCoord.y*scale) + floor(fragTexCoord.x*scale);  // Group pixels into boxes representing integer values
+    int valuei = int(value);
+
+    //if ((valuei == 0) || (valuei == 1) || (valuei == 2)) gl_FragColor = vec4(1.0);
+    //else
+    {
+        //for (int i = 2; (i < int(max(2.0, sqrt(value) + 1.0))); i++)
+        // NOTE: On GLSL 100 for loops are restricted and loop condition must be a constant
+        // Tested on RPI, it seems loops are limited around 60 iteractions
+        for (int i = 2; i < 48; i++)
+        {
+            if ((value - float(i)*floor(value/float(i))) <= 0.0)
+            {
+                gl_FragColor = Colorizer(float(i), scale);
+                //break;    // Uncomment to color by the largest factor instead
+            }
+        }
+    }
+}

+ 34 - 0
examples/shaders/resources/shaders/glsl120/gbuffer.fs

@@ -0,0 +1,34 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec3 fragPosition;
+varying vec2 fragTexCoord;
+varying vec3 fragNormal;
+varying vec4 fragColor;
+
+// TODO: Is there some alternative for GLSL100
+//layout (location = 0) out vec3 gPosition;
+//layout (location = 1) out vec3 gNormal;
+//layout (location = 2) out vec4 gAlbedoSpec;
+//uniform vec3 gPosition;
+//uniform vec3 gNormal;
+//uniform vec4 gAlbedoSpec;
+
+// Input uniform values
+uniform sampler2D texture0;  // Diffuse texture
+uniform sampler2D specularTexture;
+
+void main()
+{
+    // Store the fragment position vector in the first gbuffer texture
+    //gPosition = fragPosition;
+    
+    // Store the per-fragment normals into the gbuffer
+    //gNormal = normalize(fragNormal);
+    
+    // Store the diffuse per-fragment color
+    gl_FragColor.rgb = texture2D(texture0, fragTexCoord).rgb;
+    
+    // Store specular intensity in gAlbedoSpec's alpha component
+    gl_FragColor.a = texture2D(specularTexture, fragTexCoord).r;
+}

+ 60 - 0
examples/shaders/resources/shaders/glsl120/gbuffer.vs

@@ -0,0 +1,60 @@
+#version 120
+
+// Input vertex attributes
+attribute vec3 vertexPosition;
+attribute vec2 vertexTexCoord;
+attribute vec3 vertexNormal;
+attribute vec4 vertexColor;
+
+// Input uniform values
+uniform mat4 matModel;
+uniform mat4 matView;
+uniform mat4 matProjection;
+
+// Output vertex attributes (to fragment shader)
+varying vec3 fragPosition;
+varying vec2 fragTexCoord;
+varying vec3 fragNormal;
+varying vec4 fragColor;
+
+
+// https://github.com/glslify/glsl-inverse
+mat3 inverse(mat3 m)
+{
+    float a00 = m[0][0], a01 = m[0][1], a02 = m[0][2];
+    float a10 = m[1][0], a11 = m[1][1], a12 = m[1][2];
+    float a20 = m[2][0], a21 = m[2][1], a22 = m[2][2];
+
+    float b01 = a22*a11 - a12*a21;
+    float b11 = -a22*a10 + a12*a20;
+    float b21 = a21*a10 - a11*a20;
+
+    float det = a00*b01 + a01*b11 + a02*b21;
+
+    return mat3(b01, (-a22*a01 + a02*a21), (a12*a01 - a02*a11),
+              b11, (a22*a00 - a02*a20), (-a12*a00 + a02*a10),
+              b21, (-a21*a00 + a01*a20), (a11*a00 - a01*a10))/det;
+}
+
+// https://github.com/glslify/glsl-transpose
+mat3 transpose(mat3 m)
+{
+    return mat3(m[0][0], m[1][0], m[2][0],
+              m[0][1], m[1][1], m[2][1],
+              m[0][2], m[1][2], m[2][2]);
+}
+
+void main()
+{
+    // Calculate vertex attributes for fragment shader
+    vec4 worldPos = matModel*vec4(vertexPosition, 1.0);
+    fragPosition = worldPos.xyz; 
+    fragTexCoord = vertexTexCoord;
+    fragColor = vertexColor;
+
+    mat3 normalMatrix = transpose(inverse(mat3(matModel)));
+    fragNormal = normalMatrix*vertexNormal;
+
+    // Calculate final vertex position
+    gl_Position = matProjection*matView*worldPos;
+}

+ 17 - 0
examples/shaders/resources/shaders/glsl120/hybrid_raster.fs

@@ -0,0 +1,17 @@
+#version 120
+
+#extension GL_EXT_frag_depth : enable   // Extension required for writing depth         
+
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+void main()
+{
+    vec4 texelColor = texture2D(texture0, fragTexCoord);
+
+    gl_FragColor = texelColor*colDiffuse*fragColor;
+    gl_FragDepthEXT = gl_FragCoord.z;
+}

+ 291 - 0
examples/shaders/resources/shaders/glsl120/hybrid_raymarch.fs

@@ -0,0 +1,291 @@
+#version 120
+
+#extension GL_EXT_frag_depth : enable           //Extension required for writing depth
+#extension GL_OES_standard_derivatives : enable //Extension used for fwidth()
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+// Custom Input Uniform
+uniform vec3 camPos;
+uniform vec3 camDir;
+uniform vec2 screenCenter;
+
+#define ZERO 0
+
+// SRC: https://learnopengl.com/Advanced-OpenGL/Depth-testing
+float CalcDepth(in vec3 rd, in float Idist)
+{
+    float local_z = dot(normalize(camDir),rd)*Idist;
+    return (1.0/(local_z) - 1.0/0.01)/(1.0/1000.0 -1.0/0.01);
+}
+
+// SRC: https://iquilezles.org/articles/distfunctions/
+float sdHorseshoe(in vec3 p, in vec2 c, in float r, in float le, vec2 w)
+{
+    p.x = abs(p.x);
+    float l = length(p.xy);
+    p.xy = mat2(-c.x, c.y, 
+              c.y, c.x)*p.xy;
+    p.xy = vec2((p.y>0.0 || p.x>0.0)?p.x:l*sign(-c.x),
+                (p.x>0.0)?p.y:l);
+    p.xy = vec2(p.x,abs(p.y-r))-vec2(le,0.0);
+    
+    vec2 q = vec2(length(max(p.xy,0.0)) + min(0.0,max(p.x,p.y)),p.z);
+    vec2 d = abs(q) - w;
+    return min(max(d.x,d.y),0.0) + length(max(d,0.0));
+}
+
+// r = sphere's radius
+// h = cutting's plane's position
+// t = thickness
+float sdSixWayCutHollowSphere(vec3 p, float r, float h, float t)
+{
+    // Six way symetry Transformation
+    vec3 ap = abs(p);
+    if (ap.x < max(ap.y, ap.z)){
+        if (ap.y < ap.z) ap.xz = ap.zx;
+        else ap.xy = ap.yx;
+    }
+
+    vec2 q = vec2(length(ap.yz), ap.x);
+    
+    float w = sqrt(r*r-h*h);
+    
+    return ((h*q.x<w*q.y) ? length(q-vec2(w,h)) : abs(length(q)-r)) - t;
+}
+
+// SRC: https://iquilezles.org/articles/boxfunctions
+vec2 iBox(in vec3 ro, in vec3 rd, in vec3 rad) 
+{
+    vec3 m = 1.0/rd;
+    vec3 n = m*ro;
+    vec3 k = abs(m)*rad;
+    vec3 t1 = -n - k;
+    vec3 t2 = -n + k;
+
+    return vec2(max(max(t1.x, t1.y), t1.z),
+                 min(min(t2.x, t2.y), t2.z));
+}
+
+vec2 opU(vec2 d1, vec2 d2)
+{
+    return (d1.x<d2.x) ? d1 : d2;
+}
+
+vec2 map(in vec3 pos)
+{
+    vec2 res = vec2(sdHorseshoe(pos-vec3(-1.0,0.08, 1.0), vec2(cos(1.3),sin(1.3)), 0.2, 0.3, vec2(0.03,0.5)), 11.5) ;
+    res = opU(res, vec2(sdSixWayCutHollowSphere(pos-vec3(0.0, 1.0, 0.0), 4.0, 3.5, 0.5), 4.5)) ;
+
+    return res;
+}
+
+// SRC: https://www.shadertoy.com/view/Xds3zN
+vec2 raycast(in vec3 ro, in vec3 rd)
+{
+    vec2 res = vec2(-1.0,-1.0);
+
+    float tmin = 1.0;
+    float tmax = 20.0;
+
+    // Raytrace floor plane
+    float tp1 = (-ro.y)/rd.y;
+    if (tp1>0.0)
+    {
+        tmax = min(tmax, tp1);
+        res = vec2(tp1, 1.0);
+    }
+
+    float t = tmin;
+    for (int i=0; i<70 ; i++)
+    {
+        if (t>tmax) break;
+        vec2 h = map(ro+rd*t);
+        if (abs(h.x) < (0.0001*t))
+        { 
+            res = vec2(t,h.y); 
+            break;
+        }
+        t += h.x;
+    }
+
+    return res;
+}
+
+
+// https://iquilezles.org/articles/rmshadows
+float calcSoftshadow(in vec3 ro, in vec3 rd, in float mint, in float tmax)
+{
+    // bounding volume
+    float tp = (0.8-ro.y)/rd.y; if (tp>0.0) tmax = min(tmax, tp);
+
+    float res = 1.0;
+    float t = mint;
+    for (int i=ZERO; i<24; i++)
+    {
+        float h = map(ro + rd*t).x;
+        float s = clamp(8.0*h/t,0.0,1.0);
+        res = min(res, s);
+        t += clamp(h, 0.01, 0.2);
+        if (res<0.004 || t>tmax) break;
+    }
+    res = clamp(res, 0.0, 1.0);
+    return res*res*(3.0-2.0*res);
+}
+
+
+// https://iquilezles.org/articles/normalsSDF
+vec3 calcNormal(in vec3 pos)
+{
+    vec2 e = vec2(1.0, -1.0)*0.5773*0.0005;
+    return normalize(e.xyy*map(pos + e.xyy).x + 
+                     e.yyx*map(pos + e.yyx).x + 
+                     e.yxy*map(pos + e.yxy).x + 
+                     e.xxx*map(pos + e.xxx).x);
+}
+
+// https://iquilezles.org/articles/nvscene2008/rwwtt.pdf
+float calcAO(in vec3 pos, in vec3 nor)
+{
+    float occ = 0.0;
+    float sca = 1.0;
+    for (int i=ZERO; i<5; i++)
+    {
+        float h = 0.01 + 0.12*float(i)/4.0;
+        float d = map(pos + h*nor).x;
+        occ += (h-d)*sca;
+        sca *= 0.95;
+        if (occ>0.35) break;
+    }
+    return clamp(1.0 - 3.0*occ, 0.0, 1.0)*(0.5+0.5*nor.y);
+}
+
+// https://iquilezles.org/articles/checkerfiltering
+float checkersGradBox(in vec2 p)
+{
+    // filter kernel
+    vec2 w = fwidth(p) + 0.001;
+    // analytical integral (box filter)
+    vec2 i = 2.0*(abs(fract((p-0.5*w)*0.5)-0.5)-abs(fract((p+0.5*w)*0.5)-0.5))/w;
+    // xor pattern
+    return 0.5 - 0.5*i.x*i.y;                  
+}
+
+// https://www.shadertoy.com/view/tdS3DG
+vec4 render(in vec3 ro, in vec3 rd)
+{ 
+    // background
+    vec3 col = vec3(0.7, 0.7, 0.9) - max(rd.y,0.0)*0.3;
+    
+    // raycast scene
+    vec2 res = raycast(ro,rd);
+    float t = res.x;
+    float m = res.y;
+    if (m>-0.5)
+    {
+        vec3 pos = ro + t*rd;
+        vec3 nor = (m<1.5) ? vec3(0.0,1.0,0.0) : calcNormal(pos);
+        vec3 ref = reflect(rd, nor);
+        
+        // material        
+        col = 0.2 + 0.2*sin(m*2.0 + vec3(0.0,1.0,2.0));
+        float ks = 1.0;
+        
+        if (m<1.5)
+        {
+            float f = checkersGradBox(3.0*pos.xz);
+            col = 0.15 + f*vec3(0.05);
+            ks = 0.4;
+        }
+
+        // lighting
+        float occ = calcAO(pos, nor);
+        
+        vec3 lin = vec3(0.0);
+
+        // sun
+        {
+            vec3  lig = normalize(vec3(-0.5, 0.4, -0.6));
+            vec3  hal = normalize(lig-rd);
+            float dif = clamp(dot(nor, lig), 0.0, 1.0);
+          //if (dif>0.0001)
+                  dif *= calcSoftshadow(pos, lig, 0.02, 2.5);
+            float spe = pow(clamp(dot(nor, hal), 0.0, 1.0),16.0);
+                  spe *= dif;
+                  spe *= 0.04+0.96*pow(clamp(1.0-dot(hal,lig),0.0,1.0),5.0);
+                //spe *= 0.04+0.96*pow(clamp(1.0-sqrt(0.5*(1.0-dot(rd,lig))),0.0,1.0),5.0);
+            lin += col*2.20*dif*vec3(1.30,1.00,0.70);
+            lin +=     5.00*spe*vec3(1.30,1.00,0.70)*ks;
+        }
+        // sky
+        {
+            float dif = sqrt(clamp(0.5+0.5*nor.y, 0.0, 1.0));
+                  dif *= occ;
+            float spe = smoothstep(-0.2, 0.2, ref.y);
+                  spe *= dif;
+                  spe *= 0.04+0.96*pow(clamp(1.0+dot(nor,rd),0.0,1.0), 5.0);
+          //if (spe>0.001)
+                  spe *= calcSoftshadow(pos, ref, 0.02, 2.5);
+            lin += col*0.60*dif*vec3(0.40,0.60,1.15);
+            lin +=     2.00*spe*vec3(0.40,0.60,1.30)*ks;
+        }
+        // back
+        {
+            float dif = clamp(dot(nor, normalize(vec3(0.5,0.0,0.6))), 0.0, 1.0)*clamp(1.0-pos.y,0.0,1.0);
+                  dif *= occ;
+            lin += col*0.55*dif*vec3(0.25,0.25,0.25);
+        }
+        // sss
+        {
+            float dif = pow(clamp(1.0+dot(nor,rd),0.0,1.0),2.0);
+                  dif *= occ;
+            lin += col*0.25*dif*vec3(1.00,1.00,1.00);
+        }
+        
+        col = lin;
+
+        col = mix(col, vec3(0.7,0.7,0.9), 1.0-exp(-0.0001*t*t*t));
+    }
+
+    return vec4(vec3(clamp(col,0.0,1.0)),t);
+}
+
+vec3 CalcRayDir(vec2 nCoord){
+    vec3 horizontal = normalize(cross(camDir,vec3(.0 , 1.0, .0)));
+    vec3 vertical   = normalize(cross(horizontal,camDir));
+    return normalize(camDir + horizontal*nCoord.x + vertical*nCoord.y);
+}
+
+mat3 setCamera()
+{
+    vec3 cw = normalize(camDir);
+    vec3 cp = vec3(0.0, 1.0 ,0.0);
+    vec3 cu = normalize(cross(cw,cp));
+    vec3 cv =          (cross(cu,cw));
+    return mat3(cu, cv, cw);
+}
+
+void main()
+{
+    vec2 nCoord = (gl_FragCoord.xy - screenCenter.xy)/screenCenter.y;
+    mat3 ca = setCamera();
+
+    // focal length
+    float fl = length(camDir);
+    vec3 rd = ca*normalize(vec3(nCoord,fl));
+    vec3 color = vec3(nCoord/2.0 + 0.5, 0.0);
+    float depth = gl_FragCoord.z;
+    {
+        vec4 res = render(camPos - vec3(0.0, 0.0, 0.0) , rd);
+        color = res.xyz;
+        depth = CalcDepth(rd,res.w);
+    }
+    gl_FragColor = vec4(color , 1.0);
+    gl_FragDepthEXT = depth;
+}

+ 80 - 0
examples/shaders/resources/shaders/glsl120/julia_set.fs

@@ -0,0 +1,80 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+uniform vec2 c;                 // c.x = real, c.y = imaginary component. Equation done is z^2 + c
+uniform vec2 offset;            // Offset of the scale
+uniform float zoom;             // Zoom of the scale
+
+// NOTE: Maximum number of shader for-loop iterations depend on GPU,
+// for example, on RasperryPi for this examply only supports up to 60
+const int maxIterations = 48;     // Max iterations to do
+const float colorCycles = 1.0;    // Number of times the color palette repeats
+
+// Square a complex number
+vec2 ComplexSquare(vec2 z)
+{
+    return vec2(z.x*z.x - z.y*z.y, z.x*z.y*2.0);
+}
+
+// Convert Hue Saturation Value (HSV) color into RGB
+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()
+{
+    /**********************************************************************************************
+      Julia sets use a function z^2 + c, where c is a constant
+      This function is iterated until the nature of the point is determined
+
+      If the magnitude of the number becomes greater than 2, then from that point onward
+      the number will get bigger and bigger, and will never get smaller (tends towards infinity)
+      2^2 = 4, 4^2 = 8 and so on
+      So at 2 we stop iterating
+
+      If the number is below 2, we keep iterating
+      But when do we stop iterating if the number is always below 2 (it converges)?
+      That is what maxIterations is for
+      Then we can divide the iterations by the maxIterations value to get a normalized value
+      that we can then map to a color
+
+      We use dot product (z.x*z.x + z.y*z.y) to determine the magnitude (length) squared
+      And once the magnitude squared is > 4, then magnitude > 2 is also true (saves computational power)
+    *************************************************************************************************/
+
+    // The pixel coordinates are scaled so they are on the mandelbrot scale
+    // NOTE: fragTexCoord already comes as normalized screen coordinates but offset must be normalized before scaling and zoom
+    vec2 z = vec2((fragTexCoord.x - 0.5)*2.5, (fragTexCoord.y - 0.5)*1.5)/zoom;
+    z.x += offset.x;
+    z.y += offset.y;
+
+    int iter = 0;
+    for (int iterations = 0; iterations < 60; iterations++)
+    {
+        z = ComplexSquare(z) + c;  // Iterate function
+        if (dot(z, z) > 4.0) break;
+
+        iter = iterations;
+    }
+
+    // Another few iterations decreases errors in the smoothing calculation
+    // See http://linas.org/art-gallery/escape/escape.html for more information
+    z = ComplexSquare(z) + c;
+    z = ComplexSquare(z) + c;
+
+    // This last part smooths the color (again see link above)
+    float smoothVal = float(iter) + 1.0 - (log(log(length(z)))/log(2.0));
+
+    // Normalize the value so it is between 0 and 1
+    float norm = smoothVal/float(maxIterations);
+
+    // If in set, color black. 0.999 allows for some float accuracy error
+    if (norm > 0.999) gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
+    else gl_FragColor = vec4(Hsv2rgb(vec3(norm*colorCycles, 1.0, 1.0)), 1.0);
+}

+ 36 - 0
examples/shaders/resources/shaders/glsl120/lighting_instancing.vs

@@ -0,0 +1,36 @@
+#version 120
+
+// Input vertex attributes
+attribute vec3 vertexPosition;
+attribute vec2 vertexTexCoord;
+attribute vec3 vertexNormal;
+attribute vec4 vertexColor;
+
+attribute mat4 instanceTransform;
+
+// Input uniform values
+uniform mat4 mvp;
+uniform mat4 matNormal;
+
+// Output vertex attributes (to fragment shader)
+varying vec3 fragPosition;
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+varying vec3 fragNormal;
+
+// NOTE: Add your custom variables here
+
+void main()
+{
+    // Compute MVP for current instance
+    mat4 mvpi = mvp*instanceTransform;
+
+    // Send vertex attributes to fragment shader
+    fragPosition = vec3(mvpi*vec4(vertexPosition, 1.0));
+    fragTexCoord = vertexTexCoord;
+    fragColor = vertexColor;
+    fragNormal = normalize(vec3(matNormal*vec4(vertexNormal, 1.0)));
+
+    // Calculate final vertex position
+    gl_Position = mvpi*vec4(vertexPosition, 1.0);
+}

+ 22 - 0
examples/shaders/resources/shaders/glsl120/mask.fs

@@ -0,0 +1,22 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform sampler2D mask;
+uniform vec4 colDiffuse;
+uniform int frame;
+
+// NOTE: Add your custom variables here
+
+void main()
+{
+    vec4 maskColour = texture2D(mask, fragTexCoord + vec2(sin(-float(frame)/150.0)/10.0, cos(-float(frame)/170.0)/10.0));
+    if (maskColour.r < 0.25) discard;
+    vec4 texelColor = texture2D(texture0, fragTexCoord + vec2(sin(float(frame)/90.0)/8.0, cos(float(frame)/60.0)/8.0));
+
+    gl_FragColor = texelColor*maskColour;
+}

+ 32 - 0
examples/shaders/resources/shaders/glsl120/outline.fs

@@ -0,0 +1,32 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+uniform vec2 textureSize;
+uniform float outlineSize;
+uniform vec4 outlineColor;
+
+void main()
+{
+    vec4 texel = texture2D(texture0, fragTexCoord);   // Get texel color
+    vec2 texelScale = vec2(0.0);
+    texelScale.x = outlineSize/textureSize.x;
+    texelScale.y = outlineSize/textureSize.y;
+
+    // We sample four corner texels, but only for the alpha channel (this is for the outline)
+    vec4 corners = vec4(0.0);
+    corners.x = texture2D(texture0, fragTexCoord + vec2(texelScale.x, texelScale.y)).a;
+    corners.y = texture2D(texture0, fragTexCoord + vec2(texelScale.x, -texelScale.y)).a;
+    corners.z = texture2D(texture0, fragTexCoord + vec2(-texelScale.x, texelScale.y)).a;
+    corners.w = texture2D(texture0, fragTexCoord + vec2(-texelScale.x, -texelScale.y)).a;
+
+    float outline = min(dot(corners, vec4(1.0)), 1.0);
+    vec4 color = mix(vec4(0.0), outlineColor, outline);
+    gl_FragColor = mix(color, texel, texel.a);
+}

+ 37 - 0
examples/shaders/resources/shaders/glsl120/reload.fs

@@ -0,0 +1,37 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;           // Texture coordinates (sampler2D)
+varying vec4 fragColor;              // Tint color
+
+// Uniform inputs
+uniform vec2 resolution;        // Viewport resolution (in pixels)
+uniform vec2 mouse;             // Mouse pixel xy coordinates
+uniform float time;             // Total run time (in secods)
+
+// Draw circle
+vec4 DrawCircle(vec2 fragCoord, vec2 position, float radius, vec3 color)
+{
+    float d = length(position - fragCoord) - radius;
+    float t = clamp(d, 0.0, 1.0);
+    return vec4(color, 1.0 - t);
+}
+
+void main()
+{
+    vec2 fragCoord = gl_FragCoord.xy;
+    vec2 position = vec2(mouse.x, resolution.y - mouse.y);
+    float radius = 40.0;
+
+    // Draw background layer
+    vec4 colorA = vec4(0.2,0.2,0.8, 1.0);
+    vec4 colorB = vec4(1.0,0.7,0.2, 1.0);
+    vec4 layer1 = mix(colorA, colorB, abs(sin(time*0.1)));
+
+    // Draw circle layer
+    vec3 color = vec3(0.9, 0.16, 0.21);
+    vec4 layer2 = DrawCircle(fragCoord, position, radius, color);
+
+    // Blend the two layers
+    gl_FragColor = mix(layer1, layer2, layer2.a);
+}

+ 75 - 0
examples/shaders/resources/shaders/glsl120/spotlight.fs

@@ -0,0 +1,75 @@
+#version 120
+
+#define MAX_SPOTS   3
+
+struct Spot {
+    vec2 pos;        // window coords of spot
+    float inner;    // inner fully transparent centre radius
+    float radius;    // alpha fades out to this radius
+};
+
+uniform Spot spots[MAX_SPOTS];  // Spotlight positions array
+uniform float screenWidth;      // Width of the screen
+
+void main()
+{
+    float alpha = 1.0;
+
+    // Get the position of the current fragment (screen coordinates!)
+    vec2 pos = vec2(gl_FragCoord.x, gl_FragCoord.y);
+
+    // Find out which spotlight is nearest
+    float d = 65000.0;  // some high value
+    int fi = -1;        // found index
+
+    for (int i = 0; i < MAX_SPOTS; i++)
+    {
+        for (int j = 0; j < MAX_SPOTS; j++)
+        {
+            float dj = distance(pos, spots[j].pos) - spots[j].radius + spots[i].radius;
+
+            if (d > dj)
+            {
+                d = dj;
+                fi = i;
+            }
+        }
+    }
+
+    // d now equals distance to nearest spot...
+    // allowing for the different radii of all spotlights
+    if (fi == 0)
+    {
+        if (d > spots[0].radius) alpha = 1.0;
+        else
+        {
+            if (d < spots[0].inner) alpha = 0.0;
+            else alpha = (d - spots[0].inner)/(spots[0].radius - spots[0].inner);
+        }
+    }
+    else if (fi == 1)
+    {
+        if (d > spots[1].radius) alpha = 1.0;
+        else
+        {
+            if (d < spots[1].inner) alpha = 0.0;
+            else alpha = (d - spots[1].inner)/(spots[1].radius - spots[1].inner);
+        }
+    }
+    else if (fi == 2)
+    {
+        if (d > spots[2].radius) alpha = 1.0;
+        else
+        {
+            if (d < spots[2].inner) alpha = 0.0;
+            else alpha = (d - spots[2].inner)/(spots[2].radius - spots[2].inner);
+        }
+    }
+
+    // Right hand side of screen is dimly lit,
+    // could make the threshold value user definable
+    if ((pos.x > screenWidth/2.0) && (alpha > 0.9)) alpha = 0.9;
+
+    // could make the black out colour user definable...
+    gl_FragColor = vec4(0, 0, 0, alpha);
+}

+ 19 - 0
examples/shaders/resources/shaders/glsl120/tiling.fs

@@ -0,0 +1,19 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+// NOTE: Add your custom variables here
+uniform vec2 tiling;
+
+void main()
+{
+    vec2 texCoord = fragTexCoord*tiling;
+
+    gl_FragColor = texture2D(texture0, texCoord)*colDiffuse;
+}

+ 15 - 0
examples/shaders/resources/shaders/glsl120/vertex_displacement.fs

@@ -0,0 +1,15 @@
+#version 120
+
+// Input vertex attributes (from fragment shader)
+varying vec2 fragTexCoord;
+varying float height;
+
+void main()
+{
+    vec4 darkblue = vec4(0.0, 0.13, 0.18, 1.0);
+    vec4 lightblue = vec4(1.0, 1.0, 1.0, 1.0);
+    // Interpolate between two colors based on height
+    vec4 finalColor = mix(darkblue, lightblue, height);
+
+    gl_FragColor = finalColor;
+}

+ 43 - 0
examples/shaders/resources/shaders/glsl120/vertex_displacement.vs

@@ -0,0 +1,43 @@
+#version 120
+
+attribute vec3 vertexPosition;
+attribute vec2 vertexTexCoord;
+attribute vec3 vertexNormal;
+attribute vec4 vertexColor;
+
+uniform mat4 mvp;
+uniform mat4 matModel;
+uniform mat4 matNormal;
+
+uniform float time;
+
+uniform sampler2D perlinNoiseMap;
+
+varying vec3 fragPosition;
+varying vec2 fragTexCoord;
+varying vec3 fragNormal;
+varying float height;
+
+void main()
+{
+    // Calculate animated texture coordinates based on time and vertex position
+    vec2 animatedTexCoord = sin(vertexTexCoord + vec2(sin(time + vertexPosition.x*0.1), cos(time + vertexPosition.z*0.1))*0.3);
+
+    // Normalize animated texture coordinates to range [0, 1]
+    animatedTexCoord = animatedTexCoord*0.5 + 0.5;
+
+    // Fetch displacement from the perlin noise map
+    float displacement = texture2D(perlinNoiseMap, animatedTexCoord).r*7.0; // Amplified displacement
+
+    // Displace vertex position
+    vec3 displacedPosition = vertexPosition + vec3(0.0, displacement, 0.0);
+
+    // Send vertex attributes to fragment shader
+    fragPosition = vec3(matModel*vec4(displacedPosition, 1.0));
+    fragTexCoord = vertexTexCoord;
+    fragNormal = normalize(vec3(matNormal*vec4(vertexNormal, 1.0)));
+    height = displacedPosition.y*0.2; // send height to fragment shader for coloring
+
+    // Calculate final vertex position
+    gl_Position = mvp*vec4(displacedPosition, 1.0);
+}

+ 32 - 0
examples/shaders/resources/shaders/glsl120/wave.fs

@@ -0,0 +1,32 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+uniform float seconds;
+uniform vec2 size;
+uniform float freqX;
+uniform float freqY;
+uniform float ampX;
+uniform float ampY;
+uniform float speedX;
+uniform float speedY;
+
+void main() {
+    float pixelWidth = 1.0/size.x;
+    float pixelHeight = 1.0/size.y;
+    float aspect = pixelHeight/pixelWidth;
+    float boxLeft = 0.0;
+    float boxTop = 0.0;
+
+    vec2 p = fragTexCoord;
+    p.x += cos((fragTexCoord.y - boxTop)*freqX/(pixelWidth*750.0) + (seconds*speedX))*ampX*pixelWidth;
+    p.y += sin((fragTexCoord.x - boxLeft)*freqY*aspect/(pixelHeight*750.0) + (seconds*speedY))*ampY*pixelHeight;
+
+    gl_FragColor = texture2D(texture0, p)*colDiffuse*fragColor;
+}

+ 17 - 0
examples/shaders/resources/shaders/glsl120/write_depth.fs

@@ -0,0 +1,17 @@
+#version 100
+
+#extension GL_EXT_frag_depth : enable          
+
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+void main()
+{
+    vec4 texelColor = texture2D(texture0, fragTexCoord);
+    
+    gl_FragColor = texelColor*colDiffuse*fragColor;
+    gl_FragDepthEXT = 1.0 - gl_FragCoord.z;
+}