commit dc6d5257751647a4349c4cc0aaac1f9302635253
parent 794cff3d788f649925f1885480081d6c089b42bf
Author: Michael Savage <mikejsavage@gmail.com>
Date: Sat, 24 Nov 2018 13:40:33 +0200
Direction indicators and semi functional outlines through walls
Diffstat:
9 files changed, 323 insertions(+), 91 deletions(-)
diff --git a/bsp.cc b/bsp.cc
@@ -7,6 +7,7 @@
#include "gl.h"
#include "renderer.h"
#include "shaders.h"
+#include "obj.h"
#include "immediate.h"
#include "bsp.h"
#include "bsp_renderer.h"
@@ -16,7 +17,10 @@ static bool fix = false;
static v3 fix_start;
static v3 fix_end;
-static FB gbuffer;
+static FB world_depth_and_normals;
+static FB model_depth;
+static FB model_depth_outline;
+static Mesh tree_mesh;
static const float EPSILON = 1.0 / 32.0;
@@ -290,6 +294,28 @@ BSP_Leaf & BSP::position_to_leaf( v3 pos ) const {
return leaves[ -( node_idx + 1 ) ];
}
+static v2 screen_pos( const m4 & P, const m4 & V, v3 camera_pos, v3 target, v2 clamp, float near_plane_depth ) {
+ v4 clip = P * V * v4( target, 1.0 );
+ if( abs( clip.z ) < near_plane_depth )
+ return v2( 0, 0 );
+
+ v2 res = clip.xy() / clip.z;
+
+ v3 forward = -V.row2().xyz();
+ float d = dot( target - camera_pos, forward );
+ if( d < 0 )
+ res = -res;
+
+ if( abs( res.x ) > clamp.x || abs( res.y ) > clamp.y || d < 0 ) {
+ float rx = clamp.x / abs( res.x );
+ float ry = clamp.y / abs( res.y );
+
+ res *= min( rx, ry );
+ }
+
+ return res;
+}
+
GAME_INIT( game_init ) {
bsp_init( &game->bsp, "assets/acidwdm2.bsp" );
@@ -310,9 +336,9 @@ GAME_INIT( game_init ) {
FramebufferConfig fb_config;
- texture_config.format = TEXFMT_RGB_U8;
- fb_config.textures[ OUTPUT_ALBEDO ].config = texture_config;
- fb_config.textures[ OUTPUT_ALBEDO ].attachment = FB_COLOUR;
+ // texture_config.format = TEXFMT_RGB_U8;
+ // fb_config.textures[ OUTPUT_ALBEDO ].config = texture_config;
+ // fb_config.textures[ OUTPUT_ALBEDO ].attachment = FB_COLOUR;
texture_config.format = TEXFMT_RGB_HALF;
fb_config.textures[ OUTPUT_NORMAL ].config = texture_config;
@@ -322,8 +348,27 @@ GAME_INIT( game_init ) {
fb_config.textures[ OUTPUT_DEPTH ].config = texture_config;
fb_config.textures[ OUTPUT_DEPTH ].attachment = FB_DEPTH;
- gbuffer = renderer_new_fb( fb_config );
+ world_depth_and_normals = renderer_new_fb( fb_config );
+ }
+
+ {
+ v2u32 window_size = get_window_size();
+
+ TextureConfig texture_config;
+ texture_config.width = window_size.x;
+ texture_config.height = window_size.y;
+
+ FramebufferConfig fb_config;
+
+ texture_config.format = TEXFMT_DEPTH;
+ fb_config.textures[ OUTPUT_DEPTH ].config = texture_config;
+ fb_config.textures[ OUTPUT_DEPTH ].attachment = FB_DEPTH;
+
+ model_depth = renderer_new_fb( fb_config );
+ model_depth_outline = renderer_new_fb( fb_config );
}
+
+ tree_mesh = load_obj( "models/trees/PineTree.obj", &mem->persistent_arena );
}
GAME_FRAME( game_frame ) {
@@ -352,57 +397,126 @@ GAME_FRAME( game_frame ) {
game->pos += right * speed * dt * lr;
game->pos.z += dz * speed * dt;
- m4 P = m4_perspective( VERTICAL_FOV, get_aspect_ratio(), NEAR_PLANE_DEPTH, FAR_PLANE_DEPTH );
- m4 V = m4_view( forward, right, up, game->pos );
-
renderer_begin_frame();
- renderer_begin_pass( gbuffer, RENDERER_CLEAR_COLOUR_DO, RENDERER_CLEAR_DEPTH_DO );
+
+ m4 P = m4_perspective( 90, get_aspect_ratio(), NEAR_PLANE_DEPTH, FAR_PLANE_DEPTH );
+ m4 V = m4_view( forward, right, up, game->pos );
UniformBinding view_uniforms = renderer_uniforms( V, P );
+ UniformBinding world_model_uniforms = renderer_uniforms( m4_identity() );
+ UniformBinding tree_model_uniforms = renderer_uniforms( m4_translation( 100, -600, 340 + 5 * sinf( current_time * 10 ) ) * m4_rotz( current_time ) * m4_rotx( deg_to_rad( 90 ) ) * m4_scale( 32 ) );
+ // depth/normals pre pass
{
+ renderer_begin_pass( world_depth_and_normals, RENDERER_CLEAR_COLOUR_DO, RENDERER_CLEAR_DEPTH_DO );
+
RenderState render_state;
render_state.shader = get_shader( SHADER_FLAT_VERTEX_COLOURS_TO_GBUFFER );
render_state.uniforms[ UNIFORMS_VIEW ] = view_uniforms;
+ render_state.uniforms[ UNIFORMS_MODEL ] = world_model_uniforms;
render_state.cull_face = CULLFACE_FRONT;
+
bspr_render( &game->bspr, game->pos, render_state );
- }
- immediate_sphere( v3( 0, 0, 0 ), 128, v4( 1, 1, 0, 1 ) );
+ render_state.cull_face = CULLFACE_BACK;
+
+ // immediate_sphere( v3( 0, 0, 0 ), 128, v4( 1, 1, 0, 1 ) );
+ //
+ // if( input->keys[ KEY_T ] ) {
+ // fix = true;
+ // fix_start = game->pos;
+ // fix_end = fix_start + forward * 1000.0f;
+ // }
+ //
+ // if( fix ) {
+ // Intersection is;
+ // bool hit = game->bspr.bsp->trace_seg( fix_start, fix_end, is );
+ //
+ // if( hit ) {
+ // immediate_sphere( is.pos, 16, v4( 1, 0, 0, 1 ) );
+ // }
+ // }
+ //
+ // immediate_render( render_state );
+ //
+ render_state.uniforms[ UNIFORMS_MODEL ] = tree_model_uniforms;
+ renderer_draw_mesh( tree_mesh, render_state );
- if( input->keys[ KEY_T ] ) {
- fix = true;
- fix_start = game->pos;
- fix_end = fix_start + forward * 1000.0f;
+ renderer_end_pass();
}
- if( fix ) {
- Intersection is;
- bool hit = game->bspr.bsp->trace_seg( fix_start, fix_end, is );
+ // model depth
+ {
+ RenderPassConfig pass;
+ pass.target = model_depth;
+ pass.clear_depth = true;
+ pass.depth = 0.0f;
+ renderer_begin_pass( pass );
- if( hit ) {
- immediate_sphere( is.pos, 16, v4( 1, 0, 0, 1 ) );
- }
+ RenderState render_state;
+ render_state.shader = get_shader( SHADER_FLAT_VERTEX_COLOURS_TO_GBUFFER );
+ render_state.depth_func = DEPTHFUNC_ALWAYS;
+ render_state.uniforms[ UNIFORMS_VIEW ] = view_uniforms;
+ render_state.uniforms[ UNIFORMS_MODEL ] = tree_model_uniforms;
+
+ renderer_draw_mesh( tree_mesh, render_state );
+
+ renderer_end_pass();
}
- RenderState immediate_render_state;
- immediate_render_state.shader = get_shader( SHADER_FLAT_VERTEX_COLOURS );
- immediate_render_state.uniforms[ UNIFORMS_VIEW ] = view_uniforms;
- immediate_render( immediate_render_state );
+ // model depth edge detection
+ {
+ renderer_begin_pass( model_depth_outline, RENDERER_CLEAR_COLOUR_DONT, RENDERER_CLEAR_DEPTH_DONT );
- renderer_end_pass();
+ RenderState render_state;
+ render_state.shader = get_shader( SHADER_DEPTH_EDGE );
+ render_state.depth_func = DEPTHFUNC_ALWAYS;
+ render_state.textures[ 0 ] = model_depth.textures[ OUTPUT_DEPTH ];
+ renderer_draw_fullscreen_triangle( render_state );
+
+ renderer_end_pass();
+ }
+
+ // compose
{
- renderer_begin_pass( RENDERER_CLEAR_COLOUR_DONT, RENDERER_CLEAR_DEPTH_DONT );
+ renderer_begin_pass( RENDERER_CLEAR_COLOUR_DO, RENDERER_CLEAR_DEPTH_DO );
RenderState render_state;
render_state.shader = get_shader( SHADER_GBUFFER );
- render_state.depth_func = DEPTHFUNC_DISABLED;
- render_state.textures[ 0 ] = gbuffer.textures[ OUTPUT_ALBEDO ];
- render_state.textures[ 1 ] = gbuffer.textures[ OUTPUT_NORMAL ];
- render_state.textures[ 2 ] = gbuffer.textures[ OUTPUT_DEPTH ];
+ render_state.uniforms[ UNIFORMS_VIEW ] = view_uniforms;
+ render_state.uniforms[ UNIFORMS_MODEL ] = world_model_uniforms;
+ render_state.cull_face = CULLFACE_FRONT;
+ // render_state.depth_func = DEPTHFUNC_EQUAL;
+ render_state.textures[ 0 ] = world_depth_and_normals.textures[ OUTPUT_NORMAL ];
+ render_state.textures[ 1 ] = world_depth_and_normals.textures[ OUTPUT_DEPTH ];
+ render_state.textures[ 2 ] = model_depth_outline.textures[ OUTPUT_DEPTH ];
- renderer_draw_fullscreen_triangle( render_state );
+ bspr_render( &game->bspr, game->pos, render_state );
+
+ render_state.cull_face = CULLFACE_BACK;
+
+ // immediate_sphere( v3( 0, 0, 0 ), 128, v4( 1, 1, 0, 1 ) );
+ //
+ // if( input->keys[ KEY_T ] ) {
+ // fix = true;
+ // fix_start = game->pos;
+ // fix_end = fix_start + forward * 1000.0f;
+ // }
+ //
+ // if( fix ) {
+ // Intersection is;
+ // bool hit = game->bspr.bsp->trace_seg( fix_start, fix_end, is );
+ //
+ // if( hit ) {
+ // immediate_sphere( is.pos, 16, v4( 1, 0, 0, 1 ) );
+ // }
+ // }
+ //
+ // immediate_render( render_state );
+
+ render_state.uniforms[ UNIFORMS_MODEL ] = tree_model_uniforms;
+ renderer_draw_mesh( tree_mesh, render_state );
renderer_end_pass();
}
@@ -446,6 +560,33 @@ GAME_FRAME( game_frame ) {
render_state.depth_func = DEPTHFUNC_ALWAYS;
immediate_render( render_state );
}
+ {
+ const float aspect = get_aspect_ratio();
+ const float crosshair_thickness = 0.0025f;
+ const float crosshair_length = 0.01f;
+
+ v3 target = v3( 100, -600, 400 + 5 * sinf( current_time * 10 ) );
+ v2 a = screen_pos( P, V, game->pos, target, v2( 1.0f - 0.02f, 1.0f - 0.02f * aspect ), NEAR_PLANE_DEPTH );
+ v3 t = v3( a, 1 );
+
+ const v4 red( 0, 0.5, 0, 1 );
+ immediate_triangle(
+ t + v3( -crosshair_length, crosshair_length * aspect, 0 ),
+ t + v3( -crosshair_length, -crosshair_length * aspect, 0 ),
+ t + v3( crosshair_length, crosshair_length * aspect, 0 ),
+ red
+ );
+ immediate_triangle(
+ t + v3( crosshair_length, -crosshair_length * aspect, 0 ),
+ t + v3( crosshair_length, crosshair_length * aspect, 0 ),
+ t + v3( -crosshair_length, -crosshair_length * aspect, 0 ),
+ red
+ );
+ RenderState render_state;
+ render_state.shader = get_shader( SHADER_UI );
+ render_state.depth_func = DEPTHFUNC_ALWAYS;
+ immediate_render( render_state );
+ }
{
char buf[ 256 ];
diff --git a/linear_algebra.h b/linear_algebra.h
@@ -229,6 +229,7 @@ struct ALIGNTO_SSE v4 {
return w;
}
+ v2 xy() const { return v2( x, y ); }
v3 xyz() const { return v3( x, y, z ); }
};
@@ -653,6 +654,10 @@ forceinline v4 operator/( v4 v, float scale ) {
return v * inv_scale;
}
+forceinline void operator/=( v4 & v, float scale ) {
+ v = v / scale;
+}
+
forceinline v4 operator-( v4 v ) {
return v4( -v.x, -v.y, -v.z, -v.w );
}
diff --git a/renderer.cc b/renderer.cc
@@ -55,8 +55,7 @@ struct DeleteCommand {
struct RenderPass {
size_t begin, one_past_end;
- FB render_target;
- GLbitfield clear_mask;
+ RenderPassConfig config;
};
static DynamicArray< DrawCall > draw_calls;
@@ -326,10 +325,18 @@ void renderer_end_frame() {
uniforms_buffer = NULL;
for( const RenderPass & pass : render_passes ) {
- bind_fb( pass.render_target );
-
- if( pass.clear_mask != 0 ) {
- glClear( pass.clear_mask );
+ bind_fb( pass.config.target );
+
+ GLbitfield clear_mask = 0;
+ if( pass.config.clear_colour )
+ clear_mask |= GL_COLOR_BUFFER_BIT;
+ if( pass.config.clear_depth )
+ clear_mask |= GL_DEPTH_BUFFER_BIT;
+
+ if( clear_mask != 0 ) {
+ glClearColor( pass.config.colour.x, pass.config.colour.y, pass.config.colour.z, pass.config.colour.w );
+ glClearDepth( pass.config.depth );
+ glClear( clear_mask );
}
// TODO: sort draw calls
@@ -383,26 +390,25 @@ void renderer_end_frame() {
}
}
-void renderer_begin_pass( FB render_target, ClearColourBool clear_colour, ClearDepthBool clear_depth ) {
+void renderer_begin_pass( const RenderPassConfig & pass ) {
ASSERT( !in_pass );
in_pass = true;
- GLbitfield clear_mask = 0;
- if( clear_colour == RENDERER_CLEAR_COLOUR_DO ) {
- clear_mask |= GL_COLOR_BUFFER_BIT;
- }
- if( clear_depth == RENDERER_CLEAR_DEPTH_DO ) {
- clear_mask |= GL_DEPTH_BUFFER_BIT;
- }
-
current_render_pass.begin = draw_calls.size();
- current_render_pass.render_target = render_target;
- current_render_pass.clear_mask = clear_mask;
+ current_render_pass.config = pass;
+}
+
+void renderer_begin_pass( FB target, ClearColourBool clear_colour, ClearDepthBool clear_depth ) {
+ RenderPassConfig pass;
+ pass.target = target;
+ pass.clear_colour = clear_colour == RENDERER_CLEAR_COLOUR_DO;
+ pass.clear_depth = clear_depth == RENDERER_CLEAR_DEPTH_DO;
+ renderer_begin_pass( pass );
}
void renderer_begin_pass( ClearColourBool clear_colour, ClearDepthBool clear_depth ) {
- FB render_target = { };
- renderer_begin_pass( render_target, clear_colour, clear_depth );
+ FB target = { };
+ renderer_begin_pass( target, clear_colour, clear_depth );
}
void renderer_end_pass() {
@@ -426,6 +432,8 @@ Texture renderer_blue_noise() {
}
UniformBinding renderer_upload_uniforms( const void * data, size_t size, size_t alignment ) {
+ ASSERT( in_frame );
+
alignment = max( alignment, ubo_offset_alignment );
UniformBinding binding;
diff --git a/renderer.h b/renderer.h
@@ -207,6 +207,16 @@ struct TextureConfig {
v4 border_colour;
};
+struct RenderPassConfig {
+ FB target = { };
+
+ bool clear_colour = false;
+ v4 colour = v4( 0 );
+
+ bool clear_depth = false;
+ float depth = 1.0f;
+};
+
struct FramebufferConfig {
struct FramebufferTexture {
TextureConfig config;
@@ -223,7 +233,8 @@ void renderer_init();
void renderer_term();
void renderer_begin_frame();
-void renderer_begin_pass( FB render_target, ClearColourBool clear_colour, ClearDepthBool clear_depth );
+void renderer_begin_pass( const RenderPassConfig & pass );
+void renderer_begin_pass( FB target, ClearColourBool clear_colour, ClearDepthBool clear_depth );
void renderer_begin_pass( ClearColourBool clear_colour, ClearDepthBool clear_depth );
void renderer_end_pass();
void renderer_end_frame();
diff --git a/shaders.cc b/shaders.cc
@@ -75,9 +75,12 @@ void shaders_init() {
shaders[ SHADER_FLAT_VERTEX_COLOURS_TO_GBUFFER ].path = "shaders/flat_vertex_colours_to_gbuffer.glsl";
shaders[ SHADER_GBUFFER ].path = "shaders/gbuffer.glsl";
- shaders[ SHADER_GBUFFER ].texture_uniform_names[ 0 ] = "albedo";
- shaders[ SHADER_GBUFFER ].texture_uniform_names[ 1 ] = "normal";
- shaders[ SHADER_GBUFFER ].texture_uniform_names[ 2 ] = "depth";
+ shaders[ SHADER_GBUFFER ].texture_uniform_names[ 0 ] = "world_normal";
+ shaders[ SHADER_GBUFFER ].texture_uniform_names[ 1 ] = "world_depth";
+ shaders[ SHADER_GBUFFER ].texture_uniform_names[ 2 ] = "outline_depth";
+
+ shaders[ SHADER_DEPTH_EDGE ].path = "shaders/depth_edge.glsl";
+ shaders[ SHADER_DEPTH_EDGE ].texture_uniform_names[ 0 ] = "model_depth";
int failed = hotload_shaders();
if( failed != 0 ) {
diff --git a/shaders.h b/shaders.h
@@ -18,6 +18,7 @@ enum ShaderID {
SHADER_FLAT_VERTEX_COLOURS_TO_GBUFFER,
SHADER_GBUFFER,
+ SHADER_DEPTH_EDGE,
SHADER_COUNT,
};
diff --git a/shaders/depth_edge.glsl b/shaders/depth_edge.glsl
@@ -0,0 +1,43 @@
+uniform sampler2D model_depth;
+
+#ifdef VERTEX_SHADER
+
+in vec2 position;
+
+void main() {
+ gl_Position = vec4( position, 0.0, 1.0 );
+}
+
+#else
+
+void main() {
+ vec2 pixel = vec2( 1.0 / textureSize( model_depth, 0 ) );
+ vec3 pole = vec3( -1.0, 0.0, 1.0 );
+
+ vec2 uv = gl_FragCoord.xy / textureSize( model_depth, 0 );
+
+ /* float d0 = texture( model_depth, uv + pixel.xy * pole.xx ).r; // x1, y1 */
+ float d1 = texture( model_depth, uv + pixel.xy * pole.yx ).r; // x2, y1
+ /* float d2 = texture( model_depth, uv + pixel.xy * pole.zx ).r; // x3, y1 */
+ float d3 = texture( model_depth, uv + pixel.xy * pole.xy ).r; // x1, y2
+ float d4 = texture( model_depth, uv + pixel.xy * pole.yy ).r; // x2, y2
+ float d5 = texture( model_depth, uv + pixel.xy * pole.zy ).r; // x3, y2
+ /* float d6 = texture( model_depth, uv + pixel.xy * pole.xz ).r; // x1, y3 */
+ float d7 = texture( model_depth, uv + pixel.xy * pole.yz ).r; // x2, y3
+ /* float d8 = texture( model_depth, uv + pixel.xy * pole.zz ).r; // x3, y3 */
+
+ float a = d1 * d3 * d5 * d7;
+ float b = d1 + d3 + d5 + d7;
+
+ // if a == 0, at least one 0 depth
+ // if b != 0, at least one non-0 depth
+
+ if( a == 0.0 && b != 0.0 ) {
+ gl_FragDepth = d4;
+ }
+ else {
+ gl_FragDepth = 0.0;
+ }
+}
+
+#endif
diff --git a/shaders/flat_vertex_colours_to_gbuffer.glsl b/shaders/flat_vertex_colours_to_gbuffer.glsl
@@ -1,36 +1,35 @@
layout( std140 ) uniform view {
- mat4 V;
- mat4 P;
+ mat4 camera_from_world;
+ mat4 clip_from_camera;
+};
+
+layout( std140 ) uniform model {
+ mat4 world_from_model;
};
struct VSOut {
vec3 normal;
- vec3 colour;
};
#ifdef VERTEX_SHADER
in vec3 position;
in vec3 normal;
-in vec3 colour;
out VSOut v2f;
void main() {
- gl_Position = P * V * vec4( position, 1.0 );
- v2f.colour = colour;
- v2f.normal = normal;
+ gl_Position = clip_from_camera * camera_from_world * world_from_model * vec4( position, 1.0 );
+ v2f.normal = mat3( world_from_model ) * normal;
}
#else
in VSOut v2f;
-out vec4 output_albedo;
out vec3 output_normal;
void main() {
- output_albedo = vec4( linear_to_srgb( v2f.colour ), 1.0 );
output_normal = normalize( v2f.normal );
}
diff --git a/shaders/gbuffer.glsl b/shaders/gbuffer.glsl
@@ -1,17 +1,36 @@
-uniform sampler2D albedo;
-uniform sampler2D normal;
-uniform sampler2D depth;
+layout( std140 ) uniform view {
+ mat4 camera_from_world;
+ mat4 clip_from_camera;
+};
+
+layout( std140 ) uniform model {
+ mat4 world_from_model;
+};
+
+uniform sampler2D world_normal;
+uniform sampler2D world_depth;
+uniform sampler2D outline_depth;
+
+struct VSOut {
+ vec3 colour;
+};
#ifdef VERTEX_SHADER
-in vec2 position;
+in vec3 position;
+in vec3 colour;
+
+out VSOut v2f;
void main() {
- gl_Position = vec4( position, 0.0, 1.0 );
+ gl_Position = clip_from_camera * camera_from_world * world_from_model * vec4( position, 1.0 );
+ v2f.colour = colour;
}
#else
+in VSOut v2f;
+
out vec4 screen_colour;
float linearize_depth( float depth ) {
@@ -19,20 +38,20 @@ float linearize_depth( float depth ) {
}
void main() {
- vec2 pixel = vec2( 1.0 / textureSize( albedo, 0 ) );
+ vec2 pixel = vec2( 1.0 / textureSize( world_normal, 0 ) );
vec3 pole = vec3( -1.0, 0.0, 1.0 );
- vec2 uv = gl_FragCoord.xy / textureSize( albedo, 0 );
+ vec2 uv = gl_FragCoord.xy / textureSize( world_normal, 0 );
- float d0 = linearize_depth( texture( depth, uv + pixel.xy * pole.xx ).r ); // x1, y1
- float d1 = linearize_depth( texture( depth, uv + pixel.xy * pole.yx ).r ); // x2, y1
- float d2 = linearize_depth( texture( depth, uv + pixel.xy * pole.zx ).r ); // x3, y1
- float d3 = linearize_depth( texture( depth, uv + pixel.xy * pole.xy ).r ); // x1, y2
- // float d4 = linearize_depth( texture( depth, uv + pixel.xy * pole.yy ).r ); // x2, y2
- float d5 = linearize_depth( texture( depth, uv + pixel.xy * pole.zy ).r ); // x3, y2
- float d6 = linearize_depth( texture( depth, uv + pixel.xy * pole.xz ).r ); // x1, y3
- float d7 = linearize_depth( texture( depth, uv + pixel.xy * pole.yz ).r ); // x2, y3
- float d8 = linearize_depth( texture( depth, uv + pixel.xy * pole.zz ).r ); // x3, y3
+ float d0 = linearize_depth( texture( world_depth, uv + pixel.xy * pole.xx ).r ); // x1, y1
+ float d1 = linearize_depth( texture( world_depth, uv + pixel.xy * pole.yx ).r ); // x2, y1
+ float d2 = linearize_depth( texture( world_depth, uv + pixel.xy * pole.zx ).r ); // x3, y1
+ float d3 = linearize_depth( texture( world_depth, uv + pixel.xy * pole.xy ).r ); // x1, y2
+ float d4 = linearize_depth( texture( world_depth, uv + pixel.xy * pole.yy ).r ); // x2, y2
+ float d5 = linearize_depth( texture( world_depth, uv + pixel.xy * pole.zy ).r ); // x3, y2
+ float d6 = linearize_depth( texture( world_depth, uv + pixel.xy * pole.xz ).r ); // x1, y3
+ float d7 = linearize_depth( texture( world_depth, uv + pixel.xy * pole.yz ).r ); // x2, y3
+ float d8 = linearize_depth( texture( world_depth, uv + pixel.xy * pole.zz ).r ); // x3, y3
float edgeness_depth = (
abs( d1 - d7 ) +
@@ -41,15 +60,15 @@ void main() {
abs( d2 - d6 )
);
- vec3 n0 = texture( normal, uv + pixel.xy * pole.xx ).rgb; // x1, y1
- vec3 n1 = texture( normal, uv + pixel.xy * pole.yx ).xyz; // x2, y1
- vec3 n2 = texture( normal, uv + pixel.xy * pole.zx ).xyz; // x3, y1
- vec3 n3 = texture( normal, uv + pixel.xy * pole.xy ).xyz; // x1, y2
- // vec3 n4 = texture( normal, uv + pixel.xy * pole.yy ).xyz; // x2, y2
- vec3 n5 = texture( normal, uv + pixel.xy * pole.zy ).xyz; // x3, y2
- vec3 n6 = texture( normal, uv + pixel.xy * pole.xz ).xyz; // x1, y3
- vec3 n7 = texture( normal, uv + pixel.xy * pole.yz ).xyz; // x2, y3
- vec3 n8 = texture( normal, uv + pixel.xy * pole.zz ).xyz; // x3, y3
+ vec3 n0 = texture( world_normal, uv + pixel.xy * pole.xx ).rgb; // x1, y1
+ vec3 n1 = texture( world_normal, uv + pixel.xy * pole.yx ).xyz; // x2, y1
+ vec3 n2 = texture( world_normal, uv + pixel.xy * pole.zx ).xyz; // x3, y1
+ vec3 n3 = texture( world_normal, uv + pixel.xy * pole.xy ).xyz; // x1, y2
+ // vec3 n4 = texture( world_normal, uv + pixel.xy * pole.yy ).xyz; // x2, y2
+ vec3 n5 = texture( world_normal, uv + pixel.xy * pole.zy ).xyz; // x3, y2
+ vec3 n6 = texture( world_normal, uv + pixel.xy * pole.xz ).xyz; // x1, y3
+ vec3 n7 = texture( world_normal, uv + pixel.xy * pole.yz ).xyz; // x2, y3
+ vec3 n8 = texture( world_normal, uv + pixel.xy * pole.zz ).xyz; // x3, y3
float edgeness_normal = (
max( 0.0, 1.0 - dot( n1, n7 ) ) +
@@ -60,9 +79,11 @@ void main() {
edgeness_normal = max( edgeness_normal - 0.1, 0.0 ) / 0.9;
- vec4 edgeness = vec4( vec3( max( edgeness_depth, edgeness_normal ) ), 0.0 );
+ vec3 edgeness = vec3( max( edgeness_depth, edgeness_normal ) );
+
+ vec3 colour = texture( outline_depth, uv ).r > d4 ? vec3( 1.0, 0.0, 0.0 ) : v2f.colour - edgeness;
- screen_colour = texture( albedo, uv ) - edgeness;
+ screen_colour = vec4( colour, 1.0 );
}
#endif