more substance painter and shader tests
This commit is contained in:
@@ -18,7 +18,7 @@ vec3 blur(sampler2D sp, vec2 uv, vec2 scale) {
|
||||
float accum = 0.0;
|
||||
float weight;
|
||||
vec2 offset;
|
||||
|
||||
|
||||
for (int x = -samples / 2; x < samples / 2; ++x) {
|
||||
for (int y = -samples / 2; y < samples / 2; ++y) {
|
||||
offset = vec2(float(x), float(y));
|
||||
@@ -27,14 +27,14 @@ vec3 blur(sampler2D sp, vec2 uv, vec2 scale) {
|
||||
accum += weight;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return col / accum;
|
||||
}
|
||||
|
||||
void fragment() {
|
||||
vec2 ps = vec2(1.0) / iResolution.xy * .000001 * strength;
|
||||
vec2 uv = UV ;
|
||||
|
||||
|
||||
COLOR.rgb = blur(SCREEN_TEXTURE, uv, ps );
|
||||
COLOR.a = 1.0;
|
||||
}
|
||||
|
||||
185
assets/Shaders/cel-shader-base.gdshader
Normal file
185
assets/Shaders/cel-shader-base.gdshader
Normal file
@@ -0,0 +1,185 @@
|
||||
shader_type spatial;
|
||||
|
||||
#define USE_ALPHA 0
|
||||
#define USE_ALPHA_CUTOFF 0
|
||||
#define USE_EMISSION 0
|
||||
#define USE_REFLECTIONS 0
|
||||
#define USE_NORMAL_MAP 0
|
||||
#define USE_OCCLUSION 0
|
||||
#define USE_ANISOTROPY 0
|
||||
#define USE_BACKLIGHT 0
|
||||
#define USE_REFRACTION 0
|
||||
|
||||
#if USE_ALPHA
|
||||
render_mode depth_draw_always;
|
||||
#endif
|
||||
|
||||
#include "includes/base-cel-shader.gdshaderinc"
|
||||
|
||||
#if USE_EMISSION
|
||||
#include "includes/emission.gdshaderinc"
|
||||
#endif
|
||||
|
||||
#if USE_REFLECTIONS
|
||||
#include "includes/reflections.gdshaderinc"
|
||||
#endif
|
||||
|
||||
#if USE_NORMAL_MAP
|
||||
#include "includes/normal-map.gdshaderinc"
|
||||
#endif
|
||||
|
||||
#if USE_OCCLUSION
|
||||
#include "includes/occlusion.gdshaderinc"
|
||||
#endif
|
||||
|
||||
#if USE_ANISOTROPY
|
||||
#include "includes/anisotropy.gdshaderinc"
|
||||
#endif
|
||||
|
||||
#if USE_BACKLIGHT
|
||||
#include "includes/backlight.gdshaderinc"
|
||||
#endif
|
||||
|
||||
#if USE_REFRACTION
|
||||
#include "includes/refraction.gdshaderinc"
|
||||
#elif !USE_REFRACTION && USE_ALPHA
|
||||
#include "includes/transparency.gdshaderinc"
|
||||
#endif
|
||||
|
||||
group_uniforms BaseProperties;
|
||||
#if USE_ALPHA_CUTOFF
|
||||
uniform float alpha_cutoff: hint_range(0.0, 1.0) = 0.5;
|
||||
#endif
|
||||
uniform vec4 color: source_color = vec4(0.7, 0.12, 0.86, 1.0);
|
||||
uniform sampler2D base_texture: source_color;
|
||||
uniform vec4 specular: source_color = vec4(0.3, 0.3, 0.3, 0.5);
|
||||
uniform sampler2D specular_texture: hint_default_white;
|
||||
uniform vec4 fresnel: source_color = vec4(0.2, 0.2, 0.2, 0.3);
|
||||
uniform sampler2D fresnel_texture: hint_default_white;
|
||||
group_uniforms;
|
||||
|
||||
varying vec3 SPECULAR_COLOR;
|
||||
varying float SPECULAR_STRENGTH;
|
||||
varying vec3 FRESNEL_COLOR;
|
||||
varying float FRESNEL_STRENGTH;
|
||||
|
||||
group_uniforms Tiling;
|
||||
uniform vec2 uv_scale = vec2(1,1);
|
||||
uniform vec2 uv_offset = vec2(0,0);
|
||||
group_uniforms;
|
||||
|
||||
|
||||
void vertex() {
|
||||
UV = UV * uv_scale.xy + uv_offset.xy;
|
||||
}
|
||||
|
||||
void fragment() {
|
||||
ALBEDO = color.rgb * texture(base_texture, UV).rgb;
|
||||
#if USE_ALPHA
|
||||
float alpha = color.a * texture(base_texture, UV).a;
|
||||
ALBEDO *= alpha;
|
||||
#elif USE_ALPHA_CUTOFF
|
||||
ALPHA = color.a * texture(base_texture, UV).a;
|
||||
ALPHA_SCISSOR_THRESHOLD = color.a * texture(base_texture, UV).a;
|
||||
#endif
|
||||
|
||||
#if USE_REFRACTION && USE_ALPHA
|
||||
EMISSION += refraction_fragment(alpha, NORMAL, SCREEN_UV, FRAGCOORD.z);
|
||||
#elif !USE_REFRACTION && USE_ALPHA
|
||||
EMISSION += transparency_fragment(alpha, SCREEN_UV);
|
||||
#endif
|
||||
|
||||
SPECULAR_COLOR = specular.rgb * texture(specular_texture, UV).rgb;
|
||||
SPECULAR_STRENGTH = specular.a * texture(specular_texture, UV).a;
|
||||
FRESNEL_COLOR = fresnel.rgb * texture(fresnel_texture, UV).rgb;
|
||||
FRESNEL_STRENGTH = fresnel.a * texture(fresnel_texture, UV).a;
|
||||
|
||||
#if USE_EMISSION
|
||||
EMISSION += emission_fragment(UV);
|
||||
#endif
|
||||
|
||||
#if USE_REFLECTIONS
|
||||
Surface surf = reflections_fragment(UV);
|
||||
METALLIC = surf.metallic;
|
||||
ROUGHNESS = surf.roughness;
|
||||
#endif
|
||||
|
||||
#if USE_NORMAL_MAP
|
||||
NormalData normal = normal_map_fragment(UV, NORMAL, TANGENT, BINORMAL);
|
||||
NORMAL = normal.vector;
|
||||
NORMAL_MAP = normal.map;
|
||||
NORMAL_MAP_DEPTH = normal.depth;
|
||||
#endif
|
||||
|
||||
#if USE_OCCLUSION
|
||||
OcclusionData occlusion = occlusion_fragment(UV);
|
||||
AO = occlusion.ao;
|
||||
AO_LIGHT_AFFECT = occlusion.ao_light_affect;
|
||||
#endif
|
||||
|
||||
#if USE_ANISOTROPY
|
||||
AnisotropyData aniso = anisotropy_fragment(UV);
|
||||
ANISOTROPY_DIR = aniso.direction;
|
||||
ANISOTROPY_RATIO = aniso.ratio;
|
||||
#endif
|
||||
|
||||
#if USE_BACKLIGHT
|
||||
BACKLIGHT = backlight_fragment(UV);
|
||||
#endif
|
||||
}
|
||||
|
||||
void light() {
|
||||
#if USE_BACKLIGHT
|
||||
DIFFUSE_LIGHT += backlight_diffuse(
|
||||
ALBEDO,
|
||||
LIGHT_COLOR,
|
||||
LIGHT,
|
||||
NORMAL,
|
||||
ATTENUATION,
|
||||
BACKLIGHT
|
||||
);
|
||||
#else
|
||||
DIFFUSE_LIGHT += diffuse_light(
|
||||
ALBEDO,
|
||||
LIGHT_COLOR,
|
||||
LIGHT,
|
||||
NORMAL,
|
||||
ATTENUATION
|
||||
);
|
||||
#endif
|
||||
|
||||
#if USE_ANISOTROPY
|
||||
SPECULAR_LIGHT += anisotropy_specular(
|
||||
LIGHT_COLOR,
|
||||
SPECULAR_COLOR,
|
||||
SPECULAR_STRENGTH,
|
||||
NORMAL,
|
||||
VIEW,
|
||||
LIGHT,
|
||||
ATTENUATION,
|
||||
UV,
|
||||
ANISOTROPY_DIR,
|
||||
ANISOTROPY_RATIO
|
||||
);
|
||||
#else
|
||||
SPECULAR_LIGHT += specular_light(
|
||||
LIGHT_COLOR,
|
||||
SPECULAR_COLOR,
|
||||
SPECULAR_STRENGTH,
|
||||
NORMAL,
|
||||
VIEW,
|
||||
LIGHT,
|
||||
ATTENUATION
|
||||
);
|
||||
#endif
|
||||
|
||||
SPECULAR_LIGHT += fresnel_light(
|
||||
LIGHT_COLOR,
|
||||
FRESNEL_COLOR,
|
||||
FRESNEL_STRENGTH,
|
||||
NORMAL,
|
||||
VIEW,
|
||||
LIGHT,
|
||||
ATTENUATION
|
||||
);
|
||||
}
|
||||
272
assets/Shaders/outline.gdshader
Normal file
272
assets/Shaders/outline.gdshader
Normal file
@@ -0,0 +1,272 @@
|
||||
shader_type spatial;
|
||||
render_mode unshaded, blend_mix, depth_draw_never, depth_test_disabled;
|
||||
|
||||
/*
|
||||
AUTHOR: Hannah "EMBYR" Crawford
|
||||
ENGINE_VERSION: 4.0.3
|
||||
|
||||
HOW TO USE:
|
||||
1. Create a MeshInstance3D node and place it in your scene.
|
||||
2. Set it's size to 2x2.
|
||||
3. Enable the "Flip Faces" option.
|
||||
4. Create a new shader material with this shader.
|
||||
5. Assign the material to the MeshInstance3D
|
||||
|
||||
LIMITATIONS:
|
||||
Does not work well with TAA enabled.
|
||||
|
||||
MOBILE_NOTES:
|
||||
The mobile renderer does not have access to the normal_roughness texture
|
||||
so we must rely on techniques to reconstruct this information from the
|
||||
depth buffer.
|
||||
|
||||
If you require support on mobile please uncomment the SUPPORT_MOBILE line
|
||||
below. I have done my best to match the appearance between the two modes
|
||||
however, mobile does not take into account smooth-shaded faces.
|
||||
|
||||
The high-quality reconstruction method used on mobile is rather heavy on
|
||||
texture samples. If you would like to use the lower-quality recontruction
|
||||
method for better performance, please uncomment the NAIVE_NORMAL_RECONSTRUCTION
|
||||
line below.
|
||||
*/
|
||||
//#define SUPPORT_MOBILE
|
||||
//#define NAIVE_NORMAL_RECONSTRUCTION
|
||||
|
||||
group_uniforms outline;
|
||||
uniform vec4 outlineColor: source_color = vec4(0.0, 0.0, 0.0, 0.78);
|
||||
uniform float depth_threshold = 0.025;
|
||||
uniform float normal_threshold : hint_range(0.0, 1.5) = 0.5;
|
||||
uniform float normal_smoothing : hint_range(0.0, 1.0) = 0.25;
|
||||
|
||||
group_uniforms thickness;
|
||||
uniform float max_thickness: hint_range(0.0, 5.0) = 1.3;
|
||||
uniform float min_thickness = 0.5;
|
||||
uniform float max_distance = 75.0;
|
||||
uniform float min_distance = 2.0;
|
||||
|
||||
group_uniforms grazing_prevention;
|
||||
uniform float grazing_fresnel_power = 5.0;
|
||||
uniform float grazing_angle_mask_power = 1.0;
|
||||
uniform float grazing_angle_modulation_factor = 50.0;
|
||||
|
||||
uniform sampler2D DEPTH_TEXTURE : hint_depth_texture, filter_linear, repeat_disable;
|
||||
|
||||
#ifndef SUPPORT_MOBILE
|
||||
uniform sampler2D NORMR_TEXTURE : hint_normal_roughness_texture, filter_linear, repeat_disable;
|
||||
#else
|
||||
varying flat mat4 model_view_matrix;
|
||||
#endif// !SUPPORT_MOBILE
|
||||
|
||||
struct UVNeighbors {
|
||||
vec2 center;
|
||||
vec2 left; vec2 right; vec2 up; vec2 down;
|
||||
vec2 top_left; vec2 top_right; vec2 bottom_left; vec2 bottom_right;
|
||||
};
|
||||
|
||||
struct NeighborDepthSamples {
|
||||
float c_d;
|
||||
float l_d; float r_d; float u_d; float d_d;
|
||||
float tl_d; float tr_d; float bl_d; float br_d;
|
||||
};
|
||||
|
||||
UVNeighbors getNeighbors(vec2 center, float width, float aspect) {
|
||||
vec2 h_offset = vec2(width * aspect * 0.001, 0.0);
|
||||
vec2 v_offset = vec2(0.0, width * 0.001);
|
||||
UVNeighbors n;
|
||||
n.center = center;
|
||||
n.left = center - h_offset;
|
||||
n.right = center + h_offset;
|
||||
n.up = center - v_offset;
|
||||
n.down = center + v_offset;
|
||||
n.top_left = center - (h_offset - v_offset);
|
||||
n.top_right = center + (h_offset - v_offset);
|
||||
n.bottom_left = center - (h_offset + v_offset);
|
||||
n.bottom_right = center + (h_offset + v_offset);
|
||||
return n;
|
||||
}
|
||||
|
||||
float getMinimumDepth(NeighborDepthSamples ds){
|
||||
return min(ds.c_d, min(ds.l_d, min(ds.r_d, min(ds.u_d, min(ds.d_d, min(ds.tl_d, min(ds.tr_d, min(ds.bl_d, ds.br_d))))))));
|
||||
}
|
||||
|
||||
float getLinearDepth(float depth, vec2 uv, mat4 inv_proj) {
|
||||
vec3 ndc = vec3(uv * 2.0 - 1.0, depth);
|
||||
vec4 view = inv_proj * vec4(ndc, 1.0);
|
||||
view.xyz /= view.w;
|
||||
return -view.z;
|
||||
}
|
||||
|
||||
NeighborDepthSamples getLinearDepthSamples(UVNeighbors uvs, sampler2D depth_tex, mat4 invProjMat) {
|
||||
NeighborDepthSamples result;
|
||||
result.c_d = getLinearDepth(texture(depth_tex, uvs.center).r, uvs.center, invProjMat);
|
||||
result.l_d = getLinearDepth(texture(depth_tex, uvs.left).r , uvs.left , invProjMat);
|
||||
result.r_d = getLinearDepth(texture(depth_tex, uvs.right).r , uvs.right , invProjMat);
|
||||
result.u_d = getLinearDepth(texture(depth_tex, uvs.up).r , uvs.up , invProjMat);
|
||||
result.d_d = getLinearDepth(texture(depth_tex, uvs.down).r , uvs.down , invProjMat);
|
||||
result.tl_d = getLinearDepth(texture(depth_tex, uvs.top_left).r, uvs.top_left, invProjMat);
|
||||
result.tr_d = getLinearDepth(texture(depth_tex, uvs.top_right).r, uvs.top_right, invProjMat);
|
||||
result.bl_d = getLinearDepth(texture(depth_tex, uvs.bottom_left).r, uvs.bottom_left, invProjMat);
|
||||
result.br_d = getLinearDepth(texture(depth_tex, uvs.bottom_right).r, uvs.bottom_right, invProjMat);
|
||||
return result;
|
||||
}
|
||||
|
||||
float remap(float v, float from1, float to1, float from2, float to2) {
|
||||
return (v - from1) / (to1 - from1) * (to2 - from2) + from2;
|
||||
}
|
||||
|
||||
float fresnel(float amount, vec3 normal, vec3 view) {
|
||||
return pow((1.0 - clamp(dot(normalize(normal), normalize(view)), 0.0, 1.0 )), amount);
|
||||
}
|
||||
|
||||
float getGrazingAngleModulation(vec3 pixel_normal, vec3 view) {
|
||||
float x = clamp(((fresnel(grazing_fresnel_power, pixel_normal, view) - 1.0) / grazing_angle_mask_power) + 1.0, 0.0, 1.0);
|
||||
return (x + grazing_angle_modulation_factor) + 1.0;
|
||||
}
|
||||
|
||||
float detectEdgesDepth(NeighborDepthSamples depth_samples, vec3 pixel_normal, vec3 view) {
|
||||
float n_total =
|
||||
depth_samples.l_d +
|
||||
depth_samples.r_d +
|
||||
depth_samples.u_d +
|
||||
depth_samples.d_d +
|
||||
depth_samples.tl_d +
|
||||
depth_samples.tr_d +
|
||||
depth_samples.bl_d +
|
||||
depth_samples.br_d;
|
||||
|
||||
float t = depth_threshold * getGrazingAngleModulation(pixel_normal, view);
|
||||
return step(t, n_total - (depth_samples.c_d * 8.0));
|
||||
}
|
||||
|
||||
// Reconstruction helpers
|
||||
// Source: https://www.reddit.com/r/godot/comments/v70p2k/improved_normal_from_depth/
|
||||
#ifdef SUPPORT_MOBILE
|
||||
vec3 reconstructWorldPosition(float depth, mat4 model_view, mat4 inv_proj, vec2 screen_uv, mat4 world, mat4 inv_cam){
|
||||
vec4 pos = inverse(model_view) * inv_proj * vec4((screen_uv * 2.0 - 1.0), depth * 2.0 - 1.0, 1.0);
|
||||
pos.xyz /= (pos.w + 0.0001 * (1.-abs(sign(pos.w))));
|
||||
return (pos * inv_cam).xyz + world[3].xyz;
|
||||
}
|
||||
|
||||
#ifndef NAIVE_NORMAL_RECONSTRUCTION
|
||||
vec3 reconstructWorldNormal(sampler2D depth_tex, mat4 model_view, mat4 inv_proj, vec2 screen_uv, mat4 world, mat4 inv_cam, vec2 viewport_size) {
|
||||
vec2 e = vec2(1.0 / viewport_size);
|
||||
float c0 = texture(depth_tex, screen_uv ).r;
|
||||
float l2 = texture(depth_tex, screen_uv - vec2(2,0) * e).r;
|
||||
float l1 = texture(depth_tex, screen_uv - vec2(1,0) * e).r;
|
||||
float r1 = texture(depth_tex, screen_uv + vec2(1,0) * e).r;
|
||||
float r2 = texture(depth_tex, screen_uv + vec2(2,0) * e).r;
|
||||
float b2 = texture(depth_tex, screen_uv - vec2(0,2) * e).r;
|
||||
float b1 = texture(depth_tex, screen_uv - vec2(0,1) * e).r;
|
||||
float t1 = texture(depth_tex, screen_uv + vec2(0,1) * e).r;
|
||||
float t2 = texture(depth_tex, screen_uv + vec2(0,2) * e).r;
|
||||
|
||||
float dl = abs(l1 * l2 / (2.0 * l2 - l1) - c0);
|
||||
float dr = abs(r1 * r2 / (2.0 * r2 - r1) - c0);
|
||||
float db = abs(b1 * b2 / (2.0 * b2 - b1) - c0);
|
||||
float dt = abs(t1 * t2 / (2.0 * t2 - t1) - c0);
|
||||
|
||||
vec3 ce = reconstructWorldPosition(c0, model_view, inv_proj, screen_uv, world, inv_cam);
|
||||
|
||||
vec3 dpdx = (dl<dr) ? ce-reconstructWorldPosition(l1, model_view, inv_proj, screen_uv - vec2(1,0) * e, world, inv_cam) :
|
||||
-ce+reconstructWorldPosition(r1, model_view, inv_proj, screen_uv + vec2(1,0) * e, world, inv_cam) ;
|
||||
vec3 dpdy = (db<dt) ? ce-reconstructWorldPosition(b1, model_view, inv_proj, screen_uv - vec2(0,1) * e, world, inv_cam) :
|
||||
-ce+reconstructWorldPosition(t1, model_view, inv_proj, screen_uv + vec2(0,1) * e, world, inv_cam) ;
|
||||
|
||||
return normalize(cross(dpdx,dpdy));
|
||||
}
|
||||
#else
|
||||
vec3 reconstructWorldNormal(sampler2D depth_tex, mat4 model_view, mat4 inv_proj, vec2 screen_uv, mat4 world, mat4 inv_cam, vec2 viewport_size) {
|
||||
vec3 pos = reconstructWorldPosition(texture(depth_tex, screen_uv).x, model_view, inv_proj, screen_uv, world, inv_cam);
|
||||
return normalize(cross(dFdx(pos), dFdy(pos)));
|
||||
}
|
||||
#endif//!NAIVE_NORMAL_RECONSTRUCTION
|
||||
|
||||
float detectEdgesNormalReconstructed(UVNeighbors uvs, sampler2D depth_tex, mat4 model_view, mat4 inv_proj, vec2 screen_uv, mat4 world, mat4 inv_cam, vec2 viewport_size){
|
||||
vec3 n_u = reconstructWorldNormal(depth_tex, model_view, inv_proj, uvs.up, world, inv_cam, viewport_size);
|
||||
vec3 n_d = reconstructWorldNormal(depth_tex, model_view, inv_proj, uvs.down, world, inv_cam, viewport_size);
|
||||
vec3 n_l = reconstructWorldNormal(depth_tex, model_view, inv_proj, uvs.left, world, inv_cam, viewport_size);
|
||||
vec3 n_r = reconstructWorldNormal(depth_tex, model_view, inv_proj, uvs.right, world, inv_cam, viewport_size);
|
||||
vec3 n_tl = reconstructWorldNormal(depth_tex, model_view, inv_proj, uvs.top_left, world, inv_cam, viewport_size);
|
||||
vec3 n_tr = reconstructWorldNormal(depth_tex, model_view, inv_proj, uvs.top_right, world, inv_cam, viewport_size);
|
||||
vec3 n_bl = reconstructWorldNormal(depth_tex, model_view, inv_proj, uvs.bottom_left, world, inv_cam, viewport_size);
|
||||
vec3 n_br = reconstructWorldNormal(depth_tex, model_view, inv_proj, uvs.bottom_right, world, inv_cam, viewport_size);
|
||||
|
||||
vec3 normalFiniteDifference0 = n_tr - n_bl;
|
||||
vec3 normalFiniteDifference1 = n_tl - n_br;
|
||||
vec3 normalFiniteDifference2 = n_l - n_r;
|
||||
vec3 normalFiniteDifference3 = n_u - n_d;
|
||||
|
||||
float edgeNormal = sqrt(
|
||||
dot(normalFiniteDifference0, normalFiniteDifference0) +
|
||||
dot(normalFiniteDifference1, normalFiniteDifference1) +
|
||||
dot(normalFiniteDifference2, normalFiniteDifference2) +
|
||||
dot(normalFiniteDifference3, normalFiniteDifference3)
|
||||
) * 0.5;
|
||||
|
||||
return smoothstep(normal_threshold - normal_smoothing, normal_threshold + normal_smoothing, edgeNormal);
|
||||
}
|
||||
#else
|
||||
float detectEdgesNormal(UVNeighbors uvs, sampler2D normTex, vec3 camDirWorld){
|
||||
vec3 n_u = texture(normTex, uvs.up).xyz;
|
||||
vec3 n_d = texture(normTex, uvs.down).xyz;
|
||||
vec3 n_l = texture(normTex, uvs.left).xyz;
|
||||
vec3 n_r = texture(normTex, uvs.right).xyz;
|
||||
vec3 n_tl = texture(normTex, uvs.top_left).xyz;
|
||||
vec3 n_tr = texture(normTex, uvs.top_right).xyz;
|
||||
vec3 n_bl = texture(normTex, uvs.bottom_left).xyz;
|
||||
vec3 n_br = texture(normTex, uvs.bottom_right).xyz;
|
||||
|
||||
vec3 normalFiniteDifference0 = n_tr - n_bl;
|
||||
vec3 normalFiniteDifference1 = n_tl - n_br;
|
||||
vec3 normalFiniteDifference2 = n_l - n_r;
|
||||
vec3 normalFiniteDifference3 = n_u - n_d;
|
||||
|
||||
float edgeNormal = sqrt(
|
||||
dot(normalFiniteDifference0, normalFiniteDifference0) +
|
||||
dot(normalFiniteDifference1, normalFiniteDifference1) +
|
||||
dot(normalFiniteDifference2, normalFiniteDifference2) +
|
||||
dot(normalFiniteDifference3, normalFiniteDifference3)
|
||||
);
|
||||
|
||||
return smoothstep(normal_threshold - normal_smoothing, normal_threshold + normal_smoothing, edgeNormal);
|
||||
}
|
||||
#endif//SUPPORT_MOBILE
|
||||
|
||||
void vertex() {
|
||||
POSITION = vec4(VERTEX, 1.0);
|
||||
|
||||
#ifdef SUPPORT_MOBILE
|
||||
model_view_matrix = INV_VIEW_MATRIX * mat4(VIEW_MATRIX[0],VIEW_MATRIX[1],VIEW_MATRIX[2],VIEW_MATRIX[3]);;
|
||||
#endif
|
||||
}
|
||||
|
||||
void fragment() {
|
||||
float aspect = float(VIEWPORT_SIZE.y) / float(VIEWPORT_SIZE.x);
|
||||
|
||||
UVNeighbors n = getNeighbors(SCREEN_UV, max_thickness, aspect);
|
||||
NeighborDepthSamples depth_samples = getLinearDepthSamples(n, DEPTH_TEXTURE, INV_PROJECTION_MATRIX);
|
||||
|
||||
float min_d = getMinimumDepth(depth_samples);
|
||||
float thickness = clamp(remap(min_d, min_distance, max_distance, max_thickness, min_thickness), min_thickness, max_thickness);
|
||||
float fade_a = clamp(remap(min_d, min_distance, max_distance, 1.0, 0.0), 0.0, 1.0);
|
||||
|
||||
n = getNeighbors(SCREEN_UV, thickness, aspect);
|
||||
depth_samples = getLinearDepthSamples(n, DEPTH_TEXTURE, INV_PROJECTION_MATRIX);
|
||||
|
||||
#ifndef SUPPORT_MOBILE
|
||||
vec3 pixel_normal = texture(NORMR_TEXTURE, SCREEN_UV).xyz;
|
||||
#else
|
||||
vec3 pixel_normal = reconstructWorldNormal(DEPTH_TEXTURE, model_view_matrix, INV_PROJECTION_MATRIX, SCREEN_UV, MODEL_MATRIX, INV_VIEW_MATRIX, VIEWPORT_SIZE.xy);
|
||||
#endif
|
||||
|
||||
float depthEdges = detectEdgesDepth(depth_samples, pixel_normal, VIEW);
|
||||
|
||||
#ifndef SUPPORT_MOBILE
|
||||
float normEdges = min(detectEdgesNormal(n, NORMR_TEXTURE, CAMERA_DIRECTION_WORLD), 1.0);
|
||||
#else
|
||||
float normEdges = min(detectEdgesNormalReconstructed(n, DEPTH_TEXTURE, model_view_matrix, INV_PROJECTION_MATRIX, SCREEN_UV, MODEL_MATRIX, INV_VIEW_MATRIX, VIEWPORT_SIZE.xy), 1.0);
|
||||
#endif
|
||||
|
||||
ALBEDO.rgb = outlineColor.rgb;
|
||||
ALPHA = max(depthEdges, normEdges) * outlineColor.a * fade_a;
|
||||
}
|
||||
107
assets/Shaders/pixelArt.gdshader
Normal file
107
assets/Shaders/pixelArt.gdshader
Normal file
@@ -0,0 +1,107 @@
|
||||
shader_type spatial;
|
||||
render_mode unshaded;
|
||||
|
||||
// MIT License. Made by Leo Peltola
|
||||
// Inspired by https://threejs.org/examples/webgl_postprocessing_pixel.html
|
||||
|
||||
uniform sampler2D DEPTH_TEXTURE : hint_depth_texture, filter_linear_mipmap;
|
||||
uniform sampler2D SCREEN_TEXTURE : hint_screen_texture, filter_linear_mipmap;
|
||||
uniform sampler2D NORMAL_TEXTURE : hint_normal_roughness_texture, filter_nearest;
|
||||
|
||||
uniform bool shadows_enabled = true;
|
||||
uniform bool highlights_enabled = true;
|
||||
uniform float shadow_strength : hint_range(0.0, 1.0, 0.01) = 0.4;
|
||||
uniform float highlight_strength : hint_range(0.0, 1.0, 0.01) = 0.1;
|
||||
uniform vec3 highlight_color : source_color = vec3(1.);
|
||||
uniform vec3 shadow_color : source_color = vec3(0.0);
|
||||
|
||||
varying mat4 model_view_matrix;
|
||||
|
||||
|
||||
float getDepth(vec2 screen_uv, sampler2D depth_texture, mat4 inv_projection_matrix){
|
||||
// Credit: https://godotshaders.com/shader/depth-modulated-pixel-outline-in-screen-space/
|
||||
float raw_depth = texture(depth_texture, screen_uv)[0];
|
||||
vec3 normalized_device_coordinates = vec3(screen_uv * 2.0 - 1.0, raw_depth);
|
||||
vec4 view_space = inv_projection_matrix * vec4(normalized_device_coordinates, 1.0);
|
||||
view_space.xyz /= view_space.w;
|
||||
return -view_space.z;
|
||||
}
|
||||
|
||||
vec3 getPos(float depth, mat4 mvm, mat4 ipm, vec2 suv, mat4 wm, mat4 icm){
|
||||
vec4 pos = inverse(mvm) * ipm * vec4((suv * 2.0 - 1.0), depth * 2.0 - 1.0, 1.0);
|
||||
pos.xyz /= (pos.w+0.0001*(1.-abs(sign(pos.w))));
|
||||
return (pos*icm).xyz+wm[3].xyz;
|
||||
}
|
||||
|
||||
float normalIndicator(vec3 normalEdgeBias, vec3 baseNormal, vec3 newNormal, float depth_diff){
|
||||
// Credit: https://threejs.org/examples/webgl_postprocessing_pixel.html
|
||||
float normalDiff = dot(baseNormal - newNormal, normalEdgeBias);
|
||||
float normalIndicator = clamp(smoothstep(-.01, .01, normalDiff), 0.0, 1.0);
|
||||
float depthIndicator = clamp(sign(depth_diff * .25 + .0025), 0.0, 1.0);
|
||||
return (1.0 - dot(baseNormal, newNormal)) * depthIndicator * normalIndicator;
|
||||
}
|
||||
|
||||
void vertex(){
|
||||
model_view_matrix = VIEW_MATRIX * mat4(INV_VIEW_MATRIX[0], INV_VIEW_MATRIX[1], INV_VIEW_MATRIX[2], MODEL_MATRIX[3]);
|
||||
}
|
||||
|
||||
void fragment() {
|
||||
vec2 e = vec2(1./VIEWPORT_SIZE.xy);
|
||||
|
||||
// Shadows
|
||||
float depth_diff = 0.0;
|
||||
float neg_depth_diff = .5;
|
||||
if (shadows_enabled) {
|
||||
float depth = getDepth(SCREEN_UV, DEPTH_TEXTURE, INV_PROJECTION_MATRIX);
|
||||
float du = getDepth(SCREEN_UV+vec2(0., -1.)*e, DEPTH_TEXTURE, INV_PROJECTION_MATRIX);
|
||||
float dr = getDepth(SCREEN_UV+vec2(1., 0.)*e, DEPTH_TEXTURE, INV_PROJECTION_MATRIX);
|
||||
float dd = getDepth(SCREEN_UV+vec2(0., 1.)*e, DEPTH_TEXTURE, INV_PROJECTION_MATRIX);
|
||||
float dl = getDepth(SCREEN_UV+vec2(-1., 0.)*e, DEPTH_TEXTURE, INV_PROJECTION_MATRIX);
|
||||
depth_diff += clamp(du - depth, 0., 1.);
|
||||
depth_diff += clamp(dd - depth, 0., 1.);
|
||||
depth_diff += clamp(dr - depth, 0., 1.);
|
||||
depth_diff += clamp(dl - depth, 0., 1.);
|
||||
neg_depth_diff += depth - du;
|
||||
neg_depth_diff += depth - dd;
|
||||
neg_depth_diff += depth - dr;
|
||||
neg_depth_diff += depth - dl;
|
||||
neg_depth_diff = clamp(neg_depth_diff, 0., 1.);
|
||||
neg_depth_diff = clamp(smoothstep(0.5, 0.5, neg_depth_diff)*10., 0., 1.);
|
||||
depth_diff = smoothstep(0.2, 0.3, depth_diff);
|
||||
// ALBEDO = vec3(neg_depth_diff);
|
||||
}
|
||||
|
||||
// Highlights
|
||||
float normal_diff = 0.;
|
||||
if (highlights_enabled) {
|
||||
vec3 normal = texture(NORMAL_TEXTURE, SCREEN_UV).rgb * 2.0 - 1.0;
|
||||
vec3 nu = texture(NORMAL_TEXTURE, SCREEN_UV+vec2(0., -1.)*e).rgb * 2.0 - 1.0;
|
||||
vec3 nr = texture(NORMAL_TEXTURE, SCREEN_UV+vec2(1., 0.)*e).rgb * 2.0 - 1.0;
|
||||
vec3 nd = texture(NORMAL_TEXTURE, SCREEN_UV+vec2(0., 1.)*e).rgb * 2.0 - 1.0;
|
||||
vec3 nl = texture(NORMAL_TEXTURE, SCREEN_UV+vec2(-1., 0.)*e).rgb * 2.0 - 1.0;
|
||||
vec3 normal_edge_bias = (vec3(1., 1., 1.));
|
||||
normal_diff += normalIndicator(normal_edge_bias, normal, nu, depth_diff);
|
||||
normal_diff += normalIndicator(normal_edge_bias, normal, nr, depth_diff);
|
||||
normal_diff += normalIndicator(normal_edge_bias, normal, nd, depth_diff);
|
||||
normal_diff += normalIndicator(normal_edge_bias, normal, nl, depth_diff);
|
||||
normal_diff = smoothstep(0.2, 0.8, normal_diff);
|
||||
normal_diff = clamp(normal_diff-neg_depth_diff, 0., 1.);
|
||||
// ALBEDO = vec3(normal_diff);
|
||||
}
|
||||
|
||||
|
||||
vec3 original_color = texture(SCREEN_TEXTURE, SCREEN_UV).rgb;
|
||||
vec3 final_highlight_color = mix(original_color, highlight_color, highlight_strength);
|
||||
vec3 final_shadow_color = mix(original_color, shadow_color, shadow_strength);
|
||||
vec3 final = original_color;
|
||||
if (highlights_enabled) {
|
||||
final = mix(final, final_highlight_color, normal_diff);
|
||||
}
|
||||
if (shadows_enabled) {
|
||||
final = mix(final, final_shadow_color, depth_diff);
|
||||
}
|
||||
ALBEDO = final;
|
||||
|
||||
float alpha_mask = depth_diff * float(shadows_enabled) + normal_diff * float(highlights_enabled);
|
||||
ALPHA = clamp((alpha_mask) * 5., 0., 1.);
|
||||
}
|
||||
59
assets/Shaders/speedlines.gdshader
Normal file
59
assets/Shaders/speedlines.gdshader
Normal file
@@ -0,0 +1,59 @@
|
||||
shader_type canvas_item;
|
||||
|
||||
|
||||
uniform sampler2D noise: repeat_enable;
|
||||
uniform vec4 line_color: source_color;
|
||||
uniform float line_count: hint_range(0.0, 2.0, 0.05) = 0.5;
|
||||
uniform float line_density: hint_range(0.0, 1.0) = 0.5;
|
||||
uniform float line_faloff: hint_range(0.0, 1.0) = 0.25;
|
||||
uniform float mask_size: hint_range(0.0, 1.0) = 0.1;
|
||||
uniform float mask_edge: hint_range(0.0, 1.0) = 0.5;
|
||||
uniform float animation_speed: hint_range(1.0, 20.0) = 0.5;
|
||||
|
||||
|
||||
|
||||
|
||||
float inv_lerp(float from, float to, float value){
|
||||
return (value - from) / (to - from);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
vec2 polar_coordinates(vec2 uv, vec2 center, float zoom, float repeat)
|
||||
{
|
||||
vec2 dir = uv - center;
|
||||
float radius = length(dir) * 2.0;
|
||||
float angle = atan(dir.y, dir.x) * 1.0/(PI * 2.0);
|
||||
return mod(vec2(radius * zoom, angle * repeat), 1.0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
vec2 rotate_uv(vec2 uv, vec2 pivot, float rotation) {
|
||||
float cosa = cos(rotation);
|
||||
float sina = sin(rotation);
|
||||
uv -= pivot;
|
||||
return vec2(
|
||||
cosa * uv.x - sina * uv.y,
|
||||
cosa * uv.y + sina * uv.x
|
||||
) + pivot;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void fragment(){
|
||||
vec2 polar_uv = polar_coordinates(rotate_uv(UV, vec2(0.5), floor(fract(TIME) * animation_speed) ) , vec2(0.5), 0.01, line_count);
|
||||
vec3 lines = texture(noise, polar_uv).rgb;
|
||||
|
||||
float mask_value = length(UV - vec2(0.5));
|
||||
float mask = inv_lerp(mask_size, mask_edge, mask_value);
|
||||
float result = 1.0 - (mask * line_density);
|
||||
|
||||
result = smoothstep(result, result + line_faloff, lines.r);
|
||||
|
||||
COLOR.rgb = vec3(line_color.rgb);
|
||||
COLOR.a = min(line_color.a, result);
|
||||
}
|
||||
188
assets/Shaders/toon.gdshader
Normal file
188
assets/Shaders/toon.gdshader
Normal file
@@ -0,0 +1,188 @@
|
||||
// ATTENTION
|
||||
// This shader uses multiple include files! Copying this file alone won't work!
|
||||
// See https://github.com/eldskald/godot4-cel-shader for all the files!
|
||||
|
||||
shader_type spatial;
|
||||
|
||||
#define USE_ALPHA 0
|
||||
#define USE_ALPHA_CUTOFF 0
|
||||
#define USE_EMISSION 0
|
||||
#define USE_REFLECTIONS 0
|
||||
#define USE_NORMAL_MAP 0
|
||||
#define USE_OCCLUSION 0
|
||||
#define USE_ANISOTROPY 0
|
||||
#define USE_BACKLIGHT 0
|
||||
#define USE_REFRACTION 0
|
||||
|
||||
#if USE_ALPHA
|
||||
render_mode depth_draw_always;
|
||||
#endif
|
||||
|
||||
#include "includes/base-cel-shader.gdshaderinc"
|
||||
|
||||
#if USE_EMISSION
|
||||
#include "includes/emission.gdshaderinc"
|
||||
#endif
|
||||
|
||||
#if USE_REFLECTIONS
|
||||
#include "includes/reflections.gdshaderinc"
|
||||
#endif
|
||||
|
||||
#if USE_NORMAL_MAP
|
||||
#include "includes/normal-map.gdshaderinc"
|
||||
#endif
|
||||
|
||||
#if USE_OCCLUSION
|
||||
#include "includes/occlusion.gdshaderinc"
|
||||
#endif
|
||||
|
||||
#if USE_ANISOTROPY
|
||||
#include "includes/anisotropy.gdshaderinc"
|
||||
#endif
|
||||
|
||||
#if USE_BACKLIGHT
|
||||
#include "includes/backlight.gdshaderinc"
|
||||
#endif
|
||||
|
||||
#if USE_REFRACTION
|
||||
#include "includes/refraction.gdshaderinc"
|
||||
#elif !USE_REFRACTION && USE_ALPHA
|
||||
#include "includes/transparency.gdshaderinc"
|
||||
#endif
|
||||
|
||||
group_uniforms BaseProperties;
|
||||
#if USE_ALPHA_CUTOFF
|
||||
uniform float alpha_cutoff: hint_range(0.0, 1.0) = 0.5;
|
||||
#endif
|
||||
uniform vec4 color: source_color = vec4(0.7, 0.12, 0.86, 1.0);
|
||||
uniform sampler2D base_texture: source_color;
|
||||
uniform vec4 specular: source_color = vec4(0.3, 0.3, 0.3, 0.5);
|
||||
uniform sampler2D specular_texture: hint_default_white;
|
||||
uniform vec4 fresnel: source_color = vec4(0.2, 0.2, 0.2, 0.3);
|
||||
uniform sampler2D fresnel_texture: hint_default_white;
|
||||
group_uniforms;
|
||||
|
||||
varying vec3 SPECULAR_COLOR;
|
||||
varying float SPECULAR_AMOUNT2;
|
||||
varying vec3 FRESNEL_COLOR;
|
||||
varying float FRESNEL_AMOUNT;
|
||||
|
||||
group_uniforms Tiling;
|
||||
uniform vec2 uv_scale = vec2(1,1);
|
||||
uniform vec2 uv_offset = vec2(0,0);
|
||||
group_uniforms;
|
||||
|
||||
void vertex() {
|
||||
UV = UV * uv_scale.xy + uv_offset.xy;
|
||||
}
|
||||
|
||||
void fragment() {
|
||||
ALBEDO = color.rgb * texture(base_texture, UV).rgb;
|
||||
#if USE_ALPHA
|
||||
float alpha = color.a * texture(base_texture, UV).a;
|
||||
ALBEDO *= alpha;
|
||||
#elif USE_ALPHA_CUTOFF
|
||||
ALPHA = color.a * texture(base_texture, UV).a;
|
||||
ALPHA_SCISSOR_THRESHOLD = color.a * texture(base_texture, UV).a;
|
||||
#endif
|
||||
|
||||
#if USE_REFRACTION && USE_ALPHA
|
||||
EMISSION += refraction_fragment(alpha, NORMAL, SCREEN_UV, FRAGCOORD.z);
|
||||
#elif !USE_REFRACTION && USE_ALPHA
|
||||
EMISSION += transparency_fragment(alpha, SCREEN_UV);
|
||||
#endif
|
||||
|
||||
SPECULAR_COLOR = specular.rgb * texture(specular_texture, UV).rgb;
|
||||
SPECULAR_AMOUNT2 = specular.a * texture(specular_texture, UV).a;
|
||||
FRESNEL_COLOR = fresnel.rgb * texture(fresnel_texture, UV).rgb;
|
||||
FRESNEL_AMOUNT = fresnel.a * texture(fresnel_texture, UV).a;
|
||||
|
||||
#if USE_EMISSION
|
||||
EMISSION += emission_fragment(UV);
|
||||
#endif
|
||||
|
||||
#if USE_REFLECTIONS
|
||||
Surface surf = reflections_fragment(UV);
|
||||
METALLIC = surf.metallic;
|
||||
ROUGHNESS = surf.roughness;
|
||||
#endif
|
||||
|
||||
#if USE_NORMAL_MAP
|
||||
NormalData normal = normal_map_fragment(UV, NORMAL, TANGENT, BINORMAL);
|
||||
NORMAL = normal.vector;
|
||||
NORMAL_MAP = normal.map;
|
||||
NORMAL_MAP_DEPTH = normal.depth;
|
||||
#endif
|
||||
|
||||
#if USE_OCCLUSION
|
||||
OcclusionData occlusion = occlusion_fragment(UV);
|
||||
AO = occlusion.ao;
|
||||
AO_LIGHT_AFFECT = occlusion.ao_light_affect;
|
||||
#endif
|
||||
|
||||
#if USE_ANISOTROPY
|
||||
AnisotropyData aniso = anisotropy_fragment(UV);
|
||||
ANISOTROPY_DIR = aniso.direction;
|
||||
ANISOTROPY_RATIO = aniso.ratio;
|
||||
#endif
|
||||
|
||||
#if USE_BACKLIGHT
|
||||
BACKLIGHT = backlight_fragment(UV);
|
||||
#endif
|
||||
}
|
||||
|
||||
void light() {
|
||||
#if USE_BACKLIGHT
|
||||
DIFFUSE_LIGHT += backlight_diffuse(
|
||||
ALBEDO,
|
||||
LIGHT_COLOR,
|
||||
LIGHT,
|
||||
NORMAL,
|
||||
ATTENUATION,
|
||||
BACKLIGHT
|
||||
);
|
||||
#else
|
||||
DIFFUSE_LIGHT += diffuse_light(
|
||||
ALBEDO,
|
||||
LIGHT_COLOR,
|
||||
LIGHT,
|
||||
NORMAL,
|
||||
ATTENUATION
|
||||
);
|
||||
#endif
|
||||
|
||||
#if USE_ANISOTROPY
|
||||
SPECULAR_LIGHT += anisotropy_specular(
|
||||
LIGHT_COLOR,
|
||||
SPECULAR_COLOR,
|
||||
SPECULAR_AMOUNT,
|
||||
NORMAL,
|
||||
VIEW,
|
||||
LIGHT,
|
||||
ATTENUATION,
|
||||
UV,
|
||||
ANISOTROPY_DIR,
|
||||
ANISOTROPY_RATIO
|
||||
);
|
||||
#else
|
||||
SPECULAR_LIGHT += specular_light(
|
||||
LIGHT_COLOR,
|
||||
SPECULAR_COLOR,
|
||||
SPECULAR_AMOUNT,
|
||||
NORMAL,
|
||||
VIEW,
|
||||
LIGHT,
|
||||
ATTENUATION
|
||||
);
|
||||
#endif
|
||||
|
||||
SPECULAR_LIGHT += fresnel_light(
|
||||
LIGHT_COLOR,
|
||||
FRESNEL_COLOR,
|
||||
FRESNEL_AMOUNT,
|
||||
NORMAL,
|
||||
VIEW,
|
||||
LIGHT,
|
||||
ATTENUATION
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user