Skip to content

Commit

Permalink
replaced decal shader with native one
Browse files Browse the repository at this point in the history
  • Loading branch information
mrDIMAS committed Feb 20, 2025
1 parent b25f2c0 commit 9dcd8c3
Show file tree
Hide file tree
Showing 6 changed files with 179 additions and 196 deletions.
54 changes: 0 additions & 54 deletions fyrox-impl/src/renderer/gbuffer/decal.rs

This file was deleted.

96 changes: 37 additions & 59 deletions fyrox-impl/src/renderer/gbuffer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,23 +39,21 @@ use crate::{
renderer::{
bundle::{BundleRenderContext, RenderDataBundleStorage, SurfaceInstanceData},
cache::{
shader::ShaderCache,
shader::{
binding, property, PropertyGroup, RenderMaterial, RenderPassContainer, ShaderCache,
},
uniform::{UniformBufferCache, UniformMemoryAllocator},
},
debug_renderer::DebugRenderer,
framework::{
buffer::BufferUsage,
error::FrameworkError,
framebuffer::{
Attachment, AttachmentKind, BufferLocation, ResourceBindGroup, ResourceBinding,
},
gpu_texture::PixelKind,
framebuffer::{Attachment, AttachmentKind, GpuFrameBuffer},
geometry_buffer::GpuGeometryBuffer,
gpu_texture::{GpuTexture, PixelKind},
server::GraphicsServer,
uniform::StaticUniformBuffer,
BlendFactor, BlendFunc, BlendParameters, DrawParameters, ElementRange,
GeometryBufferExt,
},
gbuffer::decal::DecalShader,
occlusion::OcclusionTester,
FallbackResources, GeometryCache, QualitySettings, RenderPassStatistics, TextureCache,
},
Expand All @@ -67,19 +65,14 @@ use crate::{
},
};
use fxhash::FxHashSet;
use fyrox_graphics::framebuffer::GpuFrameBuffer;
use fyrox_graphics::geometry_buffer::GpuGeometryBuffer;
use fyrox_graphics::gpu_texture::GpuTexture;

mod decal;

