Skip to content

Commit

Permalink
[gbuffer] removed specular anti-aliasing since it costs a bit and it'…
Browse files Browse the repository at this point in the history
…s not needed as FSR/TAA cleans it up completely and retains more specular detal
  • Loading branch information
PanosK92 committed Oct 25, 2024
1 parent 79b8f18 commit d6b5d10
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 90 deletions.
2 changes: 1 addition & 1 deletion data/shaders/depth_prepass.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ void main_ps(gbuffer_vertex vertex)
const bool has_albedo = f3_value.y == 1.0f;
const float alpha = f3_value.z;

float alpha_threshold = get_alpha_threshold(vertex.position);
float alpha_threshold = get_alpha_threshold(vertex.position); // distance based alpha threshold
bool mask_alpha = has_alpha_mask && GET_TEXTURE(material_mask).Sample(samplers[sampler_point_wrap], vertex.uv).r <= alpha_threshold;
bool mask_albedo = alpha == 1.0f && has_albedo && GET_TEXTURE(material_albedo).Sample(samplers[sampler_anisotropic_wrap], vertex.uv).a <= alpha_threshold;

Expand Down
124 changes: 51 additions & 73 deletions data/shaders/g_buffer.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "common.hlsl"
//====================

static const float g_quality_max_distance = 500.0f;

