Skip to content

Commit 9dcd8c3

Browse files
committed
replaced decal shader with native one
1 parent b25f2c0 commit 9dcd8c3

File tree

6 files changed

+179
-196
lines changed

6 files changed

+179
-196
lines changed

fyrox-impl/src/renderer/gbuffer/decal.rs

Lines changed: 0 additions & 54 deletions
This file was deleted.

fyrox-impl/src/renderer/gbuffer/mod.rs

Lines changed: 37 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -39,23 +39,21 @@ use crate::{
3939
renderer::{
4040
bundle::{BundleRenderContext, RenderDataBundleStorage, SurfaceInstanceData},
4141
cache::{
42-
shader::ShaderCache,
42+
shader::{
43+
binding, property, PropertyGroup, RenderMaterial, RenderPassContainer, ShaderCache,
44+
},
4345
uniform::{UniformBufferCache, UniformMemoryAllocator},
4446
},
4547
debug_renderer::DebugRenderer,
4648
framework::{
4749
buffer::BufferUsage,
4850
error::FrameworkError,
49-
framebuffer::{
50-
Attachment, AttachmentKind, BufferLocation, ResourceBindGroup, ResourceBinding,
51-
},
52-
gpu_texture::PixelKind,
51+
framebuffer::{Attachment, AttachmentKind, GpuFrameBuffer},
52+
geometry_buffer::GpuGeometryBuffer,
53+
gpu_texture::{GpuTexture, PixelKind},
5354
server::GraphicsServer,
54-
uniform::StaticUniformBuffer,
55-
BlendFactor, BlendFunc, BlendParameters, DrawParameters, ElementRange,
5655
GeometryBufferExt,
5756
},
58-
gbuffer::decal::DecalShader,
5957
occlusion::OcclusionTester,
6058
FallbackResources, GeometryCache, QualitySettings, RenderPassStatistics, TextureCache,
6159
},
@@ -67,19 +65,14 @@ use crate::{
6765
},
6866
};
6967
use fxhash::FxHashSet;
70-
use fyrox_graphics::framebuffer::GpuFrameBuffer;
71-
use fyrox_graphics::geometry_buffer::GpuGeometryBuffer;
72-
use fyrox_graphics::gpu_texture::GpuTexture;
73-
74-
mod decal;
7568

7669
pub struct GBuffer {
7770
framebuffer: GpuFrameBuffer,
7871
decal_framebuffer: GpuFrameBuffer,
7972
pub width: i32,
8073
pub height: i32,
8174
cube: GpuGeometryBuffer,
82-
decal_shader: DecalShader,
75+
decal_shader: RenderPassContainer,
8376
render_pass_name: ImmutableString,
8477
occlusion_tester: OcclusionTester,
8578
}
@@ -156,7 +149,10 @@ impl GBuffer {
156149
framebuffer,
157150
width: width as i32,
158151
height: height as i32,
159-
decal_shader: DecalShader::new(server)?,
152+
decal_shader: RenderPassContainer::from_str(
153+
server,
154+
include_str!("../shaders/decal.shader"),
155+
)?,
160156
cube: GpuGeometryBuffer::from_surface_data(
161157
&SurfaceData::make_cube(Matrix4::identity()),
162158
BufferUsage::StaticDraw,
@@ -292,9 +288,6 @@ impl GBuffer {
292288
// decals do not modify depth (only diffuse and normal maps).
293289
let unit_cube = &self.cube;
294290
for decal in graph.linear_iter().filter_map(|n| n.cast::<Decal>()) {
295-
let shader = &self.decal_shader;
296-
let program = &self.decal_shader.program;
297-
298291
let world_view_proj = view_projection * decal.global_transform();
299292

300293
let diffuse_texture = decal
@@ -309,49 +302,34 @@ impl GBuffer {
309302
.unwrap_or(&fallback_resources.normal_dummy)
310303
.clone();
311304

312-
statistics += self.decal_framebuffer.draw(
305+
let inv_world_decal = decal.global_transform().try_inverse().unwrap_or_default();
306+
let color = decal.color().srgb_to_linear_f32();
307+
let layer_index = decal.layer() as u32;
308+
let properties = PropertyGroup::from([
309+
property("worldViewProjection", &world_view_proj),
310+
property("invViewProj", &inv_view_proj),
311+
property("invWorldDecal", &inv_world_decal),
312+
property("resolution", &resolution),
313+
property("color", &color),
314+
property("layerIndex", &layer_index),
315+
]);
316+
let material = RenderMaterial::from([
317+
binding("sceneDepth", depth),
318+
binding("diffuseTexture", &diffuse_texture),
319+
binding("normalTexture", &normal_texture),
320+
binding("decalMask", decal_mask),
321+
binding("properties", &properties),
322+
]);
323+
324+
statistics += self.decal_shader.run_pass(
325+
&ImmutableString::new("Primary"),
326+
&self.decal_framebuffer,
313327
unit_cube,
314328
viewport,
315-
program,
316-
&DrawParameters {
317-
cull_face: None,
318-
color_write: Default::default(),
319-
depth_write: false,
320-
stencil_test: None,
321-
depth_test: None,
322-
blend: Some(BlendParameters {
323-
func: BlendFunc::new(BlendFactor::SrcAlpha, BlendFactor::OneMinusSrcAlpha),
324-
..Default::default()
325-
}),
326-
stencil_op: Default::default(),
327-
scissor_box: None,
328-
},
329-
&[ResourceBindGroup {
330-
bindings: &[
331-
ResourceBinding::texture(depth, &shader.scene_depth),
332-
ResourceBinding::texture(&diffuse_texture, &shader.diffuse_texture),
333-
ResourceBinding::texture(&normal_texture, &shader.normal_texture),
334-
ResourceBinding::texture(decal_mask, &shader.decal_mask),
335-
ResourceBinding::Buffer {
336-
buffer: uniform_buffer_cache.write(
337-
StaticUniformBuffer::<256>::new()
338-
.with(&world_view_proj)
339-
.with(&inv_view_proj)
340-
.with(
341-
&decal.global_transform().try_inverse().unwrap_or_default(),
342-
)
343-
.with(&resolution)
344-
.with(&decal.color().srgb_to_linear_f32())
345-
.with(&(decal.layer() as u32)),
346-
)?,
347-
binding: BufferLocation::Auto {
348-
shader_location: shader.uniform_buffer_binding,
349-
},
350-
data_usage: Default::default(),
351-
},
352-
],
353-
}],
354-
ElementRange::Full,
329+
&material,
330+
uniform_buffer_cache,
331+
Default::default(),
332+
None,
355333
)?;
356334
}
357335

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
(
2+
name: "Decal",
3+
resources: [
4+
(
5+
name: "sceneDepth",
6+
kind: Texture(kind: Sampler2D, fallback: White),
7+
binding: 0
8+
),
9+
(
10+
name: "diffuseTexture",
11+
kind: Texture(kind: Sampler2D, fallback: White),
12+
binding: 1
13+
),
14+
(
15+
name: "normalTexture",
16+
kind: Texture(kind: Sampler2D, fallback: White),
17+
binding: 2
18+
),
19+
(
20+
name: "decalMask",
21+
kind: Texture(kind: USampler2D, fallback: White),
22+
binding: 3
23+
),
24+
(
25+
name: "properties",
26+
kind: PropertyGroup([
27+
(name: "worldViewProjection", kind: Matrix4()),
28+
(name: "invViewProj", kind: Matrix4()),
29+
(name: "invWorldDecal", kind: Matrix4()),
30+
(name: "resolution", kind: Vector2()),
31+
(name: "color", kind: Vector4()),
32+
(name: "layerIndex", kind: UInt()),
33+
]),
34+
binding: 0
35+
),
36+
],
37+
passes: [
38+
(
39+
name: "Primary",
40+
41+
draw_parameters: DrawParameters(
42+
cull_face: None,
43+
color_write: ColorMask(
44+
red: true,
45+
green: true,
46+
blue: true,
47+
alpha: true,
48+
),
49+
depth_write: false,
50+
stencil_test: None,
51+
depth_test: None,
52+
blend: Some(BlendParameters(
53+
func: BlendFunc(
54+
sfactor: SrcAlpha,
55+
dfactor: OneMinusSrcAlpha,
56+
alpha_sfactor: SrcAlpha,
57+
alpha_dfactor: OneMinusSrcAlpha,
58+
),
59+
equation: BlendEquation(
60+
rgb: Add,
61+
alpha: Add
62+
)
63+
)),
64+
stencil_op: StencilOp(
65+
fail: Keep,
66+
zfail: Keep,
67+
zpass: Keep,
68+
write_mask: 0xFFFF_FFFF,
69+
),
70+
scissor_box: None
71+
),
72+
73+
vertex_shader:
74+
r#"
75+
layout (location = 0) in vec3 vertexPosition;
76+
77+
out vec4 clipSpacePosition;
78+
79+
void main()
80+
{
81+
gl_Position = properties.worldViewProjection * vec4(vertexPosition, 1.0);
82+
clipSpacePosition = gl_Position;
83+
}
84+
"#,
85+
86+
fragment_shader:
87+
r#"
88+
layout (location = 0) out vec4 outDiffuseMap;
89+
layout (location = 1) out vec4 outNormalMap;
90+
91+
in vec4 clipSpacePosition;
92+
93+
void main()
94+
{
95+
vec2 screenPos = clipSpacePosition.xy / clipSpacePosition.w;
96+
97+
vec2 texCoord = vec2(
98+
(1.0 + screenPos.x) / 2.0 + (0.5 / properties.resolution.x),
99+
(1.0 + screenPos.y) / 2.0 + (0.5 / properties.resolution.y)
100+
);
101+
102+
uvec4 maskIndex = texture(decalMask, texCoord);
103+
104+
// Masking.
105+
if (maskIndex.r != properties.layerIndex) {
106+
discard;
107+
}
108+
109+
float sceneDepth = texture(sceneDepth, texCoord).r;
110+
111+
vec3 sceneWorldPosition = S_UnProject(vec3(texCoord, sceneDepth), properties.invViewProj);
112+
113+
vec3 decalSpacePosition = (properties.invWorldDecal * vec4(sceneWorldPosition, 1.0)).xyz;
114+
115+
// Check if scene pixel is not inside decal bounds.
116+
vec3 dpos = vec3(0.5) - abs(decalSpacePosition.xyz);
117+
if (dpos.x < 0.0 || dpos.y < 0.0 || dpos.z < 0.0) {
118+
discard;
119+
}
120+
121+
vec2 decalTexCoord = decalSpacePosition.xz + 0.5;
122+
123+
outDiffuseMap = properties.color * texture(diffuseTexture, decalTexCoord);
124+
125+
vec3 fragmentTangent = dFdx(sceneWorldPosition);
126+
vec3 fragmentBinormal = dFdy(sceneWorldPosition);
127+
vec3 fragmentNormal = cross(fragmentTangent, fragmentBinormal);
128+
129+
mat3 tangentToWorld;
130+
tangentToWorld[0] = normalize(fragmentTangent); // Tangent
131+
tangentToWorld[1] = normalize(fragmentBinormal); // Binormal
132+
tangentToWorld[2] = normalize(fragmentNormal); // Normal
133+
134+
vec3 rawNormal = (texture(normalTexture, decalTexCoord) * 2.0 - 1.0).xyz;
135+
vec3 worldSpaceNormal = tangentToWorld * rawNormal;
136+
outNormalMap = vec4(worldSpaceNormal * 0.5 + 0.5, outDiffuseMap.a);
137+
}
138+
"#,
139+
)
140+
]
141+
)

0 commit comments

Comments
 (0)