pub struct GBuffer {
framebuffer: GpuFrameBuffer,
decal_framebuffer: GpuFrameBuffer,
pub width: i32,
pub height: i32,
cube: GpuGeometryBuffer,
decal_shader: DecalShader,
decal_shader: RenderPassContainer,
render_pass_name: ImmutableString,
occlusion_tester: OcclusionTester,
}
Expand Down Expand Up @@ -156,7 +149,10 @@ impl GBuffer {
framebuffer,
width: width as i32,
height: height as i32,
decal_shader: DecalShader::new(server)?,
decal_shader: RenderPassContainer::from_str(
server,
include_str!("../shaders/decal.shader"),
)?,
cube: GpuGeometryBuffer::from_surface_data(
&SurfaceData::make_cube(Matrix4::identity()),
BufferUsage::StaticDraw,
Expand Down Expand Up @@ -292,9 +288,6 @@ impl GBuffer {
// decals do not modify depth (only diffuse and normal maps).
let unit_cube = &self.cube;
for decal in graph.linear_iter().filter_map(|n| n.cast::<Decal>()) {
let shader = &self.decal_shader;
let program = &self.decal_shader.program;

let world_view_proj = view_projection * decal.global_transform();

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

statistics += self.decal_framebuffer.draw(
let inv_world_decal = decal.global_transform().try_inverse().unwrap_or_default();
let color = decal.color().srgb_to_linear_f32();
let layer_index = decal.layer() as u32;
let properties = PropertyGroup::from([
property("worldViewProjection", &world_view_proj),
property("invViewProj", &inv_view_proj),
property("invWorldDecal", &inv_world_decal),
property("resolution", &resolution),
property("color", &color),
property("layerIndex", &layer_index),
]);
let material = RenderMaterial::from([
binding("sceneDepth", depth),
binding("diffuseTexture", &diffuse_texture),
binding("normalTexture", &normal_texture),
binding("decalMask", decal_mask),
binding("properties", &properties),
]);

statistics += self.decal_shader.run_pass(
&ImmutableString::new("Primary"),
&self.decal_framebuffer,
unit_cube,
viewport,
program,
&DrawParameters {
cull_face: None,
color_write: Default::default(),
depth_write: false,
stencil_test: None,
depth_test: None,
blend: Some(BlendParameters {
func: BlendFunc::new(BlendFactor::SrcAlpha, BlendFactor::OneMinusSrcAlpha),
..Default::default()
}),
stencil_op: Default::default(),
scissor_box: None,
},
&[ResourceBindGroup {
bindings: &[
ResourceBinding::texture(depth, &shader.scene_depth),
ResourceBinding::texture(&diffuse_texture, &shader.diffuse_texture),
ResourceBinding::texture(&normal_texture, &shader.normal_texture),
ResourceBinding::texture(decal_mask, &shader.decal_mask),
ResourceBinding::Buffer {
buffer: uniform_buffer_cache.write(
StaticUniformBuffer::<256>::new()
.with(&world_view_proj)
.with(&inv_view_proj)
.with(
&decal.global_transform().try_inverse().unwrap_or_default(),
)
.with(&resolution)
.with(&decal.color().srgb_to_linear_f32())
.with(&(decal.layer() as u32)),
)?,
binding: BufferLocation::Auto {
shader_location: shader.uniform_buffer_binding,
},
data_usage: Default::default(),
},
],
}],
ElementRange::Full,
&material,
uniform_buffer_cache,
Default::default(),
None,
)?;
}

Expand Down
141 changes: 141 additions & 0 deletions fyrox-impl/src/renderer/shaders/decal.shader
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
(
name: "Decal",
resources: [
(
name: "sceneDepth",
kind: Texture(kind: Sampler2D, fallback: White),
binding: 0
),
(
name: "diffuseTexture",
kind: Texture(kind: Sampler2D, fallback: White),
binding: 1
),
(
name: "normalTexture",
kind: Texture(kind: Sampler2D, fallback: White),
binding: 2
),
(
name: "decalMask",
kind: Texture(kind: USampler2D, fallback: White),
binding: 3
),
(
name: "properties",
kind: PropertyGroup([
(name: "worldViewProjection", kind: Matrix4()),
(name: "invViewProj", kind: Matrix4()),
(name: "invWorldDecal", kind: Matrix4()),
(name: "resolution", kind: Vector2()),
(name: "color", kind: Vector4()),
(name: "layerIndex", kind: UInt()),
]),
binding: 0
),
],
passes: [
(
name: "Primary",

draw_parameters: DrawParameters(
cull_face: None,
color_write: ColorMask(
red: true,
green: true,
blue: true,
alpha: true,
),
depth_write: false,
stencil_test: None,
depth_test: None,
blend: Some(BlendParameters(
func: BlendFunc(
sfactor: SrcAlpha,
dfactor: OneMinusSrcAlpha,
alpha_sfactor: SrcAlpha,
alpha_dfactor: OneMinusSrcAlpha,
),
equation: BlendEquation(
rgb: Add,
alpha: Add
)
)),
stencil_op: StencilOp(
fail: Keep,
zfail: Keep,
zpass: Keep,
write_mask: 0xFFFF_FFFF,
),
scissor_box: None
),

vertex_shader:
r#"
layout (location = 0) in vec3 vertexPosition;

out vec4 clipSpacePosition;

void main()
{
gl_Position = properties.worldViewProjection * vec4(vertexPosition, 1.0);
clipSpacePosition = gl_Position;
}
"#,

fragment_shader:
r#"
layout (location = 0) out vec4 outDiffuseMap;
layout (location = 1) out vec4 outNormalMap;

in vec4 clipSpacePosition;

void main()
{
vec2 screenPos = clipSpacePosition.xy / clipSpacePosition.w;

vec2 texCoord = vec2(
(1.0 + screenPos.x) / 2.0 + (0.5 / properties.resolution.x),
(1.0 + screenPos.y) / 2.0 + (0.5 / properties.resolution.y)
);

uvec4 maskIndex = texture(decalMask, texCoord);

// Masking.
if (maskIndex.r != properties.layerIndex) {
discard;
}

float sceneDepth = texture(sceneDepth, texCoord).r;

vec3 sceneWorldPosition = S_UnProject(vec3(texCoord, sceneDepth), properties.invViewProj);

vec3 decalSpacePosition = (properties.invWorldDecal * vec4(sceneWorldPosition, 1.0)).xyz;

// Check if scene pixel is not inside decal bounds.
vec3 dpos = vec3(0.5) - abs(decalSpacePosition.xyz);
if (dpos.x < 0.0 || dpos.y < 0.0 || dpos.z < 0.0) {
discard;
}

vec2 decalTexCoord = decalSpacePosition.xz + 0.5;

outDiffuseMap = properties.color * texture(diffuseTexture, decalTexCoord);

vec3 fragmentTangent = dFdx(sceneWorldPosition);
vec3 fragmentBinormal = dFdy(sceneWorldPosition);
vec3 fragmentNormal = cross(fragmentTangent, fragmentBinormal);

mat3 tangentToWorld;
tangentToWorld[0] = normalize(fragmentTangent); // Tangent
tangentToWorld[1] = normalize(fragmentBinormal); // Binormal
tangentToWorld[2] = normalize(fragmentNormal); // Normal

vec3 rawNormal = (texture(normalTexture, decalTexCoord) * 2.0 - 1.0).xyz;
vec3 worldSpaceNormal = tangentToWorld * rawNormal;
outNormalMap = vec4(worldSpaceNormal * 0.5 + 0.5, outDiffuseMap.a);
}
"#,
)
]
)
Loading

0 comments on commit 9dcd8c3

Please sign in to comment.