/* * Copyright 1993-2015 NVIDIA Corporation. All rights reserved. * * Please refer to the NVIDIA end user license agreement (EULA) associated * with this source code for terms and conditions that govern your use of * this software. Any use, reproduction, disclosure, or distribution of * this software and related documentation outside the terms of the EULA * is strictly prohibited. * */ // GLSL shaders for particle rendering #define STRINGIFY(A) #A // particle vertex shader const char *particleVS = STRINGIFY( uniform float pointRadius; // point size in world space \n uniform float pointScale; // scale to calculate size in pixels \n uniform vec4 eyePos; \n void main() \n { \n vec4 wpos = vec4(gl_Vertex.xyz, 1.0); \n gl_Position = gl_ModelViewProjectionMatrix *wpos; \n // calculate window-space point size \n vec4 eyeSpacePos = gl_ModelViewMatrix *wpos; \n float dist = length(eyeSpacePos.xyz); \n gl_PointSize = pointRadius * (pointScale / dist); \n gl_TexCoord[0] = gl_MultiTexCoord0; // sprite texcoord \n gl_TexCoord[1] = eyeSpacePos; \n gl_FrontColor = gl_Color; \n } \n ); // motion blur shaders const char *mblurVS = STRINGIFY( uniform float timestep; \n void main() \n { \n vec3 pos = gl_Vertex.xyz; \n vec3 vel = gl_MultiTexCoord0.xyz; \n vec3 pos2 = (pos - vel*timestep).xyz; \n // previous position \n gl_Position = gl_ModelViewMatrix * vec4(pos, 1.0); \n // eye space gl_TexCoord[0] = gl_ModelViewMatrix * vec4(pos2, 1.0); \n // aging \n float lifetime = gl_MultiTexCoord0.w; \n float age = gl_Vertex.w; \n float phase = (lifetime > 0.0) ? (age / lifetime) : 1.0; \n // [0, 1] gl_TexCoord[1].x = phase; \n float fade = 1.0 - phase; \n // float fade = 1.0; \n // gl_FrontColor = gl_Color; \n gl_FrontColor = vec4(gl_Color.xyz, gl_Color.w*fade); \n } \n ); // motion blur geometry shader // - outputs stretched quad between previous and current positions const char *mblurGS = "#version 120\n" "#extension GL_EXT_geometry_shader4 : enable\n" STRINGIFY( uniform float pointRadius; // point size in world space \n void main() \n { \n // aging \n float phase = gl_TexCoordIn[0][1].x; \n float radius = pointRadius; \n // eye space \n vec3 pos = gl_PositionIn[0].xyz; \n vec3 pos2 = gl_TexCoordIn[0][0].xyz; \n vec3 motion = pos - pos2; \n vec3 dir = normalize(motion); \n float len = length(motion); \n vec3 x = dir *radius; \n vec3 view = normalize(-pos); \n vec3 y = normalize(cross(dir, view)) * radius; \n float facing = dot(view, dir); \n // check for very small motion to avoid jitter \n float threshold = 0.01; \n if ((len < threshold) || (facing > 0.95) || (facing < -0.95)) { \n pos2 = pos; \n x = vec3(radius, 0.0, 0.0); \n y = vec3(0.0, -radius, 0.0); \n } \n // output quad \n gl_FrontColor = gl_FrontColorIn[0]; \n gl_TexCoord[0] = vec4(0, 0, 0, phase); \n gl_TexCoord[1] = gl_PositionIn[0]; \n gl_Position = gl_ProjectionMatrix * vec4(pos + x + y, 1); \n EmitVertex(); \n gl_TexCoord[0] = vec4(0, 1, 0, phase); \n gl_TexCoord[1] = gl_PositionIn[0]; \n gl_Position = gl_ProjectionMatrix * vec4(pos + x - y, 1); \n EmitVertex(); \n gl_TexCoord[0] = vec4(1, 0, 0, phase); \n gl_TexCoord[1] = gl_PositionIn[0]; \n gl_Position = gl_ProjectionMatrix * vec4(pos2 - x + y, 1); \n EmitVertex(); \n gl_TexCoord[0] = vec4(1, 1, 0, phase); \n gl_TexCoord[1] = gl_PositionIn[0]; \n gl_Position = gl_ProjectionMatrix * vec4(pos2 - x - y, 1); \n EmitVertex(); \n } \n ); const char *simplePS = STRINGIFY( void main() \n { \n gl_FragColor = gl_Color; \n } \n ); // render particle without shadows const char *particlePS = STRINGIFY( uniform float pointRadius; \n void main() \n { \n // calculate eye-space sphere normal from texture coordinates \n vec3 N; \n N.xy = gl_TexCoord[0].xy*vec2(2.0, -2.0) + vec2(-1.0, 1.0); \n float r2 = dot(N.xy, N.xy); \n if (r2 > 1.0) discard; // kill pixels outside circle \n N.z = sqrt(1.0-r2); \n // float alpha = saturate(1.0 - r2); \n float alpha = clamp((1.0 - r2), 0.0, 1.0); \n alpha *= gl_Color.w; \n gl_FragColor = vec4(gl_Color.xyz * alpha, alpha); \n } \n ); // render particle including shadows const char *particleShadowPS = STRINGIFY( uniform float pointRadius; \n uniform sampler2D shadowTex; \n uniform sampler2D depthTex; \n void main() \n { \n // calculate eye-space sphere normal from texture coordinates \n vec3 N; \n N.xy = gl_TexCoord[0].xy*vec2(2.0, -2.0) + vec2(-1.0, 1.0); \n float r2 = dot(N.xy, N.xy); \n if (r2 > 1.0) discard; \n // kill pixels outside circle N.z = sqrt(1.0-r2); \n vec4 eyeSpacePos = gl_TexCoord[1]; \n vec4 eyeSpaceSpherePos = vec4(eyeSpacePos.xyz + N*pointRadius, 1.0); \n // point on sphere vec4 shadowPos = gl_TextureMatrix[0] * eyeSpaceSpherePos; \n vec3 shadow = vec3(1.0) - texture2DProj(shadowTex, shadowPos.xyw).xyz; \n // float alpha = saturate(1.0 - r2); \n float alpha = clamp((1.0 - r2), 0.0, 1.0); \n alpha *= gl_Color.w; \n gl_FragColor = vec4(gl_Color.xyz *shadow * alpha, alpha); \n // premul alpha } ); // render particle as lit sphere const char *particleSpherePS = STRINGIFY( uniform float pointRadius; \n uniform vec3 lightDir = vec3(0.577, 0.577, 0.577); \n void main() \n { \n // calculate eye-space sphere normal from texture coordinates \n vec3 N; \n N.xy = gl_TexCoord[0].xy*vec2(2.0, -2.0) + vec2(-1.0, 1.0); \n float r2 = dot(N.xy, N.xy); \n if (r2 > 1.0) discard; // kill pixels outside circle \n N.z = sqrt(1.0-r2); \n // calculate depth \n vec4 eyeSpacePos = vec4(gl_TexCoord[1].xyz + N*pointRadius, 1.0); // position of this pixel on sphere in eye space \n vec4 clipSpacePos = gl_ProjectionMatrix *eyeSpacePos; \n gl_FragDepth = (clipSpacePos.z / clipSpacePos.w)*0.5+0.5; \n float diffuse = max(0.0, dot(N, lightDir)); \n gl_FragColor = diffuse *gl_Color; \n } \n ); const char *passThruVS = STRINGIFY( void main() \n { \n gl_Position = gl_Vertex; \n gl_TexCoord[0] = gl_MultiTexCoord0; \n gl_FrontColor = gl_Color; \n } \n ); const char *texture2DPS = STRINGIFY( uniform sampler2D tex; \n void main() \n { \n gl_FragColor = texture2D(tex, gl_TexCoord[0].xy); \n } \n ); // 4 tap 3x3 gaussian blur const char *blurPS = STRINGIFY( uniform sampler2D tex; \n uniform vec2 texelSize; \n uniform float blurRadius; \n void main() \n { \n vec4 c; \n c = texture2D(tex, gl_TexCoord[0].xy + vec2(-0.5, -0.5)*texelSize*blurRadius); \n c += texture2D(tex, gl_TexCoord[0].xy + vec2(0.5, -0.5)*texelSize*blurRadius); \n c += texture2D(tex, gl_TexCoord[0].xy + vec2(0.5, 0.5)*texelSize*blurRadius); \n c += texture2D(tex, gl_TexCoord[0].xy + vec2(-0.5, 0.5)*texelSize*blurRadius); \n c *= 0.25; \n gl_FragColor = c; \n } \n ); // floor shader const char *floorVS = STRINGIFY( varying vec4 vertexPosEye; // vertex position in eye space \n varying vec3 normalEye; \n void main() \n { \n gl_Position = gl_ModelViewProjectionMatrix *gl_Vertex; \n gl_TexCoord[0] = gl_MultiTexCoord0; \n vertexPosEye = gl_ModelViewMatrix *gl_Vertex; \n normalEye = gl_NormalMatrix *gl_Normal; \n gl_FrontColor = gl_Color; \n } \n ); const char *floorPS = STRINGIFY( uniform vec3 lightPosEye; // light position in eye space \n uniform vec3 lightColor; \n uniform sampler2D tex; \n uniform sampler2D shadowTex; \n varying vec4 vertexPosEye; // vertex position in eye space \n varying vec3 normalEye; \n void main() \n { \n vec4 shadowPos = gl_TextureMatrix[0] * vertexPosEye; \n vec4 colorMap = texture2D(tex, gl_TexCoord[0].xy); \n vec3 N = normalize(normalEye); \n vec3 L = normalize(lightPosEye - vertexPosEye.xyz); \n float diffuse = max(0.0, dot(N, L)); \n vec3 shadow = vec3(1.0) - texture2DProj(shadowTex, shadowPos.xyw).xyz; \n if (shadowPos.w < 0.0) shadow = lightColor; \n // avoid back projections gl_FragColor = vec4(gl_Color.xyz *colorMap.xyz *diffuse * shadow, 1.0); \n } \n );