Created
December 23, 2021 02:38
-
-
Save meshula/335b39960e9a0af9f4eab0c2638e84ec to your computer and use it in GitHub Desktop.
pipeline program
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| --- labfx version 1.0 | |
| name: Particles | |
| version: 1.0 | |
| ------------------------------------------------------------------------------- | |
| buffer: gbuffer | |
| has depth: yes | |
| textures: | |
| [ diffuse, u8x4, scale: 1.0 | |
| position, f32x4, scale: 1.0 | |
| normal, f16x4, scale: 1.0 | |
| color, f16x4, scale: 1.0 ] | |
| ------------------------------------------------------------------------------- | |
| pass: clear gbuffer | |
| draw: no | |
| clear depth: yes | |
| clear outputs: yes | |
| outputs: gbuffer [diffuse, position, normal] | |
| pass: geometry | |
| draw: opaque geometry | |
| clear depth: no | |
| depth test: less | |
| write depth: yes | |
| use shader: mesh | |
| outputs: gbuffer [diffuse, position, normal] | |
| pass: sky | |
| draw: quad | |
| clear depth: no | |
| depth test: equal | |
| write depth: no | |
| use shader: sky | |
| outputs: gbuffer [color] | |
| pass: illuminate | |
| draw: quad | |
| clear depth: no | |
| write depth: no | |
| depth test: never | |
| use shader: illuminate | |
| inputs: [gbuffer.diffuse, gbuffer.position, gbuffer.normal] | |
| outputs: gbuffer [ color ] | |
| pass: particles | |
| draw: plug effekseer | |
| clear depth: no | |
| write depth: no | |
| depth test: never | |
| outputs: gbuffer [color] | |
| pass: fxaa | |
| draw: quad | |
| clear depth: no | |
| write depth: no | |
| depth test: never | |
| inputs: [gbuffer.color] | |
| outputs: visible -- visible is special: the default found frame buffer | |
| use shader: fxaa | |
| -------------------------------------------------------------------------------- | |
| shader: sky | |
| uniforms: | |
| [ u_skyMatrix: mat4 <- auto-sky-matrix, | |
| skyCube: samplerCube ] | |
| varying: | |
| [ eyeDirection: vec3 ] | |
| vsh: | |
| attributes: | |
| [ a_position: vec3 <- position ] | |
| source: | |
| ```glsl | |
| void main() { | |
| vec4 pos = vec4(a_position, 1.0); | |
| var.eyeDirection = (u_skyMatrix * pos).xyz; | |
| pos.z = 1.0; // maximum depth value as sentinel to enable writing | |
| gl_Position = pos; | |
| } | |
| ``` | |
| fsh: | |
| source: ```glsl | |
| // sky-fsh.glsl | |
| // Sky shader adapted from EtherealEngine, license BSD | |
| float atmospheric_depth(vec3 pos, vec3 dir) | |
| { | |
| float a = dot(dir, dir); | |
| float b = 2.0f * dot(dir, pos); | |
| float c = dot(pos, pos) - 1.0f; | |
| float det = b * b - 4.0f * a * c; | |
| float detSqrt = sqrt(det); | |
| float q = (-b - detSqrt) / 2.0f; | |
| float t1 = c / q; | |
| return t1; | |
| } | |
| float phase(float alpha, float g) | |
| { | |
| float a = 3.0f * (1.0f - g * g); | |
| float b = 2.0f * (2.0f + g * g); | |
| float c = 1.0f + alpha * alpha; | |
| float d = pow(1.0f + g * g - 2.0f * g * alpha, 1.5f); | |
| return (a / b) * (c / d); | |
| } | |
| float horizon_extinction(vec3 pos, vec3 dir, float radius) | |
| { | |
| float u = dot(dir, -pos); | |
| if(u < 0.0f) | |
| { | |
| return 1.0f; | |
| } | |
| vec3 near = pos + u * dir; | |
| if(length(near) < radius + 0.001f) | |
| { | |
| return 0.0f; | |
| } | |
| else | |
| { | |
| vec3 v2 = normalize(near) * radius - pos; | |
| float diff = acos(dot(normalize(v2), dir)); | |
| return smoothstep(0.0f, 1.0f, pow(diff * 2.0f, 3.0f)); | |
| } | |
| } | |
| vec3 absorb(vec3 kr, float dist, vec3 color, float factor) | |
| { | |
| float f = factor / dist; | |
| return color - color * pow(kr, vec3(f, f, f)); | |
| } | |
| float saturate(float a) | |
| { | |
| return clamp(a, 0, 1); | |
| } | |
| vec4 saturate(vec4 a) | |
| { | |
| a.x = saturate(a.x); | |
| a.y = saturate(a.y); | |
| a.z = saturate(a.z); | |
| a.w = saturate(a.w); | |
| return a; | |
| } | |
| vec4 sky_color_main() | |
| { | |
| const int u_step_count = 2; | |
| const vec3 u_kr = vec3(0.18867780436772762f, 0.4978442963618773f, 0.6616065586417131f); | |
| const vec3 u_ground_color = vec3(0.63f, 0.6f, 0.57f); | |
| const float u_spot_brightness = 10.0f; | |
| const float u_scatter_strength = 0.028; | |
| const float u_surface_height = 0.99f; // < 1 | |
| const float u_intensity = 1.0f; | |
| const float u_rayleigh_brightness = 3.3f; | |
| const float u_rayleigh_collection_power = 0.81f; | |
| const float u_rayleigh_strength = 0.139f; | |
| const float u_mie_brightness = 0.1f; | |
| const float u_mie_strength = 0.264f; | |
| const float u_mie_collection_power = 0.39f; | |
| const float u_mie_distribution = 0.63f; | |
| vec3 u_light_direction = normalize(vec3(0, -0.5, 0.5)); // should be passed in | |
| vec3 eye_dir = normalize(var.eyeDirection.xyz); | |
| vec3 eye_pos = vec3(0.0f, u_surface_height, 0.0f); | |
| float alpha = clamp(dot(eye_dir, -u_light_direction.xyz), 0, 1); | |
| float rayleigh_factor = phase(alpha, -0.01) * u_rayleigh_brightness; | |
| float mie_factor = phase(alpha, u_mie_distribution) * u_mie_brightness; | |
| float spot = smoothstep(0.0f, 15.0f, phase(alpha, 0.9995f)) * u_spot_brightness; | |
| float eye_depth = atmospheric_depth(eye_pos, eye_dir); | |
| float step_length = eye_depth / float(u_step_count); | |
| float eye_extinction = horizon_extinction(eye_pos, eye_dir, u_surface_height - 0.05f); | |
| vec3 rayleigh_collected = vec3(0.0f, 0.0f, 0.0f); | |
| vec3 mie_collected = vec3(0.0f, 0.0f, 0.0f); | |
| for(int i = 0; i < u_step_count; ++i) | |
| { | |
| float sample_distance = step_length * float(i); | |
| vec3 pos = eye_pos + eye_dir * sample_distance; | |
| float extinction = horizon_extinction(pos, -u_light_direction.xyz, u_surface_height - 0.35f); | |
| float sample_depth = atmospheric_depth(pos, -u_light_direction.xyz); | |
| vec3 influx = absorb(u_kr, sample_depth, vec3(u_intensity, u_intensity, u_intensity), u_scatter_strength) * extinction; | |
| rayleigh_collected += absorb(u_kr, sample_distance, u_kr * influx, u_rayleigh_strength); | |
| mie_collected += absorb(u_kr, sample_distance, influx, u_mie_strength); | |
| } | |
| rayleigh_collected = (rayleigh_collected * eye_extinction * pow(eye_depth, u_rayleigh_collection_power)) / float(u_step_count); | |
| mie_collected = (mie_collected * eye_extinction * pow(eye_depth, u_mie_collection_power)) / float(u_step_count); | |
| vec3 color = vec3(spot * mie_collected + mie_factor * mie_collected + rayleigh_factor * rayleigh_collected); | |
| float light_angle = dot(-normalize(-u_light_direction.xyz), eye_pos); | |
| vec3 ground_color = u_ground_color * (saturate(-light_angle)) * 0.1f; | |
| color = mix(color, ground_color, saturate(-eye_dir.y/0.06f + 0.4f)); | |
| alpha = 1.0;// dot( color, vec3( 0.2125, 0.7154, 0.0721 ) ); | |
| return vec4(color.rgb, alpha); | |
| } | |
| vec4 sample_skycube_main() | |
| { | |
| return vec4(texture(skyCube, var.eyeDirection).xyz, 1.0); | |
| } | |
| vec4 direction_color_main() | |
| { | |
| return vec4(0.5 * clamp(1.0 - var.eyeDirection.y, 0, 1), 0.5 * clamp(var.eyeDirection.y, 0, 1), 0, 1); | |
| } | |
| void main() { | |
| o_color_texture = sky_color_main(); | |
| } | |
| ``` | |
| -------------------------------------------------------------------------------- | |
| shader: illuminate | |
| uniforms: [ u_color_texture: sampler2d, | |
| u_normal_texture: sampler2d, | |
| u_diffuse_texture: sampler2d, | |
| u_resolution: vec2 <- auto-resolution ] | |
| varying: [ texCoord: vec2 ] | |
| vsh: | |
| attributes: | |
| [ a_position: vec3 <- position, | |
| a_uv: vec2 <- texcoord ] | |
| source: ```glsl | |
| void main() | |
| { | |
| var.texCoord = a_uv; | |
| gl_Position = vec4(a_position, 1.0); | |
| } | |
| ``` | |
| fsh: | |
| source: ```glsl | |
| void main() | |
| { | |
| vec3 normal = texture(u_normal_texture, var.texCoord).xyz; | |
| float i = dot(normal, normal); | |
| if (i < 0.0001) { | |
| discard; | |
| } | |
| else | |
| { | |
| vec3 light = normalize(vec3(0.1, 0.4, 0.2)); | |
| vec3 diffuse = texture(u_diffuse_texture, var.texCoord).xyz; | |
| i = dot(normal, light); | |
| o_color_texture = vec4(diffuse, 1) * i; | |
| } | |
| } | |
| ``` | |
| -------------------------------------------------------------------------------- | |
| shader: fxaa | |
| uniforms: [ u_color_texture: sampler2d, | |
| u_resolution: vec2 <- auto-resolution ] | |
| varying: [ texCoord: vec2 ] | |
| vsh: | |
| attributes: | |
| [ a_position: vec3 <- position, | |
| a_uv: vec2 <- texcoord ] | |
| source: ```glsl | |
| void main() | |
| { | |
| var.texCoord = a_uv; | |
| gl_Position = vec4(a_position, 1.0); | |
| } | |
| ``` | |
| fsh: | |
| source: ```glsl | |
| #define FXAA_REDUCE_MIN (1.0/128.0) | |
| #define FXAA_REDUCE_MUL (1.0/8.0) | |
| #define FXAA_SPAN_MAX 8.0 | |
| out vec4 fragColor; | |
| void main() { | |
| vec2 res = 1. / u_resolution; | |
| vec3 rgbNW = texture( u_color_texture, ( var.texCoord.xy + vec2( -1.0, -1.0 ) * res ) ).xyz; | |
| vec3 rgbNE = texture( u_color_texture, ( var.texCoord.xy + vec2( 1.0, -1.0 ) * res ) ).xyz; | |
| vec3 rgbSW = texture( u_color_texture, ( var.texCoord.xy + vec2( -1.0, 1.0 ) * res ) ).xyz; | |
| vec3 rgbSE = texture( u_color_texture, ( var.texCoord.xy + vec2( 1.0, 1.0 ) * res ) ).xyz; | |
| vec4 rgbaM = texture( u_color_texture, var.texCoord.xy * res ); | |
| vec3 rgbM = rgbaM.xyz; | |
| vec3 luma = vec3( 0.299, 0.587, 0.114 ); | |
| float lumaNW = dot( rgbNW, luma ); | |
| float lumaNE = dot( rgbNE, luma ); | |
| float lumaSW = dot( rgbSW, luma ); | |
| float lumaSE = dot( rgbSE, luma ); | |
| float lumaM = dot( rgbM, luma ); | |
| float lumaMin = min( lumaM, min( min( lumaNW, lumaNE ), min( lumaSW, lumaSE ) ) ); | |
| float lumaMax = max( lumaM, max( max( lumaNW, lumaNE) , max( lumaSW, lumaSE ) ) ); | |
| vec2 dir; | |
| dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); | |
| dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); | |
| float dirReduce = max( ( lumaNW + lumaNE + lumaSW + lumaSE ) * ( 0.25 * FXAA_REDUCE_MUL ), FXAA_REDUCE_MIN ); | |
| float rcpDirMin = 1.0 / ( min( abs( dir.x ), abs( dir.y ) ) + dirReduce ); | |
| dir = min( vec2( FXAA_SPAN_MAX, FXAA_SPAN_MAX), | |
| max( vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), | |
| dir * rcpDirMin)) * res; | |
| vec4 rgbA = (1.0/2.0) * (texture(u_color_texture, var.texCoord.xy + dir * (1.0/3.0 - 0.5)) + | |
| texture(u_color_texture, var.texCoord.xy + dir * (2.0/3.0 - 0.5))); | |
| vec4 rgbB = rgbA * (1.0/2.0) + (1.0/4.0) * (texture(u_color_texture, var.texCoord.xy + dir * (0.0/3.0 - 0.5)) + | |
| texture(u_color_texture, var.texCoord.xy + dir * (3.0/3.0 - 0.5))); | |
| float lumaB = dot(rgbB, vec4(luma, 0.0)); | |
| if ( ( lumaB < lumaMin ) || ( lumaB > lumaMax ) ) { | |
| fragColor = rgbA; | |
| } else { | |
| fragColor = rgbB; | |
| } | |
| fragColor = vec4(pow(texture( u_color_texture, var.texCoord ).xyz, vec3(1.0/2.2)), 1. ); | |
| } | |
| ``` |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment