diff options
Diffstat (limited to 'tests/manual/wave/shaders/ribbon.vert')
-rw-r--r-- | tests/manual/wave/shaders/ribbon.vert | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/tests/manual/wave/shaders/ribbon.vert b/tests/manual/wave/shaders/ribbon.vert new file mode 100644 index 000000000..2ff9d2729 --- /dev/null +++ b/tests/manual/wave/shaders/ribbon.vert @@ -0,0 +1,149 @@ +#version 330 core + +in vec3 vertexPosition; +in vec3 vertexNormal; + +out EyeSpaceVertex { + vec3 position; + vec3 normal; +} vs_out; + +uniform mat4 modelView; +uniform mat3 modelViewNormal; +uniform mat4 mvp; + +uniform float time; +uniform float amplitude = 1.0; +uniform float lambda = 20.0; +uniform float period = 15.0; + +// +// Description : Array and textureless GLSL 3D simplex noise function. +// Author : Ian McEwan, Ashima Arts. +// Maintainer : ijm +// Lastmod : 20110409 (stegu) +// License : Copyright (C) 2011 Ashima Arts. All rights reserved. +// Distributed under the MIT License. See LICENSE file. +// + +vec4 permute( vec4 x ) +{ + return mod(((x*34.0)+1.0)*x, 289.0); +} + +vec4 taylorInvSqrt( vec4 r ) +{ + return 1.79284291400159 - 0.85373472095314 * r; +} + +float snoise(vec3 v) +{ + const vec2 C = vec2(1.0/6.0, 1.0/3.0) ; + const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); + + // First corner + vec3 i = floor(v + dot(v, C.yyy) ); + vec3 x0 = v - i + dot(i, C.xxx) ; + + // Other corners + vec3 g = step(x0.yzx, x0.xyz); + vec3 l = 1.0 - g; + vec3 i1 = min( g.xyz, l.zxy ); + vec3 i2 = max( g.xyz, l.zxy ); + + // x0 = x0 - 0. + 0.0 * C + vec3 x1 = x0 - i1 + 1.0 * C.xxx; + vec3 x2 = x0 - i2 + 2.0 * C.xxx; + vec3 x3 = x0 - 1. + 3.0 * C.xxx; + + // Permutations + i = mod(i, 289.0 ); + vec4 p = permute( permute( permute( + i.z + vec4(0.0, i1.z, i2.z, 1.0 )) + + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) + + i.x + vec4(0.0, i1.x, i2.x, 1.0 )); + + // Gradients + // ( N*N points uniformly over a square, mapped onto an octahedron.) + float n_ = 1.0/7.0; // N=7 + vec3 ns = n_ * D.wyz - D.xzx; + + vec4 j = p - 49.0 * floor(p * ns.z *ns.z); // mod(p,N*N) + + vec4 x_ = floor(j * ns.z); + vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N) + + vec4 x = x_ *ns.x + ns.yyyy; + vec4 y = y_ *ns.x + ns.yyyy; + vec4 h = 1.0 - abs(x) - abs(y); + + vec4 b0 = vec4( x.xy, y.xy ); + vec4 b1 = vec4( x.zw, y.zw ); + + //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0; + //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0; + vec4 s0 = floor(b0)*2.0 + 1.0; + vec4 s1 = floor(b1)*2.0 + 1.0; + vec4 sh = -step(h, vec4(0.0)); + + vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ; + vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ; + + vec3 p0 = vec3(a0.xy,h.x); + vec3 p1 = vec3(a0.zw,h.y); + vec3 p2 = vec3(a1.xy,h.z); + vec3 p3 = vec3(a1.zw,h.w); + + //Normalise gradients + vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3))); + p0 *= norm.x; + p1 *= norm.y; + p2 *= norm.z; + p3 *= norm.w; + + // Mix final noise value + vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); + m = m * m; + return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), + dot(p2,x2), dot(p3,x3) ) ); +} + +float height( const in vec3 pos ) +{ + // Perturb the y position by a wave function in (x, t) + const float twoPi = 2.0 * 3.14159265358979323846; + float k = twoPi / lambda; + float omega = twoPi / period; + + float y = amplitude * sin( k * pos.x - omega * time ); + + // Further perturb by a noise function + y += snoise( 0.27 * vec3( 0.4 * pos.x, 3.0, 2.0 * pos.z - 0.5 * time ) ); + + return y; +} + +void main() +{ + // Calculate y value based upon input coordinates and time + vec3 pos = vertexPosition; + pos.y = height( pos ); + + // Estimate normal vector by calculating the y value at small offsets + // and then taking the cross product of the differences + float offset = 0.5; + vec3 posOffsetX = vertexPosition + vec3( offset, 0.0, 0.0 ); + posOffsetX.y = height( posOffsetX ); + vec3 posOffsetZ = vertexPosition + vec3( 0.0, 0.0, offset ); + posOffsetZ.y = height( posOffsetZ ); + + vec3 dydx = posOffsetX - pos; + vec3 dydz = posOffsetZ - pos; + vec3 normal = cross( dydz, dydx ); + + // Transform the position and normal to eye space for lighting + vs_out.normal = normalize( modelViewNormal * normal ); + vs_out.position = vec3( modelView * vec4( pos, 1.0 ) ); + + gl_Position = mvp * vec4( pos, 1.0 ); +} |