// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // * Neither the name of NVIDIA CORPORATION nor the names of its // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Copyright (c) 2018 NVIDIA Corporation. All rights reserved. // GLSL shaders #include "Compound.h" #define STRINGIFY(A) #A // particle vertex shader const char *particleVS = STRINGIFY( uniform float pointRadius; // point size in world space uniform float pointScale; // scale to calculate size in pixels uniform float densityThreshold = 500.0; uniform float pointShrink = 0.2; void main() { // scale down point size based on density float density = gl_MultiTexCoord1.x; float scaledPointRadius = pointRadius * (pointShrink + smoothstep(densityThreshold, densityThreshold*2.0, density)*(1.0-pointShrink)); // float scaledPointRadius = pointRadius; // calculate window-space point size vec4 eyeSpacePos = gl_ModelViewMatrix * gl_Vertex; float dist = length(eyeSpacePos.xyz); gl_PointSize = scaledPointRadius * (pointScale / dist); gl_TexCoord[0] = gl_MultiTexCoord0; // sprite texcoord gl_TexCoord[1] = vec4(eyeSpacePos.xyz, scaledPointRadius); // eye space pos gl_TexCoord[2] = vec4(gl_MultiTexCoord2.xyz, density); // velocity and density gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; if (density < densityThreshold) gl_Position.w = -1.0; // cull particles with small density gl_FrontColor = gl_Color; } ); const char *particleVSNoKill = STRINGIFY( uniform float pointRadius; // point size in world space uniform float pointScale; // scale to calculate size in pixels uniform float densityThreshold = 500.0; uniform float pointShrink = 0.2; void main() { // scale down point size based on density float density = gl_MultiTexCoord1.x; // float scaledPointRadius = pointRadius * (pointShrink + smoothstep(densityThreshold, densityThreshold*2.0, density)*(1.0-pointShrink))*max(0.0f, min(gl_MultiTexCoord3.x, 0.1))*10.0f;; float scaledPointRadius = pointRadius; // calculate window-space point size vec4 eyeSpacePos = gl_ModelViewMatrix * gl_Vertex; float dist = length(eyeSpacePos.xyz); gl_PointSize = scaledPointRadius * (pointScale / dist); //gl_PointSize = 10.0f; gl_TexCoord[0] = gl_MultiTexCoord0; // sprite texcoord gl_TexCoord[1] = vec4(eyeSpacePos.xyz, scaledPointRadius); // eye space pos gl_TexCoord[2] = vec4(gl_MultiTexCoord2.xyz, density); // velocity and density gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; gl_FrontColor = gl_Color; } ); // render particle as constant shaded disc const char *particleDebugPS = STRINGIFY( uniform float pointRadius; void main() { // calculate eye-space sphere normal from texture coordinates vec3 N; N.xy = gl_TexCoord[0].xy*vec2(2.0, -2.0) + vec2(-1.0, 1.0); float r2 = dot(N.xy, N.xy); if (r2 > 1.0) discard; // kill pixels outside circle // gl_FragColor = gl_Color; gl_FragColor = gl_TexCoord[2].w * 0.001; // show density // gl_FragColor = gl_TexCoord[2]; // show vel } ); // render particle as lit sphere const char *particleSpherePS = STRINGIFY( uniform float pointRadius; uniform vec3 lightDir = vec3(0.577, 0.577, 0.577); void main() { // calculate eye-space sphere normal from texture coordinates vec3 N; N.xy = gl_TexCoord[0].xy*vec2(2.0, -2.0) + vec2(-1.0, 1.0); float r2 = dot(N.xy, N.xy); if (r2 > 1.0) discard; // kill pixels outside circle N.z = sqrt(1.0-r2); // calculate depth vec4 eyeSpacePos = vec4(gl_TexCoord[1].xyz + N*pointRadius, 1.0); // position of this pixel on sphere in eye space vec4 clipSpacePos = gl_ProjectionMatrix * eyeSpacePos; gl_FragDepth = (clipSpacePos.z / clipSpacePos.w)*0.5+0.5; float diffuse = max(0.0, dot(N, lightDir)); gl_FragColor = diffuse*gl_Color; } ); // visualize density const char *particleDensityPS = STRINGIFY( uniform float pointRadius; uniform vec3 lightDir = vec3(0.577, 0.577, 0.577); uniform float densityScale; uniform float densityOffset; void main() { // calculate eye-space sphere normal from texture coordinates vec3 N; N.xy = gl_TexCoord[0].xy*vec2(2.0, -2.0) + vec2(-1.0, 1.0); float r2 = dot(N.xy, N.xy); if (r2 > 1.0) discard; // kill pixels outside circle N.z = sqrt(1.0-r2); // calculate depth vec4 eyeSpacePos = vec4(gl_TexCoord[1].xyz + N*pointRadius, 1.0); // position of this pixel on sphere in eye space vec4 clipSpacePos = gl_ProjectionMatrix * eyeSpacePos; gl_FragDepth = (clipSpacePos.z / clipSpacePos.w)*0.5+0.5; float diffuse = max(0.0, dot(N, lightDir)); // calculate color based on density float x = 1.0 - saturate((gl_TexCoord[2].w - densityOffset) * densityScale); vec3 color = lerp(gl_Color.xyz, vec3(1.0, 1.0, 1.0), x); gl_FragColor = vec4(diffuse*color, 1.0); } ); // renders eye-space depth const char *particleSurfacePS = STRINGIFY( uniform float pointRadius; uniform float faceScale = 1.0; void main() { // calculate eye-space normal from texture coordinates vec3 N; N.xy = gl_TexCoord[0].xy*vec2(2.0, -2.0) + vec2(-1.0, 1.0); float r2 = dot(N.xy, N.xy); if (r2 > 1.0) discard; // kill pixels outside circle N.z = sqrt(1.0-r2)*faceScale; // calculate depth vec4 eyeSpacePos = vec4(gl_TexCoord[1].xyz + N*gl_TexCoord[1].w, 1.0); // position of this pixel on sphere in eye space vec4 clipSpacePos = gl_ProjectionMatrix * eyeSpacePos; gl_FragDepth = (clipSpacePos.z / clipSpacePos.w)*0.5+0.5; gl_FragColor = eyeSpacePos.z; // output eye-space depth // gl_FragColor = -eyeSpacePos.z/10.0; } ); // render particle thickness const char *particleThicknessPS = STRINGIFY( uniform vec3 lightDir = vec3(0.577, 0.577, 0.577); uniform float pointRadius; uniform float faceScale = 1.0; void main() { // calculate eye-space normal from texture coordinates vec3 N; N.xy = gl_TexCoord[0].xy*vec2(2.0, -2.0) + vec2(-1.0, 1.0); float r2 = dot(N.xy, N.xy); if (r2 > 1.0) discard; // kill pixels outside circle N.z = sqrt(1.0-r2) * faceScale; // calculate depth vec4 eyeSpacePos = vec4(gl_TexCoord[1].xyz + N*gl_TexCoord[1].w, 1.0); // position of this pixel on sphere in eye space vec4 clipSpacePos = gl_ProjectionMatrix * eyeSpacePos; gl_FragDepth = (clipSpacePos.z / clipSpacePos.w)*0.5+0.5; float alpha = exp(-r2*2.0); // gl_FragColor = eyeSpacePos.z; // output distance gl_FragColor = N.z*pointRadius*2.0*alpha; // output thickness } ); // motion blur shaders const char *mblurVS = STRINGIFY( uniform float timestep = 0.02; uniform vec3 eyeVel; uniform float iStartFade = 1.0; void main() { vec3 pos = gl_Vertex.xyz; vec3 vel = gl_MultiTexCoord2.xyz; //vel = vec3(10.0f,0.0f,0.0f); vec3 pos2 = (pos - (vel+eyeVel)*timestep); // previous position gl_Position = gl_ModelViewMatrix * vec4(pos, 1.0); // eye space gl_TexCoord[0] = gl_ModelViewMatrix * vec4(pos2, 1.0); gl_TexCoord[1].x = gl_MultiTexCoord1.x; gl_TexCoord[1].y = max(0.0f, min(gl_MultiTexCoord3.x*iStartFade, 1.0f)); gl_TexCoord[2].xyz = pos; gl_TexCoord[3] = gl_MultiTexCoord4; gl_FrontColor = gl_Color; } ); const char *mblurGS = STRINGIFY( //#version 120\n //#extension GL_EXT_geometry_shader4 : enable\n uniform float pointRadius; // point size in world space uniform float densityThreshold = 50.0; uniform float idensityThreshold = 1.0 / 50.0; uniform float pointShrink = 0.25; void main() { gl_FrontColor = gl_FrontColorIn[0]; float density = gl_TexCoordIn[0][1].x; float life = gl_TexCoordIn[0][1].y; // scale down point size based on density float pointSize = pointRadius; pointSize *= gl_TexCoordIn[0][3].x; // eye space vec3 pos = gl_PositionIn[0].xyz; vec3 pos2 = gl_TexCoordIn[0][0].xyz; vec3 motion = pos - pos2; vec3 dir = normalize(motion); float len = length(motion); vec3 x = dir * pointSize; vec3 view = normalize(-pos); vec3 y = normalize(cross(dir, view)) * pointSize; float facing = dot(view, dir); // check for very small motion to avoid jitter float threshold = 0.01; // if (len < threshold) { if ((len < threshold) || (facing > 0.95) || (facing < -0.95)) { pos2 = pos; x = vec3(pointSize, 0.0, 0.0); y = vec3(0.0, -pointSize, 0.0); } //if (density < densityThreshold) { gl_TexCoord[0] = vec4(0, 0, 0, life); gl_TexCoord[2] = vec4(pos + x + y, 1); gl_Position = gl_ProjectionMatrix * gl_TexCoord[2]; gl_TexCoord[3] = gl_TexCoordIn[0][2]; EmitVertex(); gl_TexCoord[0] = vec4(0, 1, 0, life); gl_TexCoord[2] = vec4(pos + x - y, 1); gl_Position = gl_ProjectionMatrix * gl_TexCoord[2]; gl_TexCoord[3] = gl_TexCoordIn[0][2]; EmitVertex(); gl_TexCoord[0] = vec4(1, 0, 0, life); gl_TexCoord[2] = vec4(pos2 - x + y, 1); gl_Position = gl_ProjectionMatrix * gl_TexCoord[2]; gl_TexCoord[3] = gl_TexCoordIn[0][2]; EmitVertex(); gl_TexCoord[0] = vec4(1, 1, 0, life); gl_TexCoord[2] = vec4(pos2 - x - y, 1); gl_Position = gl_ProjectionMatrix * gl_TexCoord[2]; gl_TexCoord[3] = gl_TexCoordIn[0][2]; EmitVertex(); //} } ); const char *mblurGSNoKill = STRINGIFY( //#version 120\n //#extension GL_EXT_geometry_shader4 : enable\n uniform float pointRadius; // point size in world space uniform float densityThreshold = 50.0; uniform float idensityThreshold = 1.0 / 30.0; uniform float pointShrink = 0.25; uniform sampler2D meteorTex; void main() { gl_FrontColor = gl_FrontColorIn[0]; float density = gl_TexCoordIn[0][1].x; float life = gl_TexCoordIn[0][1].y; gl_TexCoord[1].xy = 0.25f*vec2(gl_PrimitiveIDIn / 4, gl_PrimitiveIDIn % 4); // scale down point size based on density float factor = 1.0f;//density * idensityThreshold; //smoothstep(0.0f, densityThreshold, density); //density * idensityThreshold; //clamp(density / 50.0f, 0, 1); float pointSize = pointRadius*factor;//*(pointShrink + smoothstep(0.0, densityThreshold, density)*(1.0-pointShrink)); pointSize *= gl_TexCoordIn[0][3].x; float tmp = gl_TexCoordIn[0][3].y; float bb = 1.0f; if (tmp > 0.5f) { //gl_FrontColor = vec4(3*life,0,0,1); // TODO: Meteor trail color here... //vec2 fetchPos = vec2( min(max((3-lifeTime)/3,0),1), 0); float val = 1-min(max((life-0.3)/0.2,0.01),0.99); vec2 fetchPos = vec2(val, 0); gl_FrontColor = texture2D(meteorTex, fetchPos); if (gl_FrontColor.r > 0.5) bb += (gl_FrontColor.r-0.5)*(gl_FrontColor.r-0.5)*10; } // float pointSize = pointRadius; // eye space vec3 pos = gl_PositionIn[0].xyz; vec3 pos2 = gl_TexCoordIn[0][0].xyz; vec3 motion = pos - pos2; vec3 dir = normalize(motion); float len = length(motion); vec3 x = dir * pointSize; vec3 view = normalize(-pos); vec3 y = normalize(cross(dir, view)) * pointSize; float facing = dot(view, dir); // check for very small motion to avoid jitter float threshold = 0.01; // if (len < threshold) { if ((len < threshold) || (facing > 0.95) || (facing < -0.95)) { pos2 = pos; x = vec3(pointSize, 0.0, 0.0); y = vec3(0.0, -pointSize, 0.0); } float angle = density; float cv = cos(angle); float sv = sin(angle); vec3 xt = cv*x + sv*y; vec3 yt = -sv*x + cv*y; x = xt; y = yt; { gl_TexCoord[0] = vec4(0, 0, bb, life); gl_TexCoord[2] = vec4(pos + x + y, 1); gl_Position = gl_ProjectionMatrix * gl_TexCoord[2]; gl_TexCoord[3] = gl_TexCoordIn[0][2]; EmitVertex(); gl_TexCoord[0] = vec4(0, 1, bb, life); gl_TexCoord[2] = vec4(pos + x - y, 1); gl_Position = gl_ProjectionMatrix * gl_TexCoord[2]; EmitVertex(); gl_TexCoord[0] = vec4(1, 0, bb, life); gl_TexCoord[2] = vec4(pos2 - x + y, 1); gl_Position = gl_ProjectionMatrix * gl_TexCoord[2]; EmitVertex(); gl_TexCoord[0] = vec4(1, 1, bb, life); gl_TexCoord[2] = vec4(pos2 - x - y, 1); gl_Position = gl_ProjectionMatrix * gl_TexCoord[2]; EmitVertex(); /* gl_TexCoord[0] = vec4(0, 0, 0, life); gl_TexCoord[2] = vec4(pos + x + y, 1); gl_Position = gl_ProjectionMatrix * gl_TexCoord[2]; EmitVertex(); gl_TexCoord[0] = vec4(0, 1, 0, life); gl_TexCoord[2] = vec4(pos + x - y, 1); gl_Position = gl_ProjectionMatrix * gl_TexCoord[2]; EmitVertex(); gl_TexCoord[0] = vec4(1, 0, 0, life); gl_TexCoord[2] = vec4(pos2 - x + y, 1); gl_Position = gl_ProjectionMatrix * gl_TexCoord[2]; EmitVertex(); gl_TexCoord[0] = vec4(1, 1, 0, life); gl_TexCoord[2] = vec4(pos2 - x - y, 1); gl_Position = gl_ProjectionMatrix * gl_TexCoord[2]; EmitVertex(); */ } } ); const char *particleSprayPS = STRINGIFY( uniform sampler2DArrayShadow stex; uniform float shadowAmbient = 0.5; uniform vec3 lightDir; float shadowCoef() { const int index = 0; /* int index = 3; // find the appropriate depth map to look up in based on the depth of this fragment if(gl_FragCoord.z < far_d.x) index = 0; else if(gl_FragCoord.z < far_d.y) index = 1; else if(gl_FragCoord.z < far_d.z) index = 2; */ // transform this fragment's position from view space to scaled light clip space // such that the xy coordinates are in [0;1] // note there is no need to divide by w for othogonal light sources vec4 shadow_coord = gl_TextureMatrix[index]*vec4(gl_TexCoord[2].xyz, 1); shadow_coord.w = shadow_coord.z; // tell glsl in which layer to do the look up shadow_coord.z = float(index); // Gaussian 3x3 filter return shadow2DArray(stex, shadow_coord).x; } void main() { //gl_FragColor = vec4(1.0f,1.0f,1.0f,1.0f); //return; // calculate eye-space normal from texture coordinates vec3 N; N.xy = gl_TexCoord[0].xy*vec2(2.0, -2.0) + vec2(-1.0, 1.0); float mag = dot(N.xy, N.xy); if (mag > 1.0) discard; // kill pixels outside circle float falloff = exp(-mag*4.0); float shadowC = shadowCoef(); gl_FragColor = gl_Color*(shadowAmbient + (1.0f -shadowAmbient)*shadowC)*(abs(dot(lightDir, N))*0.3f+0.7f );//*falloff; float fog = clamp(gl_Fog.scale*(gl_Fog.end+gl_TexCoord[2].z), 0.0, 1.0); //float fog = exp(-gl_Fog.density*(gl_TexCoord[0].z*gl_TexCoord[0].z)); gl_FragColor = mix(gl_Fog.color, gl_FragColor, fog); gl_FragColor.w *= falloff * gl_TexCoord[0].w; } ); const char *particleSprayGenFOMPS= STRINGIFY( const float PI = 3.1415926535897932384626433832795; const vec4 factor_a = vec4(2.0*PI)*vec4(0.0,1.0,2.0,3.0); const vec4 factor_b = vec4(2.0*PI)*vec4(1.0,2.0,3.0,0.0); const vec4 factor_m2 = vec4(-2.0); uniform float ispotMaxDist; void main() { // calculate eye-space normal from texture coordinates vec3 N; N.xy = gl_TexCoord[0].xy*vec2(2.0, -2.0) + vec2(-1.0, 1.0); float mag = dot(N.xy, N.xy); if (mag > 1.0) discard; // kill pixels outside circle // float falloff = exp(-mag*4.0); //float falloff = pow(1.0-mag,1.5);//exp(-mag); float falloff = 1.0; float opacity = gl_Color.a * falloff * min(gl_TexCoord[0].w,1.0f); float distance = sqrt(dot(gl_TexCoord[2].xyz, gl_TexCoord[2].xyz))*ispotMaxDist; //compute value for projection into Fourier basis vec4 cos_a0123 = cos(factor_a*vec4(distance)); vec4 sin_b123 = sin(factor_b*vec4(distance)); vec4 lnOpacitR = factor_m2*vec4(log(1.0-opacity)); gl_FragData[0] = lnOpacitR*cos_a0123; gl_FragData[1] = lnOpacitR*sin_b123; } ); const char *particleSprayUseFOMPS = STRINGIFY( uniform sampler2DArrayShadow stex; uniform float shadowAmbient = 0.5; float shadowCoef() { const int index = 0; /* int index = 3; // find the appropriate depth map to look up in based on the depth of this fragment if(gl_FragCoord.z < far_d.x) index = 0; else if(gl_FragCoord.z < far_d.y) index = 1; else if(gl_FragCoord.z < far_d.z) index = 2; */ // transform this fragment's position from view space to scaled light clip space // such that the xy coordinates are in [0;1] // note there is no need to divide by w for othogonal light sources vec4 shadow_coord = gl_TextureMatrix[index]*vec4(gl_TexCoord[2].xyz, 1); shadow_coord.w = shadow_coord.z; // tell glsl in which layer to do the look up shadow_coord.z = float(index); // Gaussian 3x3 filter return shadow2DArray(stex, shadow_coord).x; } uniform float ispotMaxDist; uniform vec3 spotOriginEye; uniform sampler2D spot_a0123; uniform sampler2D spot_b123; const float PI = 3.1415926535897932384626433832795; const vec3 _2pik = vec3(2.0) * vec3(PI,2.0*PI,3.0*PI); const vec3 factor_a = vec3(2.0*PI)*vec3(1.0,2.0,3.0); const vec3 factor_b = vec3(2.0*PI)*vec3(1.0,2.0,3.0); const vec3 value_1 = vec3(1.0); uniform mat4 eyeToSpotMatrix; void main() { // calculate eye-space normal from texture coordinates vec3 N; N.xy = gl_TexCoord[0].xy*vec2(2.0, -2.0) + vec2(-1.0, 1.0); float mag = dot(N.xy, N.xy); if (mag > 1.0) discard; // kill pixels outside circle float falloff = pow(1.0-mag,1.0);//exp(-mag); //falloff = 1.0f; float shadowC = 1.0f;//shadowCoef(); // Also FOM // vec4 projectionCoordinate = eyeToSpotMatrix*vec4(gl_TexCoord[2].xyz, 1.0f); vec4 projectionCoordinate = eyeToSpotMatrix*vec4(gl_TexCoord[2].xyz, 1.0f); //gl_FragColor.xyz = gl_TexCoord[3].xyz*0.25f; //gl_FragColor.xyz = projectionCoordinate.xyz / projectionCoordinate.w; //gl_FragColor.w = 1.0f; //read Fourier series coefficients for color extinction on RGB vec4 sR_a0123 = texture2DProj(spot_a0123,projectionCoordinate); vec3 sR_b123 = texture2DProj(spot_b123,projectionCoordinate).rgb; //gl_FragColor.xyz = sR_a0123.xyz; //gl_FragColor.w = 1.0f; //return; //compute absolute and normalized distance (in spot depth range) float distance2spotCenter = length(spotOriginEye-gl_TexCoord[2].xyz);//distance from spot origin to surfel in world space float d = distance2spotCenter*ispotMaxDist; //compute some value to recover the extinction coefficient using the Fourier series vec3 sin_a123 = sin(factor_a*vec3(d)); vec3 cos_b123 = value_1-cos(factor_b*vec3(d)); //compute the extinction coefficients using Fourier float att = (sR_a0123.r*d/2.0) + dot(sin_a123*(sR_a0123.gba/_2pik) ,value_1) + dot(cos_b123*(sR_b123.rgb/_2pik) ,value_1); att = max(0.0f, att); att = min(1.0f, att); shadowC = (1.0f-att); //.... gl_FragColor.xyz = gl_Color.xyz*(shadowAmbient + (1.0f -shadowAmbient)*shadowC);//*falloff; gl_FragColor.w = gl_Color.w; //float fog = clamp(gl_Fog.scale*(gl_Fog.end+gl_TexCoord[2].z), 0.0, 1.0); //float fog = exp(-gl_Fog.density*(gl_TexCoord[0].z*gl_TexCoord[0].z)); //gl_FragColor = mix(gl_Fog.color, gl_FragColor, fog); gl_FragColor.w *= max(min(falloff,1.0f),0.0f) * max(min(gl_TexCoord[0].w,1.0f),0.0f); // gl_FragColor.w = 0.2f; //gl_FragColor.w = falloff * gl_TexCoord[0].w; //gl_FragColor.xyz = sR_a0123.xyz; } ); // motion blur shaders const char *particleDumbFoamVS = STRINGIFY( uniform float timestep = 0.02; // GPU Water uniform sampler2D waterHFTex; uniform float minEta; uniform float fracEta; uniform vec2 hfScale; // 1/(sx*dx), 1/(sz*dx) uniform vec2 hfOffset; // 0.5/sx, 0.5/sz uniform vec2 hfCellOffset; // 1.0/sx, 1.0/sz uniform vec2 origin; uniform float dx; uniform float waterHOffset; uniform vec4 foamFactor = vec4(1.0/4, 1.0/4,0,0); void main() { vec2 hfTexCoord = (gl_Vertex.xz - origin)*hfScale + hfOffset; vec4 etaH = texture2D(waterHFTex, hfTexCoord); vec4 etaHxp1 = texture2D(waterHFTex, hfTexCoord + hfCellOffset*vec2(1,0)); vec4 etaHxm1 = texture2D(waterHFTex, hfTexCoord + hfCellOffset*vec2(-1,0)); vec4 etaHzp1 = texture2D(waterHFTex, hfTexCoord + hfCellOffset*vec2(0,1)); vec4 etaHzm1 = texture2D(waterHFTex, hfTexCoord + hfCellOffset*vec2(0,-1)); float h = etaH.x+etaH.y; float hxp1 = etaHxp1.x+etaHxp1.y; float hxm1 = etaHxm1.x+etaHxm1.y; float hzp1 = etaHzp1.x+etaHzp1.y; float hzm1 = etaHzm1.x+etaHzm1.y; vec3 pos = gl_Vertex.xyz; vec3 vel = gl_MultiTexCoord2.xyz; vec3 normal = vec3(-normalize(cross(vec3(2*dx, hxp1-hxm1, 0), vec3(0, hzp1-hzm1, 2*dx))));//vec3(0,1,0); vec3 bitangent = normalize(cross(vec3(1,0,0), normal)); vec3 tangent = normalize(cross(bitangent, normal)); gl_Position = gl_ModelViewMatrix * vec4(pos, 1.0); // eye space gl_TexCoord[0] = gl_MultiTexCoord2 * foamFactor; gl_TexCoord[1] = gl_ModelViewMatrix * vec4(tangent, 0.0); gl_TexCoord[2] = gl_ModelViewMatrixInverseTranspose * vec4(normal, 0.0); gl_TexCoord[3] = gl_ModelViewMatrix * vec4(bitangent, 0.0); gl_TexCoord[0].w = max(0.0f, min(gl_MultiTexCoord3.x, 0.1))*10;// Fade with life time gl_FrontColor = gl_Color; } ); const char *particleFoamVS = STRINGIFY( uniform float timestep = 0.02; // GPU Water uniform float minEta; uniform float fracEta; uniform float dx; uniform vec4 foamFactor = vec4(1.0/4, 1.0/4,0,0); uniform float foamOffset; uniform float foamOffset2; uniform float foamOffset3; void main() { vec3 pos = gl_Vertex.xyz; vec3 normal = normalize(gl_MultiTexCoord2.xyz); vec3 bitangent = normalize(cross(vec3(1,0,0), normal)); vec3 tangent = normalize(cross(bitangent, normal)); gl_Position = gl_ModelViewMatrix * vec4(pos + normal*foamOffset + vec3(0.0f, foamOffset3, 0.0f), 1.0); // eye space vec3 eyeVec = normalize(gl_Position.xyz); gl_Position.xyz -= eyeVec*foamOffset2; gl_TexCoord[0] = gl_MultiTexCoord2 * foamFactor; gl_TexCoord[1] = gl_ModelViewMatrix * vec4(tangent, 0.0); gl_TexCoord[2] = gl_ModelViewMatrixInverseTranspose * vec4(normal, 0.0); gl_TexCoord[3] = gl_ModelViewMatrix * vec4(bitangent, 0.0); gl_TexCoord[0].w = max(0.0f, min(gl_MultiTexCoord3.x, 0.1))*10;// Fade with life time gl_FrontColor = gl_Color; } ); const char *particleDumbFoamGS = STRINGIFY( //#version 120\n //#extension GL_EXT_geometry_shader4 : enable\n uniform float pointRadius; // point size in world space uniform float densityThreshold = 500.0; uniform float pointShrink = 0.25; uniform float foamTexSize = 0.249; void main() { gl_FrontColor = gl_FrontColorIn[0]; // eye space vec3 pos = gl_PositionIn[0].xyz; vec3 x = pointRadius*gl_TexCoordIn[0][1].xyz; vec3 normal = gl_TexCoordIn[0][2].xyz; vec3 y = -pointRadius*gl_TexCoordIn[0][3].xyz; gl_TexCoord[0] = gl_TexCoordIn[0][0]+vec4(0, 0, 0, 0); gl_TexCoord[1] = vec4(normal, gl_TexCoordIn[0][0].w); gl_TexCoord[2] = vec4(pos + x + y, 1); gl_TexCoord[3] = vec4(1, 1, 0, 0); gl_Position = gl_ProjectionMatrix * gl_TexCoord[2]; EmitVertex(); gl_TexCoord[0] = gl_TexCoordIn[0][0]+vec4(0, foamTexSize, 0, 0); gl_TexCoord[2] = vec4(pos + x - y, 1); gl_Position = gl_ProjectionMatrix * gl_TexCoord[2]; gl_TexCoord[3] = vec4(1, -1, 0, 0); EmitVertex(); gl_TexCoord[0] = gl_TexCoordIn[0][0]+vec4(foamTexSize, 0, 0, 0); gl_TexCoord[2] = vec4(pos - x + y, 1); gl_Position = gl_ProjectionMatrix * gl_TexCoord[2]; gl_TexCoord[3] = vec4(-1, 1, 0, 0); EmitVertex(); gl_TexCoord[0] = gl_TexCoordIn[0][0]+vec4(foamTexSize, foamTexSize, 0, 0); gl_TexCoord[2] = vec4(pos - x - y, 1); gl_Position = gl_ProjectionMatrix * gl_TexCoord[2]; gl_TexCoord[3] = vec4(-1, -1, 0, 0); EmitVertex(); } ); const char *particleDumbFoamPS = STRINGIFY( uniform float pointRadius; uniform vec3 lightDir; uniform sampler2D foamTex; uniform sampler2DArrayShadow stex; float shadowCoef() { const int index = 0; /* int index = 3; // find the appropriate depth map to look up in based on the depth of this fragment if(gl_FragCoord.z < far_d.x) index = 0; else if(gl_FragCoord.z < far_d.y) index = 1; else if(gl_FragCoord.z < far_d.z) index = 2; */ // transform this fragment's position from view space to scaled light clip space // such that the xy coordinates are in [0;1] // note there is no need to divide by w for othogonal light sources vec4 shadow_coord = gl_TextureMatrix[index]*vec4(gl_TexCoord[2].xyz, 1); shadow_coord.w = shadow_coord.z; // tell glsl in which layer to do the look up shadow_coord.z = float(index); // Gaussian 3x3 filter return shadow2DArray(stex, shadow_coord).x; } uniform float foamAmbient = 0.8f; uniform float foamDiffuse = 0.2f; void main() { // calculate eye-space normal from texture coordinates float fog = clamp(gl_Fog.scale*(gl_Fog.end+gl_TexCoord[2].z), 0.0, 1.0); float mag = clamp(1.1-dot(gl_TexCoord[3].xy,gl_TexCoord[3].xy),0,1); gl_FragColor.xyz = mix(gl_Fog.color, gl_Color*(foamAmbient + (foamDiffuse*max(dot(gl_TexCoord[1].xyz, lightDir),0.0f) )*shadowCoef()), fog);//*falloff; gl_FragColor.w = /*texture2D(foamTex, gl_TexCoord[0]).r**/gl_Color.w*mag*gl_TexCoord[1].w; // } ); const char *particleFoamPS = STRINGIFY( uniform float pointRadius; uniform vec3 lightDir; uniform sampler2D foamTex; uniform sampler2DArrayShadow stex; float shadowCoef() { const int index = 0; /* int index = 3; // find the appropriate depth map to look up in based on the depth of this fragment if(gl_FragCoord.z < far_d.x) index = 0; else if(gl_FragCoord.z < far_d.y) index = 1; else if(gl_FragCoord.z < far_d.z) index = 2; */ // transform this fragment's position from view space to scaled light clip space // such that the xy coordinates are in [0;1] // note there is no need to divide by w for othogonal light sources vec4 shadow_coord = gl_TextureMatrix[index]*vec4(gl_TexCoord[2].xyz, 1); shadow_coord.w = shadow_coord.z; // tell glsl in which layer to do the look up shadow_coord.z = float(index); // Gaussian 3x3 filter return shadow2DArray(stex, shadow_coord).x; } uniform float foamAmbient = 0.5f; uniform float foamDiffuse = 0.5f; void main() { // calculate eye-space normal from texture coordinates //float fog = clamp(gl_Fog.scale*(gl_Fog.end+gl_TexCoord[2].z), 0.0, 1.0); float mag = clamp(1.1-dot(gl_TexCoord[3].xy,gl_TexCoord[3].xy),0,1); gl_FragColor.xyz = gl_Color*( foamAmbient + (foamDiffuse*abs(dot(gl_TexCoord[1].xyz, lightDir)))*shadowCoef() );//*falloff; gl_FragColor.w = /*texture2D(foamTex, gl_TexCoord[0]).r**/gl_Color.w*mag*gl_TexCoord[1].w; // } ); // screen-space shaders const char *passThruVS = STRINGIFY( void main() { gl_Position = gl_Vertex; gl_TexCoord[0] = gl_MultiTexCoord0; gl_TexCoord[1] = gl_Vertex; gl_FrontColor = gl_Color; } ); // blur depth map // separable version const char *depthBlurPS = STRINGIFY( //#extension GL_ARB_texture_rectangle : enable\n sampler2DRect colorTex; uniform vec2 scale = 1.0; const float r = 10.0; uniform float blurScale = 2.0 / r; uniform float blurDepthFalloff = 2.0; uniform float depthThreshold = 0.5; void main() { float center = texture2DRect(colorTex, gl_TexCoord[0].xy).x; if (center < -9999.0) { // skip background pixels discard; return; } float sum = 0; float wsum = 0; for(float x=-r; x<=r; x+=1.0) { float sample = texture2DRect(colorTex, gl_TexCoord[0].xy + x*scale).x; // bilateral filter // spatial domain float r = x * blurScale; float w = exp(-r*r); //float w = 1.0; // range domain (based on depth difference) float r2 = (sample - center) * blurDepthFalloff; //float g = 1.0; float g = exp(-r2*r2); //float g = abs(sample - center) < depthThreshold; sum += sample * w * g; wsum += w * g; } if (wsum > 0.0) { sum /= wsum; } gl_FragColor.x = sum; } ); // 2D non-separable version const char *depthBlur2DPS = STRINGIFY( //#extension GL_ARB_texture_rectangle : enable\n sampler2DRect colorTex; uniform vec2 scale = 1.0; const float r = 10.0; uniform float blurScale = 2.0 / r; uniform float blurDepthFalloff = 1.0; uniform float depthThreshold = 0.1; void main() { float center = texture2DRect(colorTex, gl_TexCoord[0].xy).x; if (center < -9999.0) { discard; return; } float sum = 0; float wsum = 0; for(float y=-r; y<=r; y+=1.0) { for(float x=-r; x<=r; x+=1.0) { float sample = texture2DRect(colorTex, gl_TexCoord[0].xy + vec2(x, y)).x; // bilateral filter // spatial domain //float r = length(vec2(x, y)) * blurScale; // float w = exp(-r*r); float rsq = (x*x + y*y) * blurScale * blurScale; float w = exp(-rsq); //float w = 1.0; // range domain (based on depth difference) float r2 = (sample - center) * blurDepthFalloff; //float g = 1.0; float g = exp(-r2*r2); // float g = abs(sample - center) < depthThreshold; sum += sample * w * g; wsum += w * g; } } if (wsum > 0.0) { sum /= wsum; } gl_FragColor.x = sum; } ); // symmetrical filter (see "Screen Space Meshes" paper) const char *depthBlurSymPS = STRINGIFY( //#extension GL_ARB_texture_rectangle : enable\n sampler2DRect colorTex; uniform vec2 scale = 1.0; const float r = 10.0; uniform float blurScale = 2.0; uniform float blurDepthFalloff = 2.0; uniform float depthThreshold = 0.25; void main() { float center = texture2DRect(colorTex, gl_TexCoord[0].xy).x; if (center == 0.0) { discard; return; } float sum = center; float wsum = 1.0; for(float x=1.0; x<=r; x+=1.0) { float sample = texture2DRect(colorTex, gl_TexCoord[0].xy + x*scale).x; float sample2 = texture2DRect(colorTex, gl_TexCoord[0].xy - x*scale).x; bool valid = abs(sample - center) < depthThreshold; bool valid2 = abs(sample2 - center) < depthThreshold; if (valid && valid2) { float r = (x / r) * blurScale; float w = exp(-r*r); sum += sample * w; wsum += w; sum += sample2 * w; wsum += w; } } if (wsum > 0.0) { sum /= wsum; } gl_FragColor.x = sum; } ); // display final shaded surface const char *displaySurfacePS = STRINGIFY( //#extension GL_ARB_texture_rectangle : enable\n uniform sampler2DRect colorTex; uniform sampler2DRect depthTex; uniform sampler2DRect thicknessTex; uniform sampler2DRect sceneTex; uniform samplerCube cubemapTex; uniform vec3 lightDir = vec3(0.577, 0.577, 0.577); uniform vec2 invViewport = vec2(1.0 / 800, 1.0 / 600); uniform float2 invFocalLen; uniform float depthThreshold = 0.1; uniform float shininess = 40.0; uniform vec4 fluidColor = vec4(0.5, 0.7, 1.0, 0.0); uniform vec4 colorFalloff = vec4(2.0, 1.0, 0.5, 1.0); uniform vec4 specularColor = vec4(1.0, 1.0, 1.0, 1.0); //uniform vec4 specularColor = vec4(0.25, 0.25, 0.25, 1.0); uniform float falloffScale = 0.3; //uniform float falloffScale = 0.1; uniform vec3 thicknessRefraction = vec3(2.0, 2.3, 2.6); uniform float subSample = 1; uniform float fresnelBias = 0.1; uniform float fresnelScale = 0.4; uniform float fresnelPower = 2.0; // 5.0 is physically correct // convert [0,1] uv coords and eye-space Z to eye-space position vec3 uvToEye(vec2 uv, float eyeZ) { uv = uv * vec2(-2.0, -2.0) - vec2(-1.0, -1.0); return vec3(uv * invFocalLen * eyeZ, eyeZ); } vec3 getEyePos(sampler2DRect tex, vec2 texCoord) { float eyeZ = texture2DRect(tex, texCoord).x; return uvToEye(texCoord*invViewport, eyeZ); } void main() { float c = texture2DRect(colorTex, gl_TexCoord[0].xy).x; if (c < -9999.0) { discard; return; } // calculate normal // taking silohette edges into account vec2 uv = gl_TexCoord[0].xy * invViewport; vec3 eyePos = uvToEye(uv, c); vec3 ddx = getEyePos(colorTex, gl_TexCoord[0].xy + vec2(1, 0)) - eyePos; if (abs(ddx.z) > depthThreshold) { ddx = eyePos - getEyePos(colorTex, gl_TexCoord[0].xy + vec2(-1, 0)); } vec3 ddy = getEyePos(colorTex, gl_TexCoord[0].xy + vec2(0, 1)) - eyePos; if (abs(ddy.z) > depthThreshold) { ddy = eyePos - getEyePos(colorTex, gl_TexCoord[0].xy + vec2(0, -1)); } vec3 n = cross(ddx, ddy); n = normalize(n); // lighting // float diffuse = max(0.0, dot(n, lightDir)); float diffuse = dot(n, lightDir)*0.5+0.5; // wrap lighting vec3 v = normalize(-eyePos); vec3 h = normalize(lightDir + v); float specular = pow(max(0.0, dot(n, h)), shininess); float fresnel = fresnelBias + fresnelScale*pow(1.0 - max(0.0, dot(n, v)), fresnelPower); // cubemap vec3 r = reflect(-v, n); r = r * gl_NormalMatrix; vec4 reflectColor = textureCube(cubemapTex, r); // color attenuation based on thickness float thickness = texture2DRect(thicknessTex, gl_TexCoord[0].xy * subSample).x; vec4 attenuatedColor = fluidColor * exp(-thickness*falloffScale*colorFalloff); // vec4 attenuatedColor = exp(-thickness*falloffScale*colorFalloff); // refraction float refraction = thickness*thicknessRefraction.x; vec4 sceneCol = texture2DRect(sceneTex, (gl_TexCoord[0].xy * subSample) + (n.xy * refraction)); /* // dispersive refraction vec3 refraction = thickness*thicknessRefraction; vec4 sceneCol; sceneCol.r = texture2DRect(sceneTex, gl_TexCoord[0].xy + (n.xy * refraction.x)).r; sceneCol.g = texture2DRect(sceneTex, gl_TexCoord[0].xy + (n.xy * refraction.y)).g; sceneCol.b = texture2DRect(sceneTex, gl_TexCoord[0].xy + (n.xy * refraction.z)).b; sceneCol.a = 1.0; */ vec4 finalCol = vec4(attenuatedColor.xyz + reflectColor.xyz*fresnel + specularColor.xyz*specular, 1.0); float alpha = saturate(attenuatedColor.w); // gl_FragColor = -c.z; // gl_FragColor = vec4(n*0.5+0.5, 1.0); // gl_FragColor = vec4(diffuse.xxx, 1.0); // gl_FragColor = vec4(specular.xxx, 1.0); // gl_FragColor = vec4(fresnel.xxx, 1.0); // gl_FragColor = diffuse*fluidColor + specular; // gl_FragColor = vec4(eyePos*0.5+0.5, 1.0); // gl_FragColor = thickness; // gl_FragColor = vec4(attenuatedColor.xyz, 1.0); // gl_FragColor = attenuatedColor.w; // gl_FragColor = alpha; gl_FragColor = lerp(finalCol, sceneCol, alpha); // gl_FragColor = sceneCol*attenuatedColor + reflectColor*fresnel + specularColor*specular; // gl_FragDepth = texture2DRect(depthTex, gl_TexCoord[0].xy).x; gl_FragDepth = texture2DRect(depthTex, gl_TexCoord[0].xy * subSample).x; //gl_FragColor.w = 1.0; } ); // new version (handles transparency differently) const char *displaySurfaceNewPS = STRINGIFY( //#extension GL_ARB_texture_rectangle : enable\n uniform sampler2DRect colorTex; uniform sampler2DRect depthTex; uniform sampler2DRect thicknessTex; uniform sampler2DRect sceneTex; uniform samplerCube cubemapTex; uniform vec3 lightDir = vec3(0.577, 0.577, 0.577); uniform vec2 invViewport = vec2(1.0 / 800, 1.0 / 600); uniform float2 invFocalLen; uniform float depthThreshold = 0.1; uniform float shininess = 40.0; uniform vec4 fluidColor = vec4(0.5, 0.7, 1.0, 0.0); uniform vec4 colorFalloff = vec4(2.0, 1.0, 0.5, 1.0); uniform vec4 specularColor = vec4(0.5, 0.5, 0.5, 1.0); uniform float falloffScale = 0.01; uniform vec3 thicknessRefraction = vec3(2.0, 2.1, 2.2); uniform float subSample = 1; uniform float fresnelBias = 0.1; uniform float fresnelScale = 0.4; uniform float fresnelPower = 2.0; // 5.0 is physically correct // convert [0,1] uv coords and eye-space Z to eye-space position vec3 uvToEye(vec2 uv, float eyeZ) { uv = uv * vec2(-2.0, -2.0) - vec2(-1.0, -1.0); return vec3(uv * invFocalLen * eyeZ, eyeZ); } vec3 getEyePos(sampler2DRect tex, vec2 texCoord) { float eyeZ = texture2DRect(tex, texCoord).x; return uvToEye(texCoord*invViewport, eyeZ); } void main() { float c = texture2DRect(colorTex, gl_TexCoord[0].xy).x; if (c < -9999.0) { discard; return; } // calculate normal // taking silohette edges into account vec2 uv = gl_TexCoord[0].xy * invViewport; vec3 eyePos = uvToEye(uv, c); vec3 ddx = getEyePos(colorTex, gl_TexCoord[0].xy + vec2(1, 0)) - eyePos; if (abs(ddx.z) > depthThreshold) { ddx = eyePos - getEyePos(colorTex, gl_TexCoord[0].xy + vec2(-1, 0)); } vec3 ddy = getEyePos(colorTex, gl_TexCoord[0].xy + vec2(0, 1)) - eyePos; if (abs(ddy.z) > depthThreshold) { ddy = eyePos - getEyePos(colorTex, gl_TexCoord[0].xy + vec2(0, -1)); } vec3 n = cross(ddx, ddy); n = normalize(n); // lighting // float diffuse = max(0.0, dot(n, lightDir)); float diffuse = dot(n, lightDir)*0.5+0.5; // wrap lighting vec3 v = normalize(-eyePos); vec3 h = normalize(lightDir + v); float specular = pow(max(0.0, dot(n, h)), shininess); float fresnel = fresnelBias + fresnelScale*pow(1.0 - max(0.0, dot(n, v)), fresnelPower); // cubemap vec3 r = reflect(-v, n); r = r * gl_NormalMatrix; vec4 reflectColor = textureCube(cubemapTex, r); // color attenuation based on thickness float thickness = texture2DRect(thicknessTex, gl_TexCoord[0].xy * subSample).x; vec4 attenuatedColor = exp(-thickness*falloffScale*colorFalloff); // refraction // float refraction = thickness*thicknessRefraction.x; // vec4 sceneCol = texture2DRect(sceneTex, (gl_TexCoord[0].xy * subSample) + (n.xy * refraction)); // dispersive refraction vec3 refraction = thickness*thicknessRefraction; vec4 sceneCol; sceneCol.r = texture2DRect(sceneTex, gl_TexCoord[0].xy + (n.xy * refraction.x)).r; sceneCol.g = texture2DRect(sceneTex, gl_TexCoord[0].xy + (n.xy * refraction.y)).g; sceneCol.b = texture2DRect(sceneTex, gl_TexCoord[0].xy + (n.xy * refraction.z)).b; sceneCol.a = 1.0; gl_FragColor = sceneCol*attenuatedColor + reflectColor*fresnel + specularColor*specular; gl_FragDepth = texture2DRect(depthTex, gl_TexCoord[0].xy * subSample).x; } ); // non-transparent version for oil etc. const char *displaySurfaceSolidPS = STRINGIFY( //#extension GL_ARB_texture_rectangle : enable\n uniform sampler2DRect colorTex; uniform sampler2DRect depthTex; uniform samplerCube cubemapTex; uniform vec3 lightDir = vec3(0.577, 0.577, 0.577); uniform vec2 invViewport = vec2(1.0 / 800, 1.0 / 600); uniform float2 invFocalLen; uniform float depthThreshold = 0.1; uniform float shininess = 40.0; uniform vec4 diffuseColor = vec4(0.0, 0.0, 0.0, 0.0); uniform vec4 specularColor = vec4(0.75, 0.75, 0.75, 1.0); uniform float subSample = 1; uniform float fresnelBias = 0.1; uniform float fresnelScale = 0.4; uniform float fresnelPower = 2.0; // 5.0 is physically correct // convert [0,1] uv coords and eye-space Z to eye-space position vec3 uvToEye(vec2 uv, float eyeZ) { uv = uv * vec2(-2.0, -2.0) - vec2(-1.0, -1.0); return vec3(uv * invFocalLen * eyeZ, eyeZ); } vec3 getEyePos(sampler2DRect tex, vec2 texCoord) { float eyeZ = texture2DRect(tex, texCoord).x; return uvToEye(texCoord*invViewport, eyeZ); } void main() { float c = texture2DRect(colorTex, gl_TexCoord[0].xy).x; if (c < -9999.0) { discard; return; } // calculate normal // taking silohette edges into account vec2 uv = gl_TexCoord[0].xy * invViewport; vec3 eyePos = uvToEye(uv, c); vec3 ddx = getEyePos(colorTex, gl_TexCoord[0].xy + vec2(1, 0)) - eyePos; if (abs(ddx.z) > depthThreshold) { ddx = eyePos - getEyePos(colorTex, gl_TexCoord[0].xy + vec2(-1, 0)); } vec3 ddy = getEyePos(colorTex, gl_TexCoord[0].xy + vec2(0, 1)) - eyePos; if (abs(ddy.z) > depthThreshold) { ddy = eyePos - getEyePos(colorTex, gl_TexCoord[0].xy + vec2(0, -1)); } vec3 n = cross(ddx, ddy); n = normalize(n); // lighting float diffuse = max(0.0, dot(n, lightDir)); // float diffuse = dot(n, lightDir)*0.5+0.5; // wrap lighting vec3 v = normalize(-eyePos); vec3 h = normalize(lightDir + v); float specular = pow(max(0.0, dot(n, h)), shininess); float fresnel = fresnelBias + fresnelScale*pow(1.0 - max(0.0, dot(n, v)), fresnelPower); // cubemap vec3 r = reflect(-v, n); r = r * gl_NormalMatrix; vec4 reflectColor = textureCube(cubemapTex, r); gl_FragColor = diffuseColor*diffuse + reflectColor*fresnel + specularColor*specular; gl_FragDepth = texture2DRect(depthTex, gl_TexCoord[0].xy * subSample).x; } ); // chrome surface using cubemap const char *displaySurfaceChromePS = STRINGIFY( //#extension GL_ARB_texture_rectangle : enable\n uniform sampler2DRect colorTex; uniform sampler2DRect depthTex; uniform samplerCube cubemapTex; uniform vec3 lightDir = vec3(0.577, 0.577, 0.577); uniform vec2 invViewport = vec2(1.0 / 800, 1.0 / 600); uniform float2 invFocalLen; uniform float depthThreshold = 0.1; uniform float shininess = 40.0; uniform vec4 fluidColor = vec4(0.5, 0.7, 1.0, 0.0); uniform float subSample = 1; // convert [0,1] uv coords and eye-space Z to eye-space position vec3 uvToEye(vec2 uv, float eyeZ) { uv = uv * vec2(-2.0, -2.0) - vec2(-1.0, -1.0); return vec3(uv * invFocalLen * eyeZ, eyeZ); } vec3 getEyePos(sampler2DRect tex, vec2 texCoord) { float eyeZ = texture2DRect(tex, texCoord).x; return uvToEye(texCoord*invViewport, eyeZ); } void main() { float c = texture2DRect(colorTex, gl_TexCoord[0].xy).x; if (c < -9999.0) { discard; return; } // calculate normal // taking silohette edges into account vec2 uv = gl_TexCoord[0].xy * invViewport; vec3 eyePos = uvToEye(uv, c); vec3 ddx = getEyePos(colorTex, gl_TexCoord[0].xy + vec2(1, 0)) - eyePos; vec3 ddx2 = eyePos - getEyePos(colorTex, gl_TexCoord[0].xy + vec2(-1, 0)); // if (abs(ddx.z) > abs(ddx2.z)) { if (abs(ddx.z) > depthThreshold) { ddx = ddx2; } vec3 ddy = getEyePos(colorTex, gl_TexCoord[0].xy + vec2(0, 1)) - eyePos; vec3 ddy2 = eyePos - getEyePos(colorTex, gl_TexCoord[0].xy + vec2(0, -1)); // if (abs(ddy2.z) < abs(ddy.z)) { if (abs(ddy.z) > depthThreshold) { ddy = ddy2; } vec3 n = cross(ddx, ddy); n = normalize(n); // lighting float diffuse = max(0.0, dot(n, lightDir)); // float diffuse = dot(n, lightDir)*0.5+0.5; // wrap lighting // vec3 v = vec3(0, 0, 1); vec3 v = normalize(-eyePos); vec3 h = normalize(lightDir + v); float specular = pow(max(0.0, dot(n, h)), shininess); // float fresnel = pow(1.0 - max(0.0, dot(n, v)), 5.0); float fresnel = 0.2 + 0.8*pow(1.0 - max(0.0, dot(n, v)), 2.0); //float fresnel = 1.0 - max(0.0, dot(n, v)); // cubemap vec3 r = reflect(-v, n); // r = (mat3) gl_ModelViewMatrixInverse * r; r = r * gl_NormalMatrix; vec4 reflectColor = textureCube(cubemapTex, r); // gl_FragColor = reflectColor * fresnel; gl_FragColor = reflectColor * (0.5 + 0.5*diffuse); gl_FragDepth = texture2DRect(depthTex, gl_TexCoord[0].xy * subSample).x; } ); const char *textureRectPS = STRINGIFY( //#extension GL_ARB_texture_rectangle : enable\n uniform sampler2DRect tex; void main() { gl_FragColor = texture2DRect(tex, gl_TexCoord[0].xy); } ); // dilate depth image by taking maximum value of neighbourhood const char *dilatePS = STRINGIFY( //#extension GL_ARB_texture_rectangle : enable\n uniform sampler2DRect tex; void main() { float c = texture2DRect(tex, gl_TexCoord[0].xy).x; if (c < -9999.0) { c = max(c, texture2DRect(tex, gl_TexCoord[0].xy + vec2(1, 0)).x); c = max(c, texture2DRect(tex, gl_TexCoord[0].xy + vec2(1, 1)).x); c = max(c, texture2DRect(tex, gl_TexCoord[0].xy + vec2(0, 1)).x); //c = max(c, texture2DRect(tex, gl_TexCoord[0].xy + vec2(-1, 0)).x); //c = max(c, texture2DRect(tex, gl_TexCoord[0].xy + vec2(1, 0)).x); //c = max(c, texture2DRect(tex, gl_TexCoord[0].xy + vec2(0, -1)).x); //c = max(c, texture2DRect(tex, gl_TexCoord[0].xy + vec2(0, 1)).x); } gl_FragColor = c; } ); // NUTT // Water heightfield thickness vertex shader const char *hfThicknessVS = STRINGIFY( uniform float zMax; void main() { vec4 eyeSpacePos = gl_ModelViewMatrix * vec4(gl_Vertex.xyz,1); vec4 eyeNormal = gl_ModelViewMatrixInverseTranspose * vec4(gl_Normal.xyz,0); //gl_TexCoord[0] = vec4(eyeSpacePos.xyz,0); // sprite texcoord //float tc = 0.1*(zFar + eyeSpacePos.z); float dis = sqrt(dot(eyeSpacePos,eyeSpacePos)); float tc = (zMax-dis); //gl_FrontColor = vec4(tc,tc,-tc,1); //gl_BackColor = vec4(-tc,-tc,-tc,1); //float tc = 0.1; if (dot(eyeNormal.xyz,eyeSpacePos.xyz) > 0) { gl_TexCoord[0] = vec4(tc,tc,tc,1); } else { gl_TexCoord[0]= vec4(-tc,-tc,-tc,1); } gl_Position = gl_ProjectionMatrix * eyeSpacePos; //gl_BackColor = vec4(1,1,1,1);//vec4(-1000,-1000,-1000,1);//vec4(-2*tc,-2*tc,-2*tc,1); } ); // Water heightfield thickness PS const char *hfThicknessPS = STRINGIFY( //#extension GL_ARB_texture_rectangle : enable\n void main() { gl_FragColor = gl_TexCoord[0]; //gl_FragColor = gl_Color; //gl_FragColor = ( } ); // Water heightfield thickness PS const char *hfThicknessAddPS = STRINGIFY( //#extension GL_ARB_texture_rectangle : enable\n uniform sampler2DRect thicknessTex; void main() { // Add contribution of heightfield fluid thickness to particle thickness vec4 col = texture2DRect(thicknessTex, gl_TexCoord[0].xy); col.x = max(col.x, 0.0); //col.x*=-1; /* if (col.x > 10) { gl_FragColor = vec4(0,0,0,1); } else { */ gl_FragColor = vec4(col.x,col.x,col.x,1); //} } ); // Water heightfield depth vertex shader const char *hfDepthVS = STRINGIFY( void main() { vec4 eyeSpacePos = gl_ModelViewMatrix * gl_Vertex; gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; gl_TexCoord[0] = vec4(eyeSpacePos.xyz,0); // sprite texcoord } ); // Water heightfield depth PS const char *hfDepthPS = STRINGIFY( //#extension GL_ARB_texture_rectangle : enable\n void main() { gl_FragColor = vec4(gl_TexCoord[0].z,gl_TexCoord[0].z,gl_TexCoord[0].z,1); } ); // Turn depth map to distance from eye and subtract const char *depthToInitThicknessPS = STRINGIFY( //#extension GL_ARB_texture_rectangle : enable\n uniform sampler2DRect depthTex; uniform float zNear; uniform float zFar; uniform float mulX; uniform float mulY; uniform float zMax; void main() { float glDepth = texture2DRect(depthTex, gl_TexCoord[0].xy).x; float eyeDepth = zNear*zFar / (zFar - glDepth*(zFar-zNear)); gl_FragDepth = glDepth; //gl_FragDepth = texture2DRect(depthTex, gl_TexCoord[0].xy).x; //gl_FragColor = vec4(gl_FragDepth,gl_FragDepth,gl_FragDepth,1); //float val = 0.001*(-(zFar - eyeDepth)); //float val = -(zFar-eyeDepth)*0.1; vec3 eyePos = vec3(gl_TexCoord[1].x*eyeDepth*mulX, gl_TexCoord[1].y*eyeDepth*mulY, eyeDepth); float val = -(zMax-sqrt(dot(eyePos,eyePos))); gl_FragColor = vec4( val,val,val, 1); } ); // Debug PS const char *debugPS = STRINGIFY( //#extension GL_ARB_texture_rectangle : enable\n uniform sampler2DRect thicknessTex; void main() { vec4 col = texture2DRect(thicknessTex, gl_TexCoord[0].xy); col.x*=-0.01; // if (col.x > 1) { // gl_FragColor = vec4(1,0,0,1); // } else { gl_FragColor = vec4(col.x,col.x,col.x,1); // } //gl_FragColor = vec4(1,0,1,1); } ); // Debug Triangle VS const char *debugTriVS = STRINGIFY( void main() { vec4 eyeSpacePos = gl_ModelViewMatrix * gl_Vertex; vec4 eyeSpaceNormal = gl_ModelViewMatrixInverseTranspose * vec4(gl_Normal.xyz,1); gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; vec3 eyeVec = normalize(eyeSpacePos.xyz); float dp = dot(eyeSpaceNormal.xyz,eyeVec.xyz); if (dp > 0) { gl_FrontColor = vec4(dp,0,0,1); } else { gl_FrontColor = vec4(0,-dp,0,1); } } ); const char *copyPS = STRINGIFY( //#extension GL_ARB_texture_rectangle : enable\n uniform sampler2DRect depthTex; uniform sampler2DRect sceneTex; void main() { gl_FragColor = texture2DRect(sceneTex, gl_TexCoord[0].xy); gl_FragDepth = texture2DRect(depthTex, gl_TexCoord[0].xy).x; } ); // Debug Triangle PS const char *debugTriPS = STRINGIFY( //#extension GL_ARB_texture_rectangle : enable\n void main() { gl_FragColor = gl_Color; } ); // display final shaded surface Nuttapong's mod const char *displaySurfaceNutPS = STRINGIFY( //#extension GL_ARB_texture_rectangle : enable\n uniform vec2 colorTexScale; uniform sampler2DArrayShadow stex; uniform sampler2DRect colorTex; uniform sampler2DRect depthTex; uniform sampler2DRect thicknessTex; uniform sampler2DRect sceneTex; uniform samplerCube cubemapTex; uniform vec3 lightDir = vec3(0.577, 0.577, 0.577); uniform vec2 invViewport = vec2(1.0 / 800, 1.0 / 600); uniform float2 invFocalLen; uniform float depthThreshold = 0.01; uniform float shininess = 40.0; //uniform vec4 fluidColor = vec4(0.5, 0.7, 1.0, 0.0); uniform vec4 fluidColor = vec4(17/255.0, 52/255.0, 71/255.0, 0.0); uniform vec4 colorFalloff = vec4(2.0, 1.0, 0.5, 1.0); uniform vec4 specularColor = vec4(0.7, 0.7, 0.7, 1.0); //uniform vec4 specularColor = vec4(0.25, 0.25, 0.25, 1.0); uniform float falloffScale = 0.03; //uniform float falloffScale = 0.1; uniform vec3 thicknessRefraction = vec3(2.0, 2.3, 2.6); uniform float subSample = 1; uniform float fresnelBias = 0.0; uniform float fresnelScale = 1.0; uniform float fresnelPower = 2.0; // 5.0 is physically correct uniform float shadowAmbient = 0.9; uniform float splashZShadowBias = 0.001f; uniform float refracMultiplier = 1.0; uniform float epsilon = 0.0001f; uniform float thicknessAlphaMul = 3.0f; uniform float decayRate = 1.0f; // convert [0,1] uv coords and eye-space Z to eye-space position vec3 uvToEye(vec2 uv, float eyeZ) { uv = uv * vec2(-2.0, -2.0) - vec2(-1.0, -1.0); return vec3(uv * invFocalLen * eyeZ, eyeZ); } vec3 getEyePos(sampler2DRect tex, vec2 texCoord) { float eyeZ = texture2DRect(tex, texCoord*colorTexScale).x; return uvToEye(texCoord*invViewport, eyeZ); } float shadowCoef(float3 eyePos) { const int index = 0; /* int index = 3; // find the appropriate depth map to look up in based on the depth of this fragment if(gl_FragCoord.z < far_d.x) index = 0; else if(gl_FragCoord.z < far_d.y) index = 1; else if(gl_FragCoord.z < far_d.z) index = 2; */ // transform this fragment's position from view space to scaled light clip space // such that the xy coordinates are in [0;1] // note there is no need to divide by w for othogonal light sources vec4 shadow_coord = gl_TextureMatrix[index]*vec4(eyePos.x, eyePos.y, eyePos.z,1); shadow_coord.w = shadow_coord.z + splashZShadowBias; // tell glsl in which layer to do the look up shadow_coord.z = float(index); // Gaussian 3x3 filter return shadow2DArray(stex, shadow_coord).x; } void main() { //gl_FragColor = vec4(1.0f, 0.0f, 0.0f, 1.0f); //return; float c = texture2DRect(colorTex, gl_TexCoord[0].xy*colorTexScale).x; if (c < -9999.0) { discard; return; } // calculate normal // taking silohette edges into account vec2 uv = gl_TexCoord[0].xy * invViewport; vec3 eyePos = uvToEye(uv, c); vec3 ddx = getEyePos(colorTex, gl_TexCoord[0].xy + vec2(1, 0)) - eyePos; vec3 ddx2 = eyePos - getEyePos(colorTex, gl_TexCoord[0].xy + vec2(-1, 0)); vec3 ddy = getEyePos(colorTex, gl_TexCoord[0].xy + vec2(0, 1)) - eyePos; vec3 ddy2 = eyePos - getEyePos(colorTex, gl_TexCoord[0].xy + vec2(0, -1)); float thickness = texture2DRect(thicknessTex, gl_TexCoord[0].xy * subSample).x; float refBlend = 0.0f; float maxDz = max(max(abs(ddx.z),abs(ddx2.z)), max(abs(ddy.z),abs(ddy2.z))); if (maxDz > depthThreshold) { refBlend = 1.0f - exp((depthThreshold - maxDz)*decayRate); } // if (abs(ddx.z) > abs(ddx2.z)) { //if (abs(ddx.z) > depthThreshold) { if (abs(ddx2.z) < abs(ddx.z)) { ddx = ddx2; } //} // if (abs(ddy2.z) < abs(ddy.z)) { //if (abs(ddy.z) > depthThreshold) { if (abs(ddy2.z) < abs(ddy.z)) { ddy = ddy2; } //} ddx.x += epsilon; ddy.y += epsilon; //vec3 ddx = getEyePos(colorTex, gl_TexCoord[0].xy + vec2(1, 0)) - getEyePos(colorTex, gl_TexCoord[0].xy + vec2(-1, 0)); //vec3 ddy = getEyePos(colorTex, gl_TexCoord[0].xy + vec2(0, 1)) - getEyePos(colorTex, gl_TexCoord[0].xy + vec2(0, -1)); //ddx.z = clamp(ddx.z, -depthThreshold, depthThreshold); //ddy.z = clamp(ddy.z, -depthThreshold, depthThreshold); // color attenuation based on thickness //ddx = normalize(ddx); //ddy = normalize(ddy); //if (depthThreshold < 0.001f) { // vec3 nn = cross(ddx, ddy); //gl_FragColor = vec4(sqrt(dot(ddx,ddx)), sqrt(dot(ddy, ddy)), sqrt(dot(nn,nn)), 1.0f); // gl_FragColor = vec4(10.0f*sqrt(dot(nn,nn)), 0.0f, 0.0f, 1.0f); // return; //} //ddx.z = clamp(ddx.z, -depthThreshold, depthThreshold); //ddy.z = clamp(ddy.z, -depthThreshold, depthThreshold); vec3 n = normalize(cross(ddx, ddy)); // lighting // float diffuse = max(0.0, dot(n, lightDir)); float diffuse = dot(n, lightDir)*0.5+0.5; // wrap lighting vec3 v = normalize(-eyePos); vec3 h = normalize(lightDir + v); float specular = pow(max(0.0, dot(n, h)), shininess*10); float fresnel = fresnelBias + fresnelScale*pow(1.0 - max(0.0, dot(n, v)), fresnelPower); // cubemap vec3 r = reflect(-v, n); r = r * gl_NormalMatrix; vec4 reflectColor = textureCube(cubemapTex, r); // vec4 attenuatedColor = exp(-thickness*falloffScale*colorFalloff); // refraction // ----------------- // Pond //vec4 attenuatedColor = fluidColor * exp(-thickness*falloffScale*colorFalloff); //float refracMultiplier = 1; //float refraction = thickness*thicknessRefraction.x*refracMultiplier; //vec4 sceneCol = texture2DRect(sceneTex, (gl_TexCoord[0].xy * subSample) + (n.xy * refraction)); //vec4 finalCol = vec4((1-fresnel)*sceneCol.xyz + reflectColor.xyz*fresnel + specularColor.xyz*specular, 1.0); // Whirlpool //float refracMultiplier = 0.1; //float refraction = thickness*thicknessRefraction.x*refracMultiplier; //vec4 sceneCol = texture2DRect(sceneTex, (gl_TexCoord[0].xy * subSample) + (n.xy * refraction)); //vec3 blendFactor = vec3(1,1,1)+2*thickness*falloffScale*vec3(1,1,1); //blendFactor = min(blendFactor, vec3(1,1,1)); //blendFactor = max(blendFactor, vec3(0,0,0)); //sceneCol.xyz = lerp(vec3(0.13, 0.19, 0.22), sceneCol.xyz, blendFactor); //vec4 finalCol = vec4((1-fresnel)*sceneCol.xyz + reflectColor.xyz*fresnel + specularColor.xyz*specular, 1.0); // FERMI float refraction = thickness*thicknessRefraction.x*refracMultiplier; vec4 sceneCol = texture2DRect(sceneTex, (gl_TexCoord[0].xy * subSample) + (n.xy * refraction)); reflectColor = (1.0f-refBlend)*reflectColor + refBlend*sceneCol; // colorFalloff = vec4(0.5, 0.5, 0.5, 1.0); vec4 attenuatedColor = exp(-thickness*falloffScale*colorFalloff*10.0); //vec3 blendFactor = vec3(1,1,1)+2*thickness*falloffScale*vec3(1,1,1); //blendFactor = min(0.5, blendFactor); //blendFactor = min(blendFactor, vec3(1,1,1)); //blendFactor = max(blendFactor, vec3(0,0,0)); //fluidColor = vec4(1.0f, 1.0f, 1.0f, 1.0f); //fluidColor = vec4(28/255.0, 69/255.0, 89/255.0, 0.0); //fluidColor = vec4(17/255.0, 52/255.0, 71/255.0, 0.0); sceneCol.xyz = lerp(fluidColor, sceneCol.xyz, attenuatedColor); //sceneCol = fluidColor; //sceneCol.xyz = vec3(0.0f,0.0f,0.0f); //vec4 finalCol = vec4((1-fresnel)*sceneCol.xyz + reflectColor.xyz*fresnel /*+ specularColor.xyz*specular*/, 1.0); float shadow = shadowCoef(eyePos); float sc = (1.0f - shadowAmbient)*shadow + shadowAmbient; vec4 finalCol = vec4((1-fresnel)*sceneCol.xyz + reflectColor.xyz*fresnel + specularColor.xyz*specular*shadow*0.9, 1.0); gl_FragColor = vec4(finalCol.xyz*(sc), max(0.0f, min(1.0, thicknessAlphaMul*thickness/*2.0f*(gl_TexCoord[1].w+waterHOffset)*/))); // gl_FragColor = finalCol; // gl_FragColor.w = max(0.0f, min(1.0, 3.0f*thickness)); /* vec4 sceneSeethroughCol = texture2DRect(sceneTex, gl_TexCoord[0].xy); //---------------- float thickPar = 0.0000001; float blendBackground = max(0.0, min(1.0f, -thickness / thickPar)); gl_FragColor = (blendBackground)*finalCol + (1.0-blendBackground)*sceneSeethroughCol; if (thickness < 0) gl_FragColor = vec4(1.0f,0.0f,0.0f,1.0f); else */ //gl_FragColor = finalCol; // gl_FragColor = sceneCol*attenuatedColor + reflectColor*fresnel + specularColor*specular; // gl_FragDepth = texture2DRect(depthTex, gl_TexCoord[0].xy).x; float fog = clamp(gl_Fog.scale*(gl_Fog.end+eyePos.z), 0.0, 1.0); //float fog = exp(-gl_Fog.density*(eyePos.z*eyePos.z)); gl_FragColor = mix(gl_Fog.color, gl_FragColor, fog); gl_FragDepth = texture2DRect(depthTex, gl_TexCoord[0].xy * colorTexScale).x; //gl_FragColor = vec4(1.0f, 0.0f, 0.0f, 1.0f); //return; //gl_FragColor.w = max(0.0, min((thickness)*5.0, 1.0)); //gl_FragColor.w = 1.0; //gl_FragColor = vec4(n.z, n.z, n.z, 1); } ); // render particle as lit sphere const char *particleBubblePS = STRINGIFY( uniform float pointRadius; uniform vec3 lightDir = vec3(0.577, 0.577, 0.577); uniform samplerCube cubemapTex; uniform sampler2DRect sceneTex; uniform vec2 viewportd2 = vec2(300,300); uniform float shininess = 40.0; uniform vec4 fluidColor = vec4(0.5, 0.7, 1.0, 0.0); uniform vec4 colorFalloff = vec4(2.0, 1.0, 0.5, 1.0); uniform vec4 specularColor = vec4(0.5, 0.5, 0.5, 1.0); //uniform vec4 specularColor = vec4(0.25, 0.25, 0.25, 1.0); uniform float falloffScale = 0.3; //uniform float falloffScale = 0.1; uniform vec3 thicknessRefraction = vec3(2.0, 2.3, 2.6); uniform float subSample = 1; uniform float fresnelBias = 0; uniform float fresnelScale = 0.4; uniform float fresnelPower = 2.0; // 5.0 is physically correct void main() { // calculate eye-space sphere normal from texture coordinates vec3 N; N.xy = gl_TexCoord[0].xy*vec2(2.0, -2.0) + vec2(-1.0, 1.0); float r2 = dot(N.xy, N.xy); if (r2 > 1.0) discard; // kill pixels outside circle N.z = sqrt(1.0-r2); // calculate depth vec4 eyeSpacePos = vec4(gl_TexCoord[1].xyz + N*pointRadius, 1.0); // position of this pixel on sphere in eye space vec4 clipSpacePos = gl_ProjectionMatrix * eyeSpacePos; gl_FragDepth = (clipSpacePos.z / clipSpacePos.w)*0.5+0.5; float diffuse = max(0.0, dot(N, lightDir)); //gl_FragColor = diffuse*gl_Color; gl_FragColor = gl_Color; gl_FragColor.w = (1.0-r2)*(1.0-r2)*0.4; vec3 v = normalize(-eyeSpacePos.xyz); vec3 h = normalize(lightDir + v); float specular = pow(max(0.0, dot(N, h)), shininess); float fresnel = fresnelBias + fresnelScale*pow(1.0 - max(0.0, dot(N, v)), fresnelPower); // cubemap vec3 r = reflect(-v, N); vec4 reflectColor = textureCube(cubemapTex, r); // color attenuation based on thickness float thickness = 0; // refraction // ----------------- // Pond //vec4 attenuatedColor = fluidColor * exp(-thickness*falloffScale*colorFalloff); //float refracMultiplier = 1; //float refraction = thickness*thicknessRefraction.x*refracMultiplier; //vec4 sceneCol = texture2DRect(sceneTex, (gl_TexCoord[0].xy * subSample) + (n.xy * refraction)); //vec4 finalCol = vec4((1-fresnel)*sceneCol.xyz + reflectColor.xyz*fresnel + specularColor.xyz*specular, 1.0); // Whirlpool vec2 tx = viewportd2 + viewportd2*vec2(clipSpacePos.x/clipSpacePos.w, clipSpacePos.y/clipSpacePos.w); vec4 sceneCol = texture2DRect(sceneTex, tx); //vec4 sceneCol = texture2DRect(sceneTex, gl_TexCoord[0].xy); //sceneCol = vec4(1,1,1,1);'' //sceneCol.xyz = lerp(vec3(0.13, 0.19, 0.22), sceneCol.xyz, blendFactor); vec4 finalCol = vec4((1-fresnel)*sceneCol.xyz + reflectColor.xyz*fresnel + specularColor.xyz*specular, 1.0); //vec4 finalCol = vec4((1-fresnel)*specularColor.xyz*specular, 1.0); float vn = (1-dot(N,v)); finalCol = vn*vn*gl_Color+specularColor*specular; finalCol.w = finalCol.x; finalCol.xyz = gl_Color; //---------------- gl_FragColor = finalCol*0.8; //gl_FragColor.w = 0.4; //gl_FragColor = vec4(clipSpacePos.x/clipSpacePos.w, clipSpacePos.y/clipSpacePos.w, 0, 1); //gl_FragColor *= gl_FragColor.w; } ); const char *depthBlurViewIDPS = STRINGIFY( //#extension GL_ARB_texture_rectangle : enable\n sampler2DRect colorTex; uniform float world2texScale; uniform float tex2worldScale; uniform float maxBlurRadius = 50; uniform float blurRadiusImagePlane = 10; // in world space uniform vec2 blurDir; // direction of blur uniform float XYFalloff = 0.02; uniform float depthFalloff = 1.00; void main() { float center = -texture2DRect(colorTex, gl_TexCoord[0].xy).x; if (center < -9999.0) { // skip background pixels discard; return; } float myWorld2Tex = world2texScale / center; float rawRad = blurRadiusImagePlane / center; float sampleRadius = round(rawRad); sampleRadius = min(sampleRadius, maxBlurRadius); sampleRadius = max(0.0, sampleRadius); float myTex2World = tex2worldScale * center; //sampleRadius = max(0.0f, sampleRadius); //sampleRadius = 0; float sum = 0; float wsum = 0; for(float i=-sampleRadius; i<=sampleRadius; i+=1) { // step of 1 pixel float sample = -texture2DRect(colorTex, gl_TexCoord[0].xy + i*blurDir).x; float x = i * myTex2World; // bilateral filter // spatial domain float r = x * XYFalloff; float cut = (rawRad - abs(i)) / (rawRad); float w = exp(-r*r) * max(0.0f, pow(cut, 0.4)) ; // range domain (based on depth difference) float r2 = (sample - center) * depthFalloff; //float g = 1.0; float g = exp(-r2*r2); sum += sample * w * g; wsum += w * g; } if (wsum > 0.0) { sum /= wsum; } gl_FragColor.x = -sum; } ); const char *depthBlurViewIDNonSepPS = STRINGIFY( //#extension GL_ARB_texture_rectangle : enable\n sampler2DRect colorTex; uniform float world2texScale; uniform float tex2worldScale; uniform float maxBlurRadius = 2; uniform float blurRadiusImagePlane = 10; // in world space uniform float XYFalloff = 0.02; uniform float depthFalloff = 1.00; void main() { float center = -texture2DRect(colorTex, gl_TexCoord[0].xy).x; if (center < -9999.0) { // skip background pixels discard; return; } float myWorld2Tex = world2texScale / center; float rawRad = blurRadiusImagePlane / center; float sampleRadius = round(rawRad); sampleRadius = min(sampleRadius, maxBlurRadius); sampleRadius = max(0.0, sampleRadius); float myTex2World = tex2worldScale * center; //sampleRadius = max(0.0f, sampleRadius); //sampleRadius = 0; float sum = 0; float wsum = 0; for(float i=-sampleRadius; i<=sampleRadius; i+=1) { // step of 1 pixel float y = i * myTex2World; for(float j=-sampleRadius; j<=sampleRadius; j+=1) { // step of 1 pixel float sample = -texture2DRect(colorTex, gl_TexCoord[0].xy + vec2(j, i)).x; float x = j * myTex2World; float dis = sqrt(x*x+y*y); // bilateral filter // spatial domain float r = dis * XYFalloff; float cut = (rawRad - abs(i)) / (rawRad); float w = exp(-r*r) * max(0.0f, pow(cut, 0.4)) ; // range domain (based on depth difference) float r2 = (sample - center) * depthFalloff; //float g = 1.0; float g = exp(-r2*r2); sum += sample * w * g; wsum += w * g; } } if (wsum > 0.0) { sum /= wsum; } gl_FragColor.x = -sum; } ); // display final shaded surface Nuttapong's mod const char *displaySurfaceNutEscapePS = STRINGIFY( //#extension GL_ARB_texture_rectangle : enable\n uniform vec2 colorTexScale; uniform sampler2DArrayShadow stex; uniform sampler2DRect colorTex; uniform sampler2DRect depthTex; uniform sampler2DRect thicknessTex; uniform sampler2DRect sceneTex; uniform samplerCube cubemapTex; uniform vec3 lightDir = vec3(0.577, 0.577, 0.577); uniform vec2 invViewport = vec2(1.0 / 800, 1.0 / 600); uniform float2 invFocalLen; uniform float depthThreshold = 0.01; uniform float shininess = 40.0; //uniform vec4 fluidColor = vec4(0.5, 0.7, 1.0, 0.0); uniform vec4 fluidColor = vec4(17/255.0, 52/255.0, 71/255.0, 0.0); uniform vec4 colorFalloff = vec4(2.0, 1.0, 0.5, 1.0); uniform vec4 specularColor = vec4(0.7, 0.7, 0.7, 1.0); //uniform vec4 specularColor = vec4(0.25, 0.25, 0.25, 1.0); uniform float falloffScale = 1.0f; //uniform float falloffScale = 0.1; uniform vec3 thicknessRefraction = vec3(2.0, 2.3, 2.6); uniform float subSample = 1; uniform float fresnelBias = 0.0; uniform float fresnelScale = 1.0; uniform float fresnelPower = 2.0; // 5.0 is physically correct uniform float shadowAmbient = 0.9; uniform float splashZShadowBias = 0.0f; uniform float refracMultiplier = 1.0; uniform float epsilon = 0.0001f; uniform float thicknessAlphaMul = 3.0f; uniform float decayRate = 1.0f; uniform float thicknessScale = 1.0f; uniform float thicknessClamp = 1000.0f; // convert [0,1] uv coords and eye-space Z to eye-space position vec3 uvToEye(vec2 uv, float eyeZ) { uv = uv * vec2(-2.0, -2.0) - vec2(-1.0, -1.0); return vec3(uv * invFocalLen * eyeZ, eyeZ); } vec3 getEyePos(sampler2DRect tex, vec2 texCoord) { float eyeZ = texture2DRect(tex, texCoord*colorTexScale).x; return uvToEye(texCoord*invViewport, eyeZ); } float shadowCoef(float3 eyePos) { const int index = 0; /* int index = 3; // find the appropriate depth map to look up in based on the depth of this fragment if(gl_FragCoord.z < far_d.x) index = 0; else if(gl_FragCoord.z < far_d.y) index = 1; else if(gl_FragCoord.z < far_d.z) index = 2; */ // transform this fragment's position from view space to scaled light clip space // such that the xy coordinates are in [0;1] // note there is no need to divide by w for othogonal light sources vec4 shadow_coord = gl_TextureMatrix[index]*vec4(eyePos.x, eyePos.y, eyePos.z,1); shadow_coord.w = shadow_coord.z + splashZShadowBias; // tell glsl in which layer to do the look up shadow_coord.z = float(index); // Gaussian 3x3 filter return shadow2DArray(stex, shadow_coord).x; } void main() { //gl_FragColor = vec4(1.0f, 0.0f, 0.0f, 1.0f); //return; float c = texture2DRect(colorTex, gl_TexCoord[0].xy*colorTexScale).x; if (c < -9999.0) { discard; return; } // calculate normal // taking silohette edges into account vec2 uv = gl_TexCoord[0].xy * invViewport; vec3 eyePos = uvToEye(uv, c); vec3 ddx = getEyePos(colorTex, gl_TexCoord[0].xy + vec2(1, 0)) - eyePos; vec3 ddx2 = eyePos - getEyePos(colorTex, gl_TexCoord[0].xy + vec2(-1, 0)); vec3 ddy = getEyePos(colorTex, gl_TexCoord[0].xy + vec2(0, 1)) - eyePos; vec3 ddy2 = eyePos - getEyePos(colorTex, gl_TexCoord[0].xy + vec2(0, -1)); float thickness = min(thicknessClamp, texture2DRect(thicknessTex, gl_TexCoord[0].xy * subSample).x* thicknessScale); float refBlend = 0.0f; float maxDz = max(max(abs(ddx.z),abs(ddx2.z)), max(abs(ddy.z),abs(ddy2.z))); if (maxDz > depthThreshold) { refBlend = 1.0f - exp((depthThreshold - maxDz)*decayRate); } // if (abs(ddx.z) > abs(ddx2.z)) { //if (abs(ddx.z) > depthThreshold) { if (abs(ddx2.z) < abs(ddx.z)) { ddx = ddx2; } //} // if (abs(ddy2.z) < abs(ddy.z)) { //if (abs(ddy.z) > depthThreshold) { if (abs(ddy2.z) < abs(ddy.z)) { ddy = ddy2; } //} ddx.x += epsilon; ddy.y += epsilon; //vec3 ddx = getEyePos(colorTex, gl_TexCoord[0].xy + vec2(1, 0)) - getEyePos(colorTex, gl_TexCoord[0].xy + vec2(-1, 0)); //vec3 ddy = getEyePos(colorTex, gl_TexCoord[0].xy + vec2(0, 1)) - getEyePos(colorTex, gl_TexCoord[0].xy + vec2(0, -1)); //ddx.z = clamp(ddx.z, -depthThreshold, depthThreshold); //ddy.z = clamp(ddy.z, -depthThreshold, depthThreshold); // color attenuation based on thickness //ddx = normalize(ddx); //ddy = normalize(ddy); //if (depthThreshold < 0.001f) { // vec3 nn = cross(ddx, ddy); //gl_FragColor = vec4(sqrt(dot(ddx,ddx)), sqrt(dot(ddy, ddy)), sqrt(dot(nn,nn)), 1.0f); // gl_FragColor = vec4(10.0f*sqrt(dot(nn,nn)), 0.0f, 0.0f, 1.0f); // return; //} //ddx.z = clamp(ddx.z, -depthThreshold, depthThreshold); //ddy.z = clamp(ddy.z, -depthThreshold, depthThreshold); vec3 n = normalize(cross(ddx, ddy)); // lighting // float diffuse = max(0.0, dot(n, lightDir)); float diffuse = dot(n, lightDir); // wrap lighting vec3 v = normalize(-eyePos); vec3 h = normalize(lightDir + v); float specular = pow(max(0.0, dot(n, h)), shininess); float fresnel = fresnelBias + fresnelScale*pow(1.0 - max(0.0, dot(n, v)), fresnelPower); // cubemap vec3 r = reflect(-v, n); r = r * gl_NormalMatrix; vec4 reflectColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);//textureCube(cubemapTex, r); // vec4 attenuatedColor = exp(-thickness*falloffScale*colorFalloff); // refraction // ----------------- // Pond //vec4 attenuatedColor = fluidColor * exp(-thickness*falloffScale*colorFalloff); //float refracMultiplier = 1; //float refraction = thickness*thicknessRefraction.x*refracMultiplier; //vec4 sceneCol = texture2DRect(sceneTex, (gl_TexCoord[0].xy * subSample) + (n.xy * refraction)); //vec4 finalCol = vec4((1-fresnel)*sceneCol.xyz + reflectColor.xyz*fresnel + specularColor.xyz*specular, 1.0); // Whirlpool //float refracMultiplier = 0.1; //float refraction = thickness*thicknessRefraction.x*refracMultiplier; //vec4 sceneCol = texture2DRect(sceneTex, (gl_TexCoord[0].xy * subSample) + (n.xy * refraction)); //vec3 blendFactor = vec3(1,1,1)+2*thickness*falloffScale*vec3(1,1,1); //blendFactor = min(blendFactor, vec3(1,1,1)); //blendFactor = max(blendFactor, vec3(0,0,0)); //sceneCol.xyz = lerp(vec3(0.13, 0.19, 0.22), sceneCol.xyz, blendFactor); //vec4 finalCol = vec4((1-fresnel)*sceneCol.xyz + reflectColor.xyz*fresnel + specularColor.xyz*specular, 1.0); // FERMI float refraction = thickness*thicknessRefraction.x*refracMultiplier; vec2 refractedCoord = gl_TexCoord[0].xy + (n.xy * refraction); // don't refract objects in front of surface // float bgDepth = texture2DRect(sceneDepthTex, refractedCoord).x; // if (bgDepth < surfaceDepth) refractedCoord = gl_TexCoord[0].xy; //refractedCoord = lerp(refractedCoord, gl_TexCoord[0].xy, smoothstep(0.01, 0.0, bgDepth - surfaceDepth)); vec4 sceneCol = texture2DRect(sceneTex, refractedCoord); vec4 attenuatedColor = exp(-thickness*falloffScale*colorFalloff); sceneCol.xyz = lerp(fluidColor, sceneCol.xyz, attenuatedColor); vec4 finalCol = vec4((1-fresnel)*sceneCol.xyz + (reflectColor.xyz )*fresnel + specularColor.xyz*specular, 1.0); gl_FragColor = vec4(diffuse, diffuse, diffuse, 1.0f);//finalCol; gl_FragColor = finalCol; gl_FragDepth = texture2DRect(depthTex, gl_TexCoord[0].xy * colorTexScale).x; //gl_FragColor = vec4(1.0f, 0.0f, 0.0f, 1.0f); /* float refraction = thickness*thicknessRefraction.x*refracMultiplier; vec4 sceneCol = texture2DRect(sceneTex, (gl_TexCoord[0].xy * subSample) + (n.xy * refraction)); reflectColor = (1.0f-refBlend)*reflectColor + refBlend*sceneCol; // colorFalloff = vec4(0.5, 0.5, 0.5, 1.0); vec4 attenuatedColor = exp(-thickness*falloffScale*colorFalloff*10.0); //vec3 blendFactor = vec3(1,1,1)+2*thickness*falloffScale*vec3(1,1,1); //blendFactor = min(0.5, blendFactor); //blendFactor = min(blendFactor, vec3(1,1,1)); //blendFactor = max(blendFactor, vec3(0,0,0)); //fluidColor = vec4(1.0f, 1.0f, 1.0f, 1.0f); //fluidColor = vec4(28/255.0, 69/255.0, 89/255.0, 0.0); //fluidColor = vec4(17/255.0, 52/255.0, 71/255.0, 0.0); sceneCol.xyz = lerp(fluidColor, sceneCol.xyz, attenuatedColor); //sceneCol = fluidColor; //sceneCol.xyz = vec3(0.0f,0.0f,0.0f); vec4 finalCol = vec4((1-fresnel)*sceneCol.xyz + reflectColor.xyz*fresnel , 1.0); float shadow = shadowCoef(eyePos); gl_FragColor = vec4(finalCol.xyz*((1.0f - shadowAmbient)*shadow + shadowAmbient), max(0.0f, min(1.0, thicknessAlphaMul*thickness))); // gl_FragColor = finalCol; // gl_FragColor.w = max(0.0f, min(1.0, 3.0f*thickness)); //gl_FragColor = finalCol; // gl_FragColor = sceneCol*attenuatedColor + reflectColor*fresnel + specularColor*specular; // gl_FragDepth = texture2DRect(depthTex, gl_TexCoord[0].xy).x; float fog = clamp(gl_Fog.scale*(gl_Fog.end+eyePos.z), 0.0, 1.0); //float fog = exp(-gl_Fog.density*(eyePos.z*eyePos.z)); gl_FragColor = mix(gl_Fog.color, gl_FragColor, fog); gl_FragDepth = texture2DRect(depthTex, gl_TexCoord[0].xy * colorTexScale).x; */ //gl_FragColor = vec4(1.0f, 0.0f, 0.0f, 1.0f); //return; //gl_FragColor.w = max(0.0, min((thickness)*5.0, 1.0)); //gl_FragColor.w = 1.0; } ); // display final shaded surface Nuttapong's mod const char *displaySurfaceNutEscapeDiffusePS = STRINGIFY( //#extension GL_ARB_texture_rectangle : enable\n uniform vec2 colorTexScale; uniform sampler2DArrayShadow stex; uniform sampler2DRect colorTex; uniform sampler2DRect depthTex; uniform sampler2DRect thicknessTex; uniform sampler2DRect sceneTex; uniform samplerCube cubemapTex; uniform vec3 lightDir = vec3(0.577, 0.577, 0.577); uniform vec2 invViewport = vec2(1.0 / 800, 1.0 / 600); uniform float2 invFocalLen; uniform float depthThreshold = 0.01; uniform float shininess = 40.0; //uniform vec4 fluidColor = vec4(0.5, 0.7, 1.0, 0.0); uniform vec4 fluidColor = vec4(17/255.0, 52/255.0, 71/255.0, 0.0); uniform vec4 colorFalloff = vec4(2.0, 1.0, 0.5, 1.0); uniform vec4 specularColor = vec4(0.7, 0.7, 0.7, 1.0); //uniform vec4 specularColor = vec4(0.25, 0.25, 0.25, 1.0); uniform float falloffScale = 1.0f; //uniform float falloffScale = 0.1; uniform vec3 thicknessRefraction = vec3(2.0, 2.3, 2.6); uniform float subSample = 1; uniform float fresnelBias = 0.0; uniform float fresnelScale = 1.0; uniform float fresnelPower = 2.0; // 5.0 is physically correct uniform float splashZShadowBias = -0.001f; uniform float refracMultiplier = 1.0; uniform float epsilon = 0.0001f; uniform float thicknessAlphaMul = 3.0f; uniform float decayRate = 1.0f; uniform float thicknessScale = 1.0f; uniform float thicknessClamp = 1000.0f; uniform vec3 spotLightPos; uniform vec3 spotLightPos2; uniform vec3 spotLightPos3; uniform float shadowAmbient = 0.5f; //#define BLUISH 1 const int BLUISH = 0; // convert [0,1] uv coords and eye-space Z to eye-space position vec3 uvToEye(vec2 uv, float eyeZ) { uv = uv * vec2(-2.0, -2.0) - vec2(-1.0, -1.0); return vec3(uv * invFocalLen * eyeZ, eyeZ); } vec3 getEyePos(sampler2DRect tex, vec2 texCoord) { float eyeZ = texture2DRect(tex, texCoord*colorTexScale).x; return uvToEye(texCoord*invViewport, eyeZ); } float shadowCoef(float3 eyePos) { const int index = 0; // transform this fragment's position from view space to scaled light clip space // such that the xy coordinates are in [0;1] // note there is no need to divide by w for othogonal light sources vec4 shadow_coord = gl_TextureMatrix[index]*vec4(eyePos.x, eyePos.y, eyePos.z,1); shadow_coord.w = shadow_coord.z + splashZShadowBias; // tell glsl in which layer to do the look up shadow_coord.z = float(index); // Gaussian 3x3 filter return shadow2DArray(stex, shadow_coord).x; } void main() { //gl_FragColor = vec4(1.0f, 0.0f, 0.0f, 1.0f); //return; float c = texture2DRect(colorTex, gl_TexCoord[0].xy*colorTexScale).x; if (c < -9999.0) { discard; return; } // calculate normal // taking silohette edges into account vec2 uv = gl_TexCoord[0].xy * invViewport; vec3 eyePos = uvToEye(uv, c); vec3 ddx = getEyePos(colorTex, gl_TexCoord[0].xy + vec2(1, 0)) - eyePos; vec3 ddx2 = eyePos - getEyePos(colorTex, gl_TexCoord[0].xy + vec2(-1, 0)); vec3 ddy = getEyePos(colorTex, gl_TexCoord[0].xy + vec2(0, 1)) - eyePos; vec3 ddy2 = eyePos - getEyePos(colorTex, gl_TexCoord[0].xy + vec2(0, -1)); float thickness = min(thicknessClamp, texture2DRect(thicknessTex, gl_TexCoord[0].xy * subSample).x* thicknessScale); float refBlend = 0.0f; float maxDz = max(max(abs(ddx.z),abs(ddx2.z)), max(abs(ddy.z),abs(ddy2.z))); if (maxDz > depthThreshold) { refBlend = 1.0f - exp((depthThreshold - maxDz)*decayRate); } // if (abs(ddx.z) > abs(ddx2.z)) { //if (abs(ddx.z) > depthThreshold) { if (abs(ddx2.z) < abs(ddx.z)) { ddx = ddx2; } //} // if (abs(ddy2.z) < abs(ddy.z)) { //if (abs(ddy.z) > depthThreshold) { if (abs(ddy2.z) < abs(ddy.z)) { ddy = ddy2; } //} ddx.x += epsilon; ddy.y += epsilon; //vec3 ddx = getEyePos(colorTex, gl_TexCoord[0].xy + vec2(1, 0)) - getEyePos(colorTex, gl_TexCoord[0].xy + vec2(-1, 0)); //vec3 ddy = getEyePos(colorTex, gl_TexCoord[0].xy + vec2(0, 1)) - getEyePos(colorTex, gl_TexCoord[0].xy + vec2(0, -1)); //ddx.z = clamp(ddx.z, -depthThreshold, depthThreshold); //ddy.z = clamp(ddy.z, -depthThreshold, depthThreshold); // color attenuation based on thickness //ddx = normalize(ddx); //ddy = normalize(ddy); //if (depthThreshold < 0.001f) { // vec3 nn = cross(ddx, ddy); //gl_FragColor = vec4(sqrt(dot(ddx,ddx)), sqrt(dot(ddy, ddy)), sqrt(dot(nn,nn)), 1.0f); // gl_FragColor = vec4(10.0f*sqrt(dot(nn,nn)), 0.0f, 0.0f, 1.0f); // return; //} //ddx.z = clamp(ddx.z, -depthThreshold, depthThreshold); //ddy.z = clamp(ddy.z, -depthThreshold, depthThreshold); vec3 n = normalize(cross(ddx, ddy)); if (dot(n, eyePos.xyz) > 0) { n.xyz *= -1; } // lighting // float diffuse = max(0.0, dot(n, lightDir)); //float diffuse = dot(n, lightDir); // wrap lighting vec3 lvec = normalize(spotLightPos - eyePos); vec3 lvec2 = normalize(spotLightPos2 - eyePos); vec3 lvec3 = normalize(spotLightPos3 - eyePos); float shadowC = shadowCoef(eyePos); float shadowFactor = ((1.0f - shadowAmbient)*shadowC + shadowAmbient); float diffuse = (0.33333f*0.7f*(max(dot(n, lvec),0.0f)+max(dot(n, lvec2),0.0f)+max(dot(n, lvec3),0.0f)))*shadowFactor+0.3f; // wrap lighting vec3 v = normalize(-eyePos); vec3 h = normalize(lightDir + v); float specular = pow(max(0.0, dot(n, h)), shininess); float fresnel = fresnelBias + fresnelScale*pow(1.0 - max(0.0, dot(n, v)), fresnelPower); // cubemap vec3 r = reflect(-v, n); r = r * gl_NormalMatrix; vec4 reflectColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);//textureCube(cubemapTex, r); // vec4 attenuatedColor = exp(-thickness*falloffScale*colorFalloff); // refraction // ----------------- // Pond //vec4 attenuatedColor = fluidColor * exp(-thickness*falloffScale*colorFalloff); //float refracMultiplier = 1; //float refraction = thickness*thicknessRefraction.x*refracMultiplier; //vec4 sceneCol = texture2DRect(sceneTex, (gl_TexCoord[0].xy * subSample) + (n.xy * refraction)); //vec4 finalCol = vec4((1-fresnel)*sceneCol.xyz + reflectColor.xyz*fresnel + specularColor.xyz*specular, 1.0); // Whirlpool //float refracMultiplier = 0.1; //float refraction = thickness*thicknessRefraction.x*refracMultiplier; //vec4 sceneCol = texture2DRect(sceneTex, (gl_TexCoord[0].xy * subSample) + (n.xy * refraction)); //vec3 blendFactor = vec3(1,1,1)+2*thickness*falloffScale*vec3(1,1,1); //blendFactor = min(blendFactor, vec3(1,1,1)); //blendFactor = max(blendFactor, vec3(0,0,0)); //sceneCol.xyz = lerp(vec3(0.13, 0.19, 0.22), sceneCol.xyz, blendFactor); //vec4 finalCol = vec4((1-fresnel)*sceneCol.xyz + reflectColor.xyz*fresnel + specularColor.xyz*specular, 1.0); // FERMI //float refraction = thickness*thicknessRefraction.x*refracMultiplier; //vec2 refractedCoord = gl_TexCoord[0].xy + (n.xy * refraction); // don't refract objects in front of surface // float bgDepth = texture2DRect(sceneDepthTex, refractedCoord).x; // if (bgDepth < surfaceDepth) refractedCoord = gl_TexCoord[0].xy; //refractedCoord = lerp(refractedCoord, gl_TexCoord[0].xy, smoothstep(0.01, 0.0, bgDepth - surfaceDepth)); vec3 sceneCol = texture2DRect(sceneTex, gl_TexCoord[0].xy).xyz; vec3 bb = vec3(diffuse,diffuse,diffuse); if (BLUISH) { vec4 col1 = 1.5*vec4(116,147,179,255) / 200.0; bb = col1.xyz*diffuse; } //#endif float alpha = clamp(thickness, 0.0f, 1.0f); gl_FragColor.xyz = (1.0f-alpha)*sceneCol + alpha*bb; gl_FragColor.w = 1.0f; //gl_FragColor = finalCol; gl_FragDepth = texture2DRect(depthTex, gl_TexCoord[0].xy * colorTexScale).x; //gl_FragColor = vec4(1.0f, 0.0f, 0.0f, 1.0f); /* float refraction = thickness*thicknessRefraction.x*refracMultiplier; vec4 sceneCol = texture2DRect(sceneTex, (gl_TexCoord[0].xy * subSample) + (n.xy * refraction)); reflectColor = (1.0f-refBlend)*reflectColor + refBlend*sceneCol; // colorFalloff = vec4(0.5, 0.5, 0.5, 1.0); vec4 attenuatedColor = exp(-thickness*falloffScale*colorFalloff*10.0); //vec3 blendFactor = vec3(1,1,1)+2*thickness*falloffScale*vec3(1,1,1); //blendFactor = min(0.5, blendFactor); //blendFactor = min(blendFactor, vec3(1,1,1)); //blendFactor = max(blendFactor, vec3(0,0,0)); //fluidColor = vec4(1.0f, 1.0f, 1.0f, 1.0f); //fluidColor = vec4(28/255.0, 69/255.0, 89/255.0, 0.0); //fluidColor = vec4(17/255.0, 52/255.0, 71/255.0, 0.0); sceneCol.xyz = lerp(fluidColor, sceneCol.xyz, attenuatedColor); //sceneCol = fluidColor; //sceneCol.xyz = vec3(0.0f,0.0f,0.0f); vec4 finalCol = vec4((1-fresnel)*sceneCol.xyz + reflectColor.xyz*fresnel , 1.0); float shadow = shadowCoef(eyePos); gl_FragColor = vec4(finalCol.xyz*((1.0f - shadowAmbient)*shadow + shadowAmbient), max(0.0f, min(1.0, thicknessAlphaMul*thickness))); // gl_FragColor = finalCol; // gl_FragColor.w = max(0.0f, min(1.0, 3.0f*thickness)); //gl_FragColor = finalCol; // gl_FragColor = sceneCol*attenuatedColor + reflectColor*fresnel + specularColor*specular; // gl_FragDepth = texture2DRect(depthTex, gl_TexCoord[0].xy).x; float fog = clamp(gl_Fog.scale*(gl_Fog.end+eyePos.z), 0.0, 1.0); //float fog = exp(-gl_Fog.density*(eyePos.z*eyePos.z)); gl_FragColor = mix(gl_Fog.color, gl_FragColor, fog); gl_FragDepth = texture2DRect(depthTex, gl_TexCoord[0].xy * colorTexScale).x; */ //gl_FragColor = vec4(1.0f, 0.0f, 0.0f, 1.0f); //return; //gl_FragColor.w = max(0.0, min((thickness)*5.0, 1.0)); //gl_FragColor.w = 1.0; } ); const char *texture2DPS = STRINGIFY( uniform sampler2D tex; \n void main() \n { \n gl_FragColor = texture2D(tex, gl_TexCoord[0].xy); \n } \n ); #if TECHNICAL_MODE const char *particleSmokeUseFOMPS = STRINGIFY( uniform sampler2DArrayShadow stex; uniform float shadowAmbient = 0.3; float shadowCoef() { const int index = 0; // transform this fragment's position from view space to scaled light clip space // such that the xy coordinates are in [0;1] // note there is no need to divide by w for othogonal light sources vec4 shadow_coord = gl_TextureMatrix[index]*vec4(gl_TexCoord[2].xyz, 1); shadow_coord.w = shadow_coord.z; // tell glsl in which layer to do the look up shadow_coord.z = float(index); // Gaussian 3x3 filter return shadow2DArray(stex, shadow_coord).x; } uniform float ispotMaxDist; uniform vec3 spotOriginEye; uniform sampler2D spot_a0123; uniform sampler2D spot_b123; uniform sampler2D smokeTex; const float PI = 3.1415926535897932384626433832795; const vec3 _2pik = vec3(2.0) * vec3(PI,2.0*PI,3.0*PI); const vec3 factor_a = vec3(2.0*PI)*vec3(1.0,2.0,3.0); const vec3 factor_b = vec3(2.0*PI)*vec3(1.0,2.0,3.0); const vec3 value_1 = vec3(1.0); uniform mat4 eyeToSpotMatrix; void main() { //gl_FragColor = gl_Color; //return; // calculate eye-space normal from texture coordinates vec3 N; N.xy = gl_TexCoord[0].xy*vec2(2.0, -2.0) + vec2(-1.0, 1.0); float mag = dot(N.xy, N.xy); if (mag > 1.0) discard; // kill pixels outside circle float falloff = pow(1.0-mag,1.0);//exp(-mag); //falloff = 1.0f; float shadowC = shadowCoef(); vec3 shadowColor = vec3(0.4, 0.4, 0.4)*0.8; // Also FOM // vec4 projectionCoordinate = eyeToSpotMatrix*vec4(gl_TexCoord[2].xyz, 1.0f); vec4 projectionCoordinate = eyeToSpotMatrix*vec4(gl_TexCoord[2].xyz, 1.0f); //gl_FragColor.xyz = gl_TexCoord[3].xyz*0.25f; //gl_FragColor.xyz = projectionCoordinate.xyz / projectionCoordinate.w; //gl_FragColor.w = 1.0f; //read Fourier series coefficients for color extinction on RGB vec4 sR_a0123 = texture2DProj(spot_a0123,projectionCoordinate); vec3 sR_b123 = texture2DProj(spot_b123,projectionCoordinate).rgb; //gl_FragColor.xyz = sR_a0123.xyz; //gl_FragColor.w = 1.0f; //return; //compute absolute and normalized distance (in spot depth range) float distance2spotCenter = length(spotOriginEye-gl_TexCoord[2].xyz);//distance from spot origin to surfel in world space float d = distance2spotCenter*ispotMaxDist; //compute some value to recover the extinction coefficient using the Fourier series vec3 sin_a123 = sin(factor_a*vec3(d)); vec3 cos_b123 = value_1-cos(factor_b*vec3(d)); //compute the extinction coefficients using Fourier float att = (sR_a0123.r*d/2.0) + dot(sin_a123*(sR_a0123.gba/_2pik) ,value_1) + dot(cos_b123*(sR_b123.rgb/_2pik) ,value_1); att = max(0.0f, att); att = min(1.0f, att); shadowC *= (1.0f-att); float inS = shadowC; shadowC = (shadowAmbient + (1.0f -shadowAmbient)*shadowC); //.... if (gl_TexCoord[0].z > 1) shadowC = 1; vec4 texColor = texture2D(smokeTex, gl_TexCoord[0].xy*0.25+gl_TexCoord[1].xy); gl_FragColor.xyz = (texColor.x)*gl_Color.xyz*(shadowColor + (vec3(1.0f,1,1) -shadowColor)*shadowC);//*falloff; gl_FragColor.w = gl_Color.w*texColor.r; //float fog = clamp(gl_Fog.scale*(gl_Fog.end+gl_TexCoord[2].z), 0.0, 1.0); //float fog = exp(-gl_Fog.density*(gl_TexCoord[0].z*gl_TexCoord[0].z)); //gl_FragColor = mix(gl_Fog.color, gl_FragColor, fog); gl_FragColor.xyz *= 1.6f; gl_FragColor.w *= max(min(falloff,1.0f),0.0f) * max(min(gl_TexCoord[0].w,1.0f),0.0f); //gl_FragColor.w = 1; //gl_FragColor.xyz = vec3(shadowC, shadowC, shadowC); // gl_FragColor.w = 0.2f; //gl_FragColor.w = falloff * gl_TexCoord[0].w; //gl_FragColor.xyz = sR_a0123.xyz; gl_FragColor.xyz *= ((gl_TexCoord[0].z)+inS*0.3)*0.7; //gl_FragDepth = gl_FragCoord.z - (1-mag)*0.00002; } ); #else const char *particleSmokeUseFOMPS = STRINGIFY( uniform sampler2DArrayShadow stex; uniform float shadowAmbient = 0.3; float shadowCoef() { const int index = 0; /* int index = 3; // find the appropriate depth map to look up in based on the depth of this fragment if(gl_FragCoord.z < far_d.x) index = 0; else if(gl_FragCoord.z < far_d.y) index = 1; else if(gl_FragCoord.z < far_d.z) index = 2; */ // transform this fragment's position from view space to scaled light clip space // such that the xy coordinates are in [0;1] // note there is no need to divide by w for othogonal light sources vec4 shadow_coord = gl_TextureMatrix[index]*vec4(gl_TexCoord[2].xyz, 1); shadow_coord.w = shadow_coord.z; // tell glsl in which layer to do the look up shadow_coord.z = float(index); // Gaussian 3x3 filter return shadow2DArray(stex, shadow_coord).x; } uniform float ispotMaxDist; uniform vec3 spotOriginEye; uniform sampler2D spot_a0123; uniform sampler2D spot_b123; uniform sampler2D smokeTex; const float PI = 3.1415926535897932384626433832795; const vec3 _2pik = vec3(2.0) * vec3(PI,2.0*PI,3.0*PI); const vec3 factor_a = vec3(2.0*PI)*vec3(1.0,2.0,3.0); const vec3 factor_b = vec3(2.0*PI)*vec3(1.0,2.0,3.0); const vec3 value_1 = vec3(1.0); uniform mat4 eyeToSpotMatrix; void main() { //gl_FragColor = gl_Color; //return; /* gl_FragColor = texture2D(smokeTex, gl_TexCoord[0].xy); gl_FragColor.w = gl_FragColor.r; gl_FragColor.xyz = vec3(1,1,1); return; */ // gl_FragColor = vec4(1,0,0,1); // return; // calculate eye-space normal from texture coordinates vec3 N; N.xy = gl_TexCoord[0].xy*vec2(2.0, -2.0) + vec2(-1.0, 1.0); float mag = dot(N.xy, N.xy); if (mag > 1.0) discard; // kill pixels outside circle float falloff = pow(1.0-mag,1.0);//exp(-mag); //falloff = 1.0f; float shadowC = shadowCoef(); vec3 shadowColor = vec3(0.4, 0.4, 0.9)*0.8; // Also FOM // vec4 projectionCoordinate = eyeToSpotMatrix*vec4(gl_TexCoord[2].xyz, 1.0f); vec4 projectionCoordinate = eyeToSpotMatrix*vec4(gl_TexCoord[2].xyz, 1.0f); //gl_FragColor.xyz = gl_TexCoord[3].xyz*0.25f; //gl_FragColor.xyz = projectionCoordinate.xyz / projectionCoordinate.w; //gl_FragColor.w = 1.0f; //read Fourier series coefficients for color extinction on RGB vec4 sR_a0123 = texture2DProj(spot_a0123,projectionCoordinate); vec3 sR_b123 = texture2DProj(spot_b123,projectionCoordinate).rgb; //gl_FragColor.xyz = sR_a0123.xyz; //gl_FragColor.w = 1.0f; //return; //compute absolute and normalized distance (in spot depth range) float distance2spotCenter = length(spotOriginEye-gl_TexCoord[2].xyz);//distance from spot origin to surfel in world space float d = distance2spotCenter*ispotMaxDist; //compute some value to recover the extinction coefficient using the Fourier series vec3 sin_a123 = sin(factor_a*vec3(d)); vec3 cos_b123 = value_1-cos(factor_b*vec3(d)); //compute the extinction coefficients using Fourier float att = (sR_a0123.r*d/2.0) + dot(sin_a123*(sR_a0123.gba/_2pik) ,value_1) + dot(cos_b123*(sR_b123.rgb/_2pik) ,value_1); att = max(0.0f, att); att = min(1.0f, att); shadowC *= (1.0f-att); float inS = shadowC; shadowC = (shadowAmbient + (1.0f -shadowAmbient)*shadowC); //.... if (gl_TexCoord[0].z > 1) shadowC = 1; vec4 texColor = texture2D(smokeTex, gl_TexCoord[0].xy*0.25+gl_TexCoord[1].xy); gl_FragColor.xyz = (texColor.x)*gl_Color.xyz*(shadowColor + (vec3(1.0f,1,1) -shadowColor)*shadowC);//*falloff; gl_FragColor.w = gl_Color.w*texColor.r; //float fog = clamp(gl_Fog.scale*(gl_Fog.end+gl_TexCoord[2].z), 0.0, 1.0); //float fog = exp(-gl_Fog.density*(gl_TexCoord[0].z*gl_TexCoord[0].z)); //gl_FragColor = mix(gl_Fog.color, gl_FragColor, fog); gl_FragColor.xyz *= 1.6f; gl_FragColor.w *= max(min(falloff,1.0f),0.0f) * max(min(gl_TexCoord[0].w,1.0f),0.0f); //gl_FragColor.w = 1; //gl_FragColor.xyz = vec3(shadowC, shadowC, shadowC); // gl_FragColor.w = 0.2f; //gl_FragColor.w = falloff * gl_TexCoord[0].w; //gl_FragColor.xyz = sR_a0123.xyz; gl_FragColor.xyz *= ((gl_TexCoord[0].z)+inS*0.3)*0.7; //gl_FragDepth = gl_FragCoord.z - (1-mag)*0.00002; } ); #endif // sky box const char *skyboxVS = STRINGIFY( uniform vec3 projectionCenter = vec3(0,0,0); void main() { gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; // gl_Position = gl_Vertex; // gl_Position = gl_ProjectionMatrix * gl_Vertex; gl_TexCoord[0].xyz = (gl_Vertex.xyz + projectionCenter); // gl_TexCoord[0].xyz = (mat3) gl_ModelViewMatrix * gl_Vertex.xyz; gl_FrontColor = gl_Color; } ); const char *skyboxPS = STRINGIFY( uniform samplerCube cubemap; void main() { gl_FragColor = textureCube(cubemap, gl_TexCoord[0].xyz * vec3(1, 1, 1)); gl_FragColor.x = 1.5 * pow(gl_FragColor.x, 2.2); gl_FragColor.y = 1.5 * pow(gl_FragColor.y, 2.2); gl_FragColor.z = 1.5 * pow(gl_FragColor.z, 2.2); gl_FragColor.w = 1.5 * pow(gl_FragColor.w, 2.2); } );