Skip to content

Instantly share code, notes, and snippets.

@meshula
Created December 23, 2021 02:38
Show Gist options
  • Save meshula/335b39960e9a0af9f4eab0c2638e84ec to your computer and use it in GitHub Desktop.
Save meshula/335b39960e9a0af9f4eab0c2638e84ec to your computer and use it in GitHub Desktop.
pipeline program
--- 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