struct gbuffer
{
float4 albedo : SV_Target0;
Expand All @@ -48,14 +46,17 @@ gbuffer_vertex main_vs(Vertex_PosUvNorTan input, uint instance_id : SV_InstanceI

gbuffer main_ps(gbuffer_vertex vertex)
{
float4 albedo = GetMaterial().color;
float3 normal = vertex.normal.xyz;
float roughness = GetMaterial().roughness;
float metalness = GetMaterial().metallness;
float occlusion = 1.0f;
float emission = 0.0f;
float2 velocity = 0.0f;

// setup
float4 albedo = GetMaterial().color;
float3 normal = vertex.normal.xyz;
float roughness = GetMaterial().roughness;
float metalness = GetMaterial().metallness;
float occlusion = 1.0f;
float emission = 0.0f;
float2 velocity = 0.0f;
Material material = GetMaterial();
Surface surface; surface.flags = material.flags;

// velocity
{
// convert to ndc
Expand All @@ -70,9 +71,6 @@ gbuffer main_ps(gbuffer_vertex vertex)
velocity = ndc_to_uv(position_ndc_current) - ndc_to_uv(position_ndc_previous);
}

Material material = GetMaterial();
Surface surface; surface.flags = material.flags;

// alpha mask
float alpha_mask = 1.0f;
if (surface.has_texture_alpha_mask())
Expand All @@ -99,73 +97,53 @@ gbuffer main_ps(gbuffer_vertex vertex)
albedo.a = 1.0f;
}

// compute pixel distance
float3 camera_to_pixel_world = buffer_frame.camera_position - vertex.position.xyz;
float pixel_distance = length(camera_to_pixel_world);

if (pixel_distance < g_quality_max_distance)
// normal mapping
if (surface.has_texture_normal())
{
// normal mapping
if (surface.has_texture_normal())
// get tangent space normal and apply the user defined intensity, then transform it to world space
float3 normal_sample = sampling::smart(surface, vertex, material_normal).xyz;
float3 tangent_normal = normalize(unpack(normal_sample));

// reconstruct z-component as this can be a BC5 two channel normal map
tangent_normal.z = sqrt(max(0.0, 1.0 - tangent_normal.x * tangent_normal.x - tangent_normal.y * tangent_normal.y));

float normal_intensity = max(0.012f, GetMaterial().normal);
tangent_normal.xy *= saturate(normal_intensity);
float3x3 tangent_to_world = make_tangent_to_world_matrix(vertex.normal, vertex.tangent);
normal = normalize(mul(tangent_normal, tangent_to_world).xyz);
}

// roughness + metalness
{
float4 roughness_sample = 1.0f;
if (surface.has_texture_roughness())
{
// get tangent space normal and apply the user defined intensity, then transform it to world space
float3 normal_sample = sampling::smart(surface, vertex, material_normal).xyz;
float3 tangent_normal = normalize(unpack(normal_sample));
roughness_sample = sampling::smart(surface, vertex, material_roughness);
roughness *= roughness_sample.g;
}

// reconstruct z-component as this can be a BC5 two channel normal map
tangent_normal.z = sqrt(max(0.0, 1.0 - tangent_normal.x * tangent_normal.x - tangent_normal.y * tangent_normal.y));
float is_single_texture_roughness_metalness = surface.has_single_texture_roughness_metalness() ? 1.0f : 0.0f;
metalness *= (1.0 - is_single_texture_roughness_metalness) + (roughness_sample.b * is_single_texture_roughness_metalness);

float normal_intensity = max(0.012f, GetMaterial().normal);
tangent_normal.xy *= saturate(normal_intensity);
float3x3 tangent_to_world = make_tangent_to_world_matrix(vertex.normal, vertex.tangent);
normal = normalize(mul(tangent_normal, tangent_to_world).xyz);
}

// roughness + metalness
if (surface.has_texture_metalness() && !surface.has_single_texture_roughness_metalness())
{
float4 roughness_sample = 1.0f;
if (surface.has_texture_roughness())
{
roughness_sample = sampling::smart(surface, vertex, material_roughness);
roughness *= roughness_sample.g;
}

float is_single_texture_roughness_metalness = surface.has_single_texture_roughness_metalness() ? 1.0f : 0.0f;
metalness *= (1.0 - is_single_texture_roughness_metalness) + (roughness_sample.b * is_single_texture_roughness_metalness);

if (surface.has_texture_metalness() && !surface.has_single_texture_roughness_metalness())
{
metalness *= sampling::smart(surface, vertex, material_metalness).r;
}
}

// occlusion
if (surface.has_texture_occlusion())
{
occlusion = sampling::smart(surface, vertex, material_occlusion).r;
}

// emission
if (surface.has_texture_emissive())
{
float3 emissive_color = GET_TEXTURE(material_emission).Sample(GET_SAMPLER(sampler_anisotropic_wrap), vertex.uv).rgb;
emission = luminance(emissive_color);
albedo.rgb += emissive_color;
}

// specular anti-aliasing
{
static const float strength = 1.0f;
static const float max_roughness_gain = 0.02f;

float roughness2 = roughness * roughness;
float3 dndu = ddx(normal), dndv = ddy(normal);
float variance = (dot(dndu, dndu) + dot(dndv, dndv));
float kernelRoughness2 = min(variance * strength, max_roughness_gain);
float filteredRoughness2 = saturate(roughness2 + kernelRoughness2);
roughness = fast_sqrt(filteredRoughness2);
metalness *= sampling::smart(surface, vertex, material_metalness).r;
}
}

// occlusion
if (surface.has_texture_occlusion())
{
occlusion = sampling::smart(surface, vertex, material_occlusion).r;
}

// emission
if (surface.has_texture_emissive())
{
float3 emissive_color = GET_TEXTURE(material_emission).Sample(GET_SAMPLER(sampler_anisotropic_wrap), vertex.uv).rgb;
emission = luminance(emissive_color);
albedo.rgb += emissive_color;
}

// write to g-buffer
gbuffer g_buffer;
Expand Down
32 changes: 16 additions & 16 deletions runtime/Resource/Import/ModelImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ namespace Spartan
bool model_is_gltf = false;
const aiScene* scene = nullptr;

Matrix convert_matrix(const aiMatrix4x4& transform)
Matrix to_matrix(const aiMatrix4x4& transform)
{
return Matrix
(
Expand All @@ -66,43 +66,43 @@ namespace Spartan
);
}

Color convert_color(const aiColor4D& ai_color)
Color to_color(const aiColor4D& ai_color)
{
return Color(ai_color.r, ai_color.g, ai_color.b, ai_color.a);
}

Color convert_color(const aiColor3D& ai_color)
Color to_color(const aiColor3D& ai_color)
{
return Color(ai_color.r, ai_color.g, ai_color.b, 1.0f);
}

Vector3 convert_vector3(const aiVector3D& ai_vector)
Vector3 to_vector3(const aiVector3D& ai_vector)
{
return Vector3(ai_vector.x, ai_vector.y, ai_vector.z);
}

Vector2 convert_vector2(const aiVector2D& ai_vector)
Vector2 to_vector2(const aiVector2D& ai_vector)
{
return Vector2(ai_vector.x, ai_vector.y);
}

Quaternion convert_quaternion(const aiQuaternion& ai_quaternion)
Quaternion to_quaternion(const aiQuaternion& ai_quaternion)
{
return Quaternion(ai_quaternion.x, ai_quaternion.y, ai_quaternion.z, ai_quaternion.w);
}

void set_entity_transform(const aiNode* node, shared_ptr<Entity> entity)
{
// convert to engine matrix
const Matrix matrix_engine = convert_matrix(node->mTransformation);
const Matrix matrix_engine = to_matrix(node->mTransformation);

// apply position, rotation and scale
entity->SetPositionLocal(matrix_engine.GetTranslation());
entity->SetRotationLocal(matrix_engine.GetRotation());
entity->SetScaleLocal(matrix_engine.GetScale());
}

constexpr void compute_node_count(const aiNode* node, uint32_t* count)
void compute_node_count(const aiNode* node, uint32_t* count)
{
if (!node)
return;
Expand Down Expand Up @@ -608,11 +608,11 @@ namespace Spartan
light->SetFlag(LightFlags::Volumetric, false);

// local transform
light->GetEntity()->SetPositionLocal(convert_vector3(light_assimp->mPosition));
light->GetEntity()->SetRotationLocal(Quaternion::FromLookRotation(convert_vector3(light_assimp->mDirection)));
light->GetEntity()->SetPositionLocal(to_vector3(light_assimp->mPosition));
light->GetEntity()->SetRotationLocal(Quaternion::FromLookRotation(to_vector3(light_assimp->mDirection)));

// color
light->SetColor(convert_color(light_assimp->mColorDiffuse));
light->SetColor(to_color(light_assimp->mColorDiffuse));

// type
if (light_assimp->mType == aiLightSource_DIRECTIONAL)
Expand Down Expand Up @@ -644,7 +644,7 @@ namespace Spartan
const uint32_t index_count = assimp_mesh->mNumFaces * 3;

// vertices
vector<RHI_Vertex_PosTexNorTan> vertices = vector<RHI_Vertex_PosTexNorTan>(vertex_count);
vector<RHI_Vertex_PosTexNorTan> vertices(vertex_count);
{
for (uint32_t i = 0; i < vertex_count; i++)
{
Expand Down Expand Up @@ -686,7 +686,7 @@ namespace Spartan
}

// indices
vector<uint32_t> indices = vector<uint32_t>(index_count);
vector<uint32_t> indices(index_count);
{
// get indices by iterating through each face of the mesh.
for (uint32_t face_index = 0; face_index < assimp_mesh->mNumFaces; face_index++)
Expand Down Expand Up @@ -762,7 +762,7 @@ namespace Spartan
for (uint32_t k = 0; k < static_cast<uint32_t>(assimp_node_anim->mNumPositionKeys); k++)
{
const auto time = assimp_node_anim->mPositionKeys[k].mTime;
const auto value = convert_vector3(assimp_node_anim->mPositionKeys[k].mValue);
const auto value = to_vector3(assimp_node_anim->mPositionKeys[k].mValue);

animation_node.positionFrames.emplace_back(KeyVector{ time, value });
}
Expand All @@ -771,7 +771,7 @@ namespace Spartan
for (uint32_t k = 0; k < static_cast<uint32_t>(assimp_node_anim->mNumRotationKeys); k++)
{
const auto time = assimp_node_anim->mPositionKeys[k].mTime;
const auto value = convert_quaternion(assimp_node_anim->mRotationKeys[k].mValue);
const auto value = to_quaternion(assimp_node_anim->mRotationKeys[k].mValue);

animation_node.rotationFrames.emplace_back(KeyQuaternion{ time, value });
}
Expand All @@ -780,7 +780,7 @@ namespace Spartan
for (uint32_t k = 0; k < static_cast<uint32_t>(assimp_node_anim->mNumScalingKeys); k++)
{
const auto time = assimp_node_anim->mPositionKeys[k].mTime;
const auto value = convert_vector3(assimp_node_anim->mScalingKeys[k].mValue);
const auto value = to_vector3(assimp_node_anim->mScalingKeys[k].mValue);

animation_node.scaleFrames.emplace_back(KeyVector{ time, value });
}
Expand Down

0 comments on commit d6b5d10

Please sign in to comment.