diff options
Diffstat (limited to 'examples/qt3d/wave/shaders')
-rw-r--r-- | examples/qt3d/wave/shaders/background.frag | 13 | ||||
-rw-r--r-- | examples/qt3d/wave/shaders/background.vert | 14 | ||||
-rw-r--r-- | examples/qt3d/wave/shaders/ribbon.frag | 49 | ||||
-rw-r--r-- | examples/qt3d/wave/shaders/ribbon.vert | 149 | ||||
-rw-r--r-- | examples/qt3d/wave/shaders/ribbonwireframe.frag | 98 | ||||
-rw-r--r-- | examples/qt3d/wave/shaders/robustwireframe.geom | 131 |
6 files changed, 454 insertions, 0 deletions
diff --git a/examples/qt3d/wave/shaders/background.frag b/examples/qt3d/wave/shaders/background.frag new file mode 100644 index 000000000..01c062189 --- /dev/null +++ b/examples/qt3d/wave/shaders/background.frag @@ -0,0 +1,13 @@ +#version 150 core + +in vec2 texCoord; + +out vec4 fragColor; + +uniform vec3 color1; +uniform vec3 color2; + +void main() +{ + fragColor = vec4( mix( color1, color2, texCoord.t ), 1.0 ); +} diff --git a/examples/qt3d/wave/shaders/background.vert b/examples/qt3d/wave/shaders/background.vert new file mode 100644 index 000000000..58fadebe5 --- /dev/null +++ b/examples/qt3d/wave/shaders/background.vert @@ -0,0 +1,14 @@ +#version 150 core + +in vec4 vertexPosition; +in vec2 vertexTexCoord; + +out vec2 texCoord; + +uniform mat4 modelMatrix; + +void main() +{ + texCoord = vertexTexCoord; + gl_Position = modelMatrix * vertexPosition; +} diff --git a/examples/qt3d/wave/shaders/ribbon.frag b/examples/qt3d/wave/shaders/ribbon.frag new file mode 100644 index 000000000..09ad78871 --- /dev/null +++ b/examples/qt3d/wave/shaders/ribbon.frag @@ -0,0 +1,49 @@ +#version 330 core + +in EyeSpaceVertex { + vec3 position; + vec3 normal; +} fs_in; + +out vec4 fragColor; + +uniform struct LightInfo { + vec4 position; + vec3 intensity; +} light; + +uniform struct LineInfo { + float width; + vec4 color; +} line; + +uniform vec3 ka; // Ambient reflectivity +uniform vec3 kd; // Diffuse reflectivity + +vec3 rimLightModel( const in vec3 pos, const in vec3 n ) +{ + // Calculate the vector from the light to the fragment + vec3 s = normalize( vec3( light.position ) - pos ); + + // Calculate the vector from the fragment to the eye position (the + // origin since this is in "eye" or "camera" space + vec3 v = normalize( -pos ); + + // Refleft the light beam using the normal at this fragment + vec3 r = reflect( -s, n ); + + // Calculate the diffuse component, which for rim lighting it 1 minus s dot n + // rather than s dot n as for standard diffuse lighting + float sDotN = dot( s, n ); + vec3 diffuse = vec3( 1.0 - max( sDotN, 0.0 ) ); + + // Combine the ambient, diffuse and specular contributions + return light.intensity * ( ka + kd * diffuse ); +} + +void main() +{ + vec3 n = gl_FrontFacing ? fs_in.normal : -fs_in.normal; + vec4 color = vec4( rimLightModel( fs_in.position, normalize( n ) ), 1.0 ); + fragColor = color; +} diff --git a/examples/qt3d/wave/shaders/ribbon.vert b/examples/qt3d/wave/shaders/ribbon.vert new file mode 100644 index 000000000..e099d53c8 --- /dev/null +++ b/examples/qt3d/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.14159; + 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 ); +} diff --git a/examples/qt3d/wave/shaders/ribbonwireframe.frag b/examples/qt3d/wave/shaders/ribbonwireframe.frag new file mode 100644 index 000000000..659f00a8a --- /dev/null +++ b/examples/qt3d/wave/shaders/ribbonwireframe.frag @@ -0,0 +1,98 @@ +#version 330 core + +in WireframeVertex { + vec3 position; + vec3 normal; + noperspective vec4 edgeA; + noperspective vec4 edgeB; + flat int configuration; +} fs_in; + +out vec4 fragColor; + +uniform struct LightInfo { + vec4 position; + vec3 intensity; +} light; + +uniform struct LineInfo { + float width; + vec4 color; +} line; + +uniform vec3 ka; // Ambient reflectivity +uniform vec3 kd; // Diffuse reflectivity + +vec3 rimLightModel( const in vec3 pos, const in vec3 n ) +{ + // Calculate the vector from the light to the fragment + vec3 s = normalize( vec3( light.position ) - pos ); + + // Calculate the vector from the fragment to the eye position (the + // origin since this is in "eye" or "camera" space + vec3 v = normalize( -pos ); + + // Refleft the light beam using the normal at this fragment + vec3 r = reflect( -s, n ); + + // Calculate the diffuse component, which for rim lighting it 1 minus s dot n + // rather than s dot n as for standard diffuse lighting + float sDotN = dot( s, n ); + vec3 diffuse = vec3( 1.0 - max( sDotN, 0.0 ) ); + + // Combine the ambient, diffuse and specular contributions + return light.intensity * ( ka + kd * diffuse ); +} + +vec4 shadeLine( const in vec4 color ) +{ + // Find the smallest distance between the fragment and a triangle edge + float d; + if ( fs_in.configuration == 0 ) { + // Common configuration + d = min( fs_in.edgeA.x, fs_in.edgeA.y ); + d = min( d, fs_in.edgeA.z ); + } else { + // Handle configuration where screen space projection breaks down + // Compute and compare the squared distances + vec2 AF = gl_FragCoord.xy - fs_in.edgeA.xy; + float sqAF = dot( AF, AF ); + float AFcosA = dot( AF, fs_in.edgeA.zw ); + d = abs( sqAF - AFcosA * AFcosA ); + + vec2 BF = gl_FragCoord.xy - fs_in.edgeB.xy; + float sqBF = dot( BF, BF ); + float BFcosB = dot( BF, fs_in.edgeB.zw ); + d = min( d, abs( sqBF - BFcosB * BFcosB ) ); + + // Only need to care about the 3rd edge for some configurations. + if ( fs_in.configuration == 1 || + fs_in.configuration == 2 || + fs_in.configuration == 4 ) { + float AFcosA0 = dot( AF, normalize( fs_in.edgeB.xy - fs_in.edgeA.xy ) ); + d = min( d, abs( sqAF - AFcosA0 * AFcosA0 ) ); + } + + d = sqrt( d ); + } + + // Blend between line color and shaded color + float mixVal; + if ( d < line.width - 1.0 ) { + mixVal = 1.0; + } else if ( d > line.width + 1.0 ) { + mixVal = 0.0; + } else { + float x = d - ( line.width - 1.0 ); + mixVal = exp2( -2.0 * ( x * x ) ); + } + + return mix( color, line.color, mixVal ); +} + +void main() +{ + vec3 n = gl_FrontFacing ? fs_in.normal : -fs_in.normal; + vec4 color = vec4( rimLightModel( fs_in.position, normalize( n ) ), 1.0 ); + fragColor = shadeLine( color ); +} diff --git a/examples/qt3d/wave/shaders/robustwireframe.geom b/examples/qt3d/wave/shaders/robustwireframe.geom new file mode 100644 index 000000000..6eb0ecc76 --- /dev/null +++ b/examples/qt3d/wave/shaders/robustwireframe.geom @@ -0,0 +1,131 @@ +#version 330 core + +layout( triangles ) in; +layout( triangle_strip, max_vertices = 3 ) out; + +in EyeSpaceVertex { + vec3 position; + vec3 normal; +} gs_in[]; + +out WireframeVertex { + vec3 position; + vec3 normal; + noperspective vec4 edgeA; + noperspective vec4 edgeB; + flat int configuration; +} gs_out; + +uniform mat4 viewportMatrix; + +const int infoA[] = int[]( 0, 0, 0, 0, 1, 1, 2 ); +const int infoB[] = int[]( 1, 1, 2, 0, 2, 1, 2 ); +const int infoAd[] = int[]( 2, 2, 1, 1, 0, 0, 0 ); +const int infoBd[] = int[]( 2, 2, 1, 2, 0, 2, 1 ); + +vec2 transformToViewport( const in vec4 p ) +{ + return vec2( viewportMatrix * ( p / p.w ) ); +} + +void main() +{ + gs_out.configuration = int(gl_in[0].gl_Position.z < 0) * int(4) + + int(gl_in[1].gl_Position.z < 0) * int(2) + + int(gl_in[2].gl_Position.z < 0); + + // If all vertices are behind us, cull the primitive + if (gs_out.configuration == 7) + return; + + // Transform each vertex into viewport space + vec2 p[3]; + p[0] = transformToViewport( gl_in[0].gl_Position ); + p[1] = transformToViewport( gl_in[1].gl_Position ); + p[2] = transformToViewport( gl_in[2].gl_Position ); + + if (gs_out.configuration == 0) + { + // Common configuration where all vertices are within the viewport + gs_out.edgeA = vec4(0.0); + gs_out.edgeB = vec4(0.0); + + // Calculate lengths of 3 edges of triangle + float a = length( p[1] - p[2] ); + float b = length( p[2] - p[0] ); + float c = length( p[1] - p[0] ); + + // Calculate internal angles using the cosine rule + float alpha = acos( ( b * b + c * c - a * a ) / ( 2.0 * b * c ) ); + float beta = acos( ( a * a + c * c - b * b ) / ( 2.0 * a * c ) ); + + // Calculate the perpendicular distance of each vertex from the opposing edge + float ha = abs( c * sin( beta ) ); + float hb = abs( c * sin( alpha ) ); + float hc = abs( b * sin( alpha ) ); + + // Now add this perpendicular distance as a per-vertex property in addition to + // the position and normal calculated in the vertex shader. + + // Vertex 0 (a) + gs_out.edgeA = vec4( ha, 0.0, 0.0, 0.0 ); + gs_out.normal = gs_in[0].normal; + gs_out.position = gs_in[0].position; + gl_Position = gl_in[0].gl_Position; + EmitVertex(); + + // Vertex 1 (b) + gs_out.edgeA = vec4( 0.0, hb, 0.0, 0.0 ); + gs_out.normal = gs_in[1].normal; + gs_out.position = gs_in[1].position; + gl_Position = gl_in[1].gl_Position; + EmitVertex(); + + // Vertex 2 (c) + gs_out.edgeA = vec4( 0.0, 0.0, hc, 0.0 ); + gs_out.normal = gs_in[2].normal; + gs_out.position = gs_in[2].position; + gl_Position = gl_in[2].gl_Position; + EmitVertex(); + + // Finish the primitive off + EndPrimitive(); + } + else + { + // Viewport projection breaks down for one or two vertices. + // Caclulate what we can here and defer rest to fragment shader. + // Since this is coherent for the entire primitive the conditional + // in the fragment shader is still cheap as all concurrent + // fragment shader invocations will take the same code path. + + // Copy across the viewport-space points for the (up to) two vertices + // in the viewport + gs_out.edgeA.xy = p[infoA[gs_out.configuration]]; + gs_out.edgeB.xy = p[infoB[gs_out.configuration]]; + + // Copy across the viewport-space edge vectors for the (up to) two vertices + // in the viewport + gs_out.edgeA.zw = normalize( gs_out.edgeA.xy - p[ infoAd[gs_out.configuration] ] ); + gs_out.edgeB.zw = normalize( gs_out.edgeB.xy - p[ infoBd[gs_out.configuration] ] ); + + // Pass through the other vertex attributes + gs_out.normal = gs_in[0].normal; + gs_out.position = gs_in[0].position; + gl_Position = gl_in[0].gl_Position; + EmitVertex(); + + gs_out.normal = gs_in[1].normal; + gs_out.position = gs_in[1].position; + gl_Position = gl_in[1].gl_Position; + EmitVertex(); + + gs_out.normal = gs_in[2].normal; + gs_out.position = gs_in[2].position; + gl_Position = gl_in[2].gl_Position; + EmitVertex(); + + // Finish the primitive off + EndPrimitive(); + } +} |