From fb48528cbb1881ff8ac96a1cd05c2c7aa326b203 Mon Sep 17 00:00:00 2001 From: yum Date: Tue, 11 Nov 2025 16:20:14 -0800 Subject: add detail map feature --- 3ner.shader | 60 +++++++++++++++++++++++++++++++++------------------------- features.cginc | 4 ++++ globals.cginc | 9 +++++++++ lighting.cginc | 10 +++++----- math.cginc | 10 ++++++++++ pbr.cginc | 11 +++++++++++ 6 files changed, 73 insertions(+), 31 deletions(-) diff --git a/3ner.shader b/3ner.shader index 11f7d87..0fcf7a0 100644 --- a/3ner.shader +++ b/3ner.shader @@ -28,15 +28,27 @@ Shader "yum_food/3ner" }]}]}", Int) = 0 [HideInInspector] m_start_Main("Main", Float) = 0 - _MainTex("Base color", 2D) = "white" {} - _Color("Tint", Color) = (1, 1, 1, 1) - - _BumpMap("Normal", 2D) = "bump" {} - _BumpScale("Normal Scale", Float) = 1 - - _MetallicGlossMap("Metallic (r) smoothness (a)", 2D) = "white" {} - _Metallic("Metallic", Range(0, 1)) = 0 - _Glossiness("Smoothness", Range(0, 1)) = 0.5 + _MainTex("Base color", 2D) = "white" {} + _Color("Tint", Color) = (1, 1, 1, 1) + + _BumpMap("Normal", 2D) = "bump" {} + _BumpScale("Normal Scale", Float) = 1 + + _MetallicGlossMap("Metallic (r) smoothness (a)", 2D) = "white" {} + _Metallic("Metallic", Range(0, 1)) = 0 + _Glossiness("Smoothness", Range(0, 1)) = 0.5 + + //ifex _Details_Enabled==0 + [HideInInspector] m_start_Details("Details", Float) = 0 + [HideInInspector] m_start_Details_Enabled("Details Enabled", Float) = 0 + [ThryToggle(_DETAILS)] _Details_Enabled("Enable", Float) = 0 + _DetailNormalMap("Normal", 2D) = "bump" {} + _DetailNormalMapScale("Normal Scale", Float) = 1 + _DetailMask("Mask", 2D) = "white" {} + [IntRange] _Details_UV_Channel("UV Channel", Range(0, 3)) = 0 + [HideInInspector] m_end_Details_Enabled("Details Enabled", Float) = 0 + [HideInInspector] m_end_Details("Details", Float) = 0 + //endex [HideInInspector] m_end_Main("Main", Float) = 0 [HideInInspector] m_start_Gimmicks("Gimmicks", Float) = 0 @@ -82,7 +94,6 @@ Shader "yum_food/3ner" //endex [HideInInspector] m_start_Ray_Marching_Instancing("Instancing and domain repetition", Float) = 0 - //ifex _Ray_Marching_Cart_Instancing_Enabled==0 [HideInInspector] m_start_Ray_Marching_Cart_Instancing("Cartesian Instancing", Float) = 0 [ThryToggle(_RAY_MARCHING_CART_INSTANCING)] _Ray_Marching_Cart_Instancing_Enabled("Enable", Float) = 0 @@ -153,8 +164,6 @@ Shader "yum_food/3ner" //endex [HideInInspector] m_end_Ray_Marching_Primitives("Primitives", Float) = 0 - [HideInInspector] m_end_Ray_Marching_Primitives("Primitives", Float) = 0 - [HideInInspector] m_end_Ray_Marching("Ray Marching", Float) = 0 //endex @@ -260,22 +269,21 @@ Shader "yum_food/3ner" [HideInInspector] m_end_Marble("Marble", Float) = 0 //endex - //endex [HideInInspector] m_end_Gimmicks("Gimmicks", Float) = 0 - //ifex _Tessellation_Enabled==0 - [HideInInspector] m_start_Tessellation("Tessellation", Float) = 0 - [ThryToggle(_TESSELLATION)] _Tessellation_Enabled("Enable", Float) = 0 - _Tessellation_Factor("Factor", Range(1, 64)) = 1 - _Tessellation_Frustum_Culling_Bias("Frustum culling bias", Float) = 35 - _Tessellation_Falloff_Factor("Falloff factor", Float) = 0.05 - // Shit for thry - [HideInInspector] Tessellation_Enabled("Enabled", Float) = 1 - [HideInInspector] Tessellation_EnabledForwardBase("Enabled (ForwardBase)", Float) = 1 - [HideInInspector] Tessellation_EnabledForwardAdd("Enabled (ForwardAdd)", Float) = 1 - [HideInInspector] Tessellation_EnabledShadowCaster("Enabled (ShadowCaster)", Float) = 1 - [HideInInspector] m_end_Tessellation("Tessellation", Float) = 0 - //endex + //ifex _Tessellation_Enabled==0 + [HideInInspector] m_start_Tessellation("Tessellation", Float) = 0 + [ThryToggle(_TESSELLATION)] _Tessellation_Enabled("Enable", Float) = 0 + _Tessellation_Factor("Factor", Range(1, 64)) = 1 + _Tessellation_Frustum_Culling_Bias("Frustum culling bias", Float) = 35 + _Tessellation_Falloff_Factor("Falloff factor", Float) = 0.05 + // Shit for thry + [HideInInspector] Tessellation_Enabled("Enabled", Float) = 1 + [HideInInspector] Tessellation_EnabledForwardBase("Enabled (ForwardBase)", Float) = 1 + [HideInInspector] Tessellation_EnabledForwardAdd("Enabled (ForwardAdd)", Float) = 1 + [HideInInspector] Tessellation_EnabledShadowCaster("Enabled (ShadowCaster)", Float) = 1 + [HideInInspector] m_end_Tessellation("Tessellation", Float) = 0 + //endex [HideInInspector] m_start_Rendering_Options("Rendering Options", Float) = 0 diff --git a/features.cginc b/features.cginc index 8eec291..08d8e3f 100644 --- a/features.cginc +++ b/features.cginc @@ -23,6 +23,10 @@ #pragma shader_feature_local _CLEARCOAT_MASK //endex +//ifex _Details_Enabled==0 +#pragma shader_feature_local _DETAILS +//endex + //ifex _Cloth_Sheen_Enabled==0 #pragma shader_feature_local _CLOTH_SHEEN //endex diff --git a/globals.cginc b/globals.cginc index 063b047..56d9e49 100644 --- a/globals.cginc +++ b/globals.cginc @@ -60,6 +60,15 @@ float4 _Clearcoat_Mask_ST; float _Clearcoat_Mask_Strength; #endif // _CLEARCOAT_MASK +#if defined(_DETAILS) +texture2D _DetailNormalMap; +float4 _DetailNormalMap_ST; +float _DetailNormalMapScale; +texture2D _DetailMask; +float4 _DetailMask_ST; +int _Details_UV_Channel; +#endif // _DETAILS + #if defined(_CLOTH_SHEEN) float _Cloth_Sheen_Strength; float3 _Cloth_Sheen_Color; diff --git a/lighting.cginc b/lighting.cginc index 8276b8c..cb3160a 100644 --- a/lighting.cginc +++ b/lighting.cginc @@ -163,10 +163,6 @@ void GetLighting(v2f i, Pbr pbr, out LightData data) { float3 view_dir = normalize(i.eyeVec.xyz); -#if defined(_CLEARCOAT_MASK) - float cc_mask = _Clearcoat_Mask.Sample(bilinear_clamp_s, i.uv01.xy).r; -#endif - data.common.V = -view_dir; data.common.N = pbr.normal; data.common.NoV = saturate(dot(pbr.normal, data.common.V)); @@ -209,7 +205,11 @@ void GetLighting(v2f i, Pbr pbr, out LightData data) { data.indirect.diffuse = getIndirectDiffuse(i, pbr, data.indirect); data.indirect.specular = getIndirectSpecular(i, pbr.roughness, view_dir, data.indirect.dir); #if defined(_CLEARCOAT) - data.indirect.specular_cc = getIndirectSpecular(i, pbr.cc_roughness, view_dir, dir_cc) * cc_mask; + data.indirect.specular_cc = getIndirectSpecular(i, pbr.cc_roughness, view_dir, dir_cc); +#if defined(_CLEARCOAT_MASK) + float cc_mask = _Clearcoat_Mask.Sample(bilinear_clamp_s, i.uv01.xy).r; + data.indirect.specular_cc *= cc_mask; +#endif #endif } diff --git a/math.cginc b/math.cginc index c37ce07..02d0fe0 100644 --- a/math.cginc +++ b/math.cginc @@ -89,5 +89,15 @@ float3 round_hex(float3 hex_coord) { return rounded; } +// Reoriented normal mapping +// https://blog.selfshadow.com/publications/blending-in-detail/ +// Inputs are in tangent space. +float3 blendNormalsHill12(float3 n0, float3 n1) { + n0.z += 1.0; + n1.xy = -n1.xy; + + return normalize(n0 * dot(n0, n1) - n1 * n0.z); +} + #endif // __MATH_INC diff --git a/pbr.cginc b/pbr.cginc index cb6b079..73ff970 100644 --- a/pbr.cginc +++ b/pbr.cginc @@ -4,6 +4,7 @@ #include "filamented.cginc" #include "globals.cginc" #include "interpolators.cginc" +#include "texture_utils.cginc" struct Pbr { float4 albedo; @@ -63,6 +64,16 @@ Pbr getPbr(v2f i) { float3 normal_tangent = UnpackNormal(_BumpMap.Sample(aniso16_trilinear_repeat_s, i.uv01.xy * _BumpMap_ST.xy)); normal_tangent.xy *= _BumpScale; + +#if defined(_DETAILS) + float2 detail_uv = get_uv_by_channel(i, _Details_UV_Channel); + float3 detail_normal = UnpackNormal(_DetailNormalMap.Sample(aniso16_trilinear_repeat_s, detail_uv * _DetailNormalMap_ST.xy)); + detail_normal.xy *= _DetailNormalMapScale; + float detail_mask = _DetailMask.Sample(aniso16_trilinear_repeat_s, detail_uv * _DetailMask_ST.xy).r; + detail_normal.xy *= detail_mask; + normal_tangent = blendNormalsHill12(normal_tangent, detail_normal); +#endif + // Map from tangent space to world space. float3 bitangent = cross(i.normal, i.tangent.xyz) * i.tangent.w; pbr.tbn = float3x3(i.tangent.xyz, bitangent, i.normal); -- cgit v1.2.3