summaryrefslogtreecommitdiff
path: root/servers/rendering/rasterizer_rd/shaders
diff options
context:
space:
mode:
authorJuan Linietsky <reduzio@gmail.com>2020-04-14 00:05:21 -0300
committerJuan Linietsky <reduzio@gmail.com>2020-04-14 11:13:34 -0300
commit5944eb6e7f4fc6f2a2b3a88032e3195467a12915 (patch)
tree80e38590d93bdb7d7a1c98310c5cc8baa99d64ad /servers/rendering/rasterizer_rd/shaders
parent451d5bd49217e4b55221032e67a7e682e20dad67 (diff)
Implement decals
Also implemented decal atlas, so projectors and other stuff can be added. Sidenote: Had to make RID hashable, so some unrelated includes changed in order to include it in hashfuncs.h
Diffstat (limited to 'servers/rendering/rasterizer_rd/shaders')
-rw-r--r--servers/rendering/rasterizer_rd/shaders/copy.glsl2
-rw-r--r--servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl16
-rw-r--r--servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl85
-rw-r--r--servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl38
4 files changed, 118 insertions, 23 deletions
diff --git a/servers/rendering/rasterizer_rd/shaders/copy.glsl b/servers/rendering/rasterizer_rd/shaders/copy.glsl
index 48c49ff7de..2d7661f65f 100644
--- a/servers/rendering/rasterizer_rd/shaders/copy.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/copy.glsl
@@ -35,7 +35,7 @@ layout(push_constant, binding = 1, std430) uniform Params {
// DOF.
float camera_z_far;
float camera_z_near;
- uvec2 pad2;
+ uint pad2[2];
}
params;
diff --git a/servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl b/servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl
index 1f499cf372..0f8688ee34 100644
--- a/servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl
@@ -13,6 +13,7 @@ layout(push_constant, binding = 1, std430) uniform Params {
vec2 pixel_size;
bool flip_y;
bool use_section;
+
bool force_luminance;
uint pad[3];
}
@@ -23,11 +24,12 @@ void main() {
vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0));
uv_interp = base_arr[gl_VertexIndex];
+ vec2 vpos = uv_interp;
if (params.use_section) {
- uv_interp = params.section.xy + uv_interp * params.section.zw;
+ vpos = params.section.xy + vpos * params.section.zw;
}
- gl_Position = vec4(uv_interp * 2.0 - 1.0, 0.0, 1.0);
+ gl_Position = vec4(vpos * 2.0 - 1.0, 0.0, 1.0);
if (params.flip_y) {
uv_interp.y = 1.0 - uv_interp.y;
@@ -46,8 +48,10 @@ layout(push_constant, binding = 1, std430) uniform Params {
vec2 pixel_size;
bool flip_y;
bool use_section;
+
bool force_luminance;
- uint pad[3];
+ bool alpha_to_zero;
+ uint pad[2];
} params;
@@ -60,9 +64,13 @@ layout(location = 0) out vec4 frag_color;
void main() {
- vec4 color = texture(source_color, uv_interp, 0.0);
+ vec2 uv = uv_interp;
+ vec4 color = textureLod(source_color, uv, 0.0);
if (params.force_luminance) {
color.rgb = vec3(max(max(color.r, color.g), color.b));
}
+ if (params.alpha_to_zero) {
+ color.rgb *= color.a;
+ }
frag_color = color;
}
diff --git a/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl b/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl
index da2c79b271..53e2f3422c 100644
--- a/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl
@@ -20,9 +20,7 @@ layout(location = 2) in vec4 tangent_attrib;
layout(location = 3) in vec4 color_attrib;
#endif
-#if defined(UV_USED)
layout(location = 4) in vec2 uv_attrib;
-#endif
#if defined(UV2_USED) || defined(USE_LIGHTMAP)
layout(location = 5) in vec2 uv2_attrib;
@@ -39,9 +37,7 @@ layout(location = 1) out vec3 normal_interp;
layout(location = 2) out vec4 color_interp;
#endif
-#if defined(UV_USED)
layout(location = 3) out vec2 uv_interp;
-#endif
#if defined(UV2_USED) || defined(USE_LIGHTMAP)
layout(location = 4) out vec2 uv2_interp;
@@ -157,9 +153,7 @@ void main() {
#endif
}
-#if defined(UV_USED)
uv_interp = uv_attrib;
-#endif
#if defined(UV2_USED) || defined(USE_LIGHTMAP)
uv2_interp = uv2_attrib;
@@ -290,9 +284,7 @@ layout(location = 1) in vec3 normal_interp;
layout(location = 2) in vec4 color_interp;
#endif
-#if defined(UV_USED)
layout(location = 3) in vec2 uv_interp;
-#endif
#if defined(UV2_USED) || defined(USE_LIGHTMAP)
layout(location = 4) in vec2 uv2_interp;
@@ -1609,9 +1601,7 @@ void main() {
}
#endif
-#if defined(UV_USED)
vec2 uv = uv_interp;
-#endif
#if defined(UV2_USED) || defined(USE_LIGHTMAP)
vec2 uv2 = uv2_interp;
@@ -1693,7 +1683,80 @@ FRAGMENT_SHADER_CODE
discard;
}
#endif
+ /////////////////////// DECALS ////////////////////////////////
+
+#ifndef MODE_RENDER_DEPTH
+
+ uvec4 cluster_cell = texture(usampler3D(cluster_texture, material_samplers[SAMPLER_NEAREST_CLAMP]), vec3(screen_uv, (abs(vertex.z) - scene_data.z_near) / (scene_data.z_far - scene_data.z_near)));
+
+ { // process decals
+
+ uint decal_count = cluster_cell.w >> CLUSTER_COUNTER_SHIFT;
+ uint decal_pointer = cluster_cell.w & CLUSTER_POINTER_MASK;
+
+ //do outside for performance and avoiding arctifacts
+ vec3 vertex_ddx = dFdx(vertex);
+ vec3 vertex_ddy = dFdy(vertex);
+
+ for (uint i = 0; i < decal_count; i++) {
+
+ uint decal_index = cluster_data.indices[decal_pointer + i];
+ if (!bool(decals.data[decal_index].mask & instances.data[instance_index].layer_mask)) {
+ continue; //not masked
+ }
+
+ vec3 uv_local = (decals.data[decal_index].xform * vec4(vertex, 1.0)).xyz;
+ if (any(lessThan(uv_local, vec3(0.0, -1.0, 0.0))) || any(greaterThan(uv_local, vec3(1.0)))) {
+ continue; //out of decal
+ }
+
+ //we need ddx/ddy for mipmaps, so simulate them
+ vec2 ddx = (decals.data[decal_index].xform * vec4(vertex_ddx, 0.0)).xz;
+ vec2 ddy = (decals.data[decal_index].xform * vec4(vertex_ddy, 0.0)).xz;
+
+ float fade = pow(1.0 - (uv_local.y > 0.0 ? uv_local.y : -uv_local.y), uv_local.y > 0.0 ? decals.data[decal_index].upper_fade : decals.data[decal_index].lower_fade);
+
+ if (decals.data[decal_index].normal_fade > 0.0) {
+ fade *= smoothstep(decals.data[decal_index].normal_fade, 1.0, dot(normal_interp, decals.data[decal_index].normal) * 0.5 + 0.5);
+ }
+
+ if (decals.data[decal_index].albedo_rect != vec4(0.0)) {
+ //has albedo
+ vec4 decal_albedo = textureGrad(sampler2D(decal_atlas_srgb, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].albedo_rect.zw + decals.data[decal_index].albedo_rect.xy, ddx * decals.data[decal_index].albedo_rect.zw, ddy * decals.data[decal_index].albedo_rect.zw);
+ decal_albedo *= decals.data[decal_index].modulate;
+ decal_albedo.a *= fade;
+ albedo = mix(albedo, decal_albedo.rgb, decal_albedo.a * decals.data[decal_index].albedo_mix);
+
+ if (decals.data[decal_index].normal_rect != vec4(0.0)) {
+
+ vec3 decal_normal = textureGrad(sampler2D(decal_atlas, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].normal_rect.zw + decals.data[decal_index].normal_rect.xy, ddx * decals.data[decal_index].normal_rect.zw, ddy * decals.data[decal_index].normal_rect.zw).xyz;
+ decal_normal.xy = decal_normal.xy * vec2(2.0, -2.0) - vec2(1.0, -1.0); //users prefer flipped y normal maps in most authoring software
+ decal_normal.z = sqrt(max(0.0, 1.0 - dot(decal_normal.xy, decal_normal.xy)));
+ //convert to view space, use xzy because y is up
+ decal_normal = (decals.data[decal_index].normal_xform * decal_normal.xzy).xyz;
+
+ normal = normalize(mix(normal, decal_normal, decal_albedo.a));
+ }
+
+ if (decals.data[decal_index].orm_rect != vec4(0.0)) {
+
+ vec3 decal_orm = textureGrad(sampler2D(decal_atlas, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].orm_rect.zw + decals.data[decal_index].orm_rect.xy, ddx * decals.data[decal_index].orm_rect.zw, ddy * decals.data[decal_index].orm_rect.zw).xyz;
+#if defined(AO_USED)
+ ao = mix(ao, decal_orm.r, decal_albedo.a);
+#endif
+ roughness = mix(roughness, decal_orm.g, decal_albedo.a);
+ metallic = mix(metallic, decal_orm.b, decal_albedo.a);
+ }
+ }
+ if (decals.data[decal_index].emission_rect != vec4(0.0)) {
+ //emission is additive, so its independent from albedo
+ emission += textureGrad(sampler2D(decal_atlas_srgb, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].emission_rect.zw + decals.data[decal_index].emission_rect.xy, ddx * decals.data[decal_index].emission_rect.zw, ddy * decals.data[decal_index].emission_rect.zw).xyz * decals.data[decal_index].emission_energy * fade;
+ }
+ }
+ }
+
+#endif //not render depth
/////////////////////// LIGHTING //////////////////////////////
//apply energy conservation
@@ -1798,8 +1861,6 @@ FRAGMENT_SHADER_CODE
}
#endif
- uvec4 cluster_cell = texture(usampler3D(cluster_texture, material_samplers[SAMPLER_NEAREST_CLAMP]), vec3(screen_uv, (abs(vertex.z) - scene_data.z_near) / (scene_data.z_far - scene_data.z_near)));
-
{ // process reflections
vec4 reflection_accum = vec4(0.0, 0.0, 0.0, 0.0);
diff --git a/servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl b/servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl
index 59f326bc9b..358b57c46a 100644
--- a/servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl
@@ -137,7 +137,7 @@ struct InstanceData {
uint layer_mask;
};
-layout(set = 0, binding = 4, std430) buffer Instances {
+layout(set = 0, binding = 4, std430) restrict readonly buffer Instances {
InstanceData data[];
}
instances;
@@ -161,7 +161,7 @@ struct LightData { //this structure needs to be as packed as possible
uint pad[3];
};
-layout(set = 0, binding = 5, std430) buffer Lights {
+layout(set = 0, binding = 5, std430) restrict readonly buffer Lights {
LightData data[];
}
lights;
@@ -248,14 +248,40 @@ layout(set = 0, binding = 9) uniform texture3D gi_probe_textures[MAX_GI_PROBE_TE
#define CLUSTER_POINTER_MASK ((1 << CLUSTER_COUNTER_SHIFT) - 1)
#define CLUSTER_COUNTER_MASK 0xfff
-layout(set = 0, binding = 10) uniform utexture3D cluster_texture;
+layout(set = 0, binding = 10) uniform texture2D decal_atlas;
+layout(set = 0, binding = 11) uniform texture2D decal_atlas_srgb;
+
+struct DecalData {
+ mat4 xform; //to decal transform
+ vec3 inv_extents;
+ float albedo_mix;
+ vec4 albedo_rect;
+ vec4 normal_rect;
+ vec4 orm_rect;
+ vec4 emission_rect;
+ vec4 modulate;
+ float emission_energy;
+ uint mask;
+ float upper_fade;
+ float lower_fade;
+ mat3x4 normal_xform;
+ vec3 normal;
+ float normal_fade;
+};
+
+layout(set = 0, binding = 12, std430) restrict readonly buffer Decals {
+ DecalData data[];
+}
+decals;
+
+layout(set = 0, binding = 13) uniform utexture3D cluster_texture;
-layout(set = 0, binding = 11, std430) buffer ClusterData {
+layout(set = 0, binding = 14, std430) restrict readonly buffer ClusterData {
uint indices[];
}
cluster_data;
-layout(set = 0, binding = 12) uniform texture2D directional_shadow_atlas;
+layout(set = 0, binding = 15) uniform texture2D directional_shadow_atlas;
// decal atlas
@@ -287,7 +313,7 @@ layout(set = 3, binding = 4) uniform texture2D ao_buffer;
/* Set 4 Skeleton & Instancing (Multimesh) */
-layout(set = 4, binding = 0, std430) buffer Transforms {
+layout(set = 4, binding = 0, std430) restrict readonly buffer Transforms {
vec4 data[];
}
transforms;