add aabb cull for mesh, improve NodeEditor view and control

add AO texture
This commit is contained in:
2026-05-17 11:33:56 +08:00
parent f50824bdb1
commit 76ebcc8f66
22 changed files with 530 additions and 154 deletions

View File

@ -130,6 +130,7 @@ uniform sampler2D u_AlbedoTexture;
uniform sampler2D u_NormalTexture;
uniform sampler2D u_MetalnessTexture;
uniform sampler2D u_RoughnessTexture;
uniform sampler2D u_AOTexture;
// environment
uniform samplerCube u_EnvRadianceTex;
@ -146,12 +147,14 @@ uniform float u_EnvMapRotation;
uniform vec4 u_AlbedoColor;
uniform float u_Metalness;
uniform float u_Roughness;
uniform float u_AO;
// textureToggle
uniform float u_AlbedoTexToggle;
uniform float u_NormalTexToggle;
uniform float u_MetalnessTexToggle;
uniform float u_RoughnessTexToggle;
uniform float u_AOTexToggle;
// shadow
const int CSM_CASCADE_COUNT = 4;
@ -485,6 +488,8 @@ void main()
m_Params.Roughness = u_RoughnessTexToggle > 0.5 ? texture(u_RoughnessTexture, vs_Input.TexCoord).r : u_Roughness;
m_Params.Roughness = max(m_Params.Roughness, 0.05);
float ao = u_AOTexToggle > 0.5 ? texture(u_AOTexture, vs_Input.TexCoord).r : u_AO;
// normal
m_Params.Normal = normalize(vs_Input.Normal);
if (u_NormalTexToggle > 0.5)
@ -524,7 +529,7 @@ void main()
}
}
vec3 iblContribution = IBL(F0, Lr) * u_IBLContribution;
vec3 iblContribution = IBL(F0, Lr) * u_IBLContribution * ao;
color = vec4(lightContribution + iblContribution, 1.0);

View File

@ -117,6 +117,7 @@ uniform sampler2D u_AlbedoTexture;
uniform sampler2D u_NormalTexture;
uniform sampler2D u_MetalnessTexture;
uniform sampler2D u_RoughnessTexture;
uniform sampler2D u_AOTexture;
// environment
uniform samplerCube u_EnvRadianceTex;
@ -133,12 +134,14 @@ uniform float u_EnvMapRotation;
uniform vec4 u_AlbedoColor;
uniform float u_Metalness;
uniform float u_Roughness;
uniform float u_AO;
// textureToggle
uniform float u_AlbedoTexToggle;
uniform float u_NormalTexToggle;
uniform float u_MetalnessTexToggle;
uniform float u_RoughnessTexToggle;
uniform float u_AOTexToggle;
// shadow
const int CSM_CASCADE_COUNT = 4;
@ -470,6 +473,8 @@ void main()
m_Params.Roughness = u_RoughnessTexToggle > 0.5 ? texture(u_RoughnessTexture, vs_Input.TexCoord).r : u_Roughness;
m_Params.Roughness = max(m_Params.Roughness, 0.05);
float ao = u_AOTexToggle > 0.5 ? texture(u_AOTexture, vs_Input.TexCoord).r : u_AO;
// normal
m_Params.Normal = normalize(vs_Input.Normal);
if (u_NormalTexToggle > 0.5)
@ -511,7 +516,7 @@ void main()
}
}
vec3 iblContribution = IBL(F0, Lr) * u_IBLContribution;
vec3 iblContribution = IBL(F0, Lr) * u_IBLContribution * ao;
color = vec4(lightContribution + iblContribution, 1.0);

View File

@ -25,29 +25,38 @@ uniform sampler2D u_DepthTexture;
uniform sampler2D u_MaterialInfoTexture;
uniform mat4 u_Projection;
uniform mat4 u_InvProjection;
uniform mat4 u_View;
uniform mat4 u_InvViewProjection;
uniform vec3 u_CameraPosition;
uniform vec2 u_ScreenSize;
uniform float u_CameraNear;
uniform float u_CameraFar;
uniform int u_Steps = 64;
uniform int u_Steps = 32;
uniform float u_Thickness = 0.5;
uniform float u_MaxDistance = 30.0;
uniform float u_StepSize = 0.5;
uniform float u_RayOffset = 0.1;
uniform float u_Intensity = 1.0;
float saturate(float x)
{
return clamp(x, 0.0, 1.0);
}
float LinearizeDepth(float depth)
{
float z = depth * 2.0 - 1.0;
return (2.0 * u_CameraNear * u_CameraFar) / (u_CameraFar + u_CameraNear - z * (u_CameraFar - u_CameraNear));
}
vec3 ReconstructViewPos(vec2 tc, float depth)
vec3 ComputeWorldSpacePosition(vec2 uv, float depth)
{
float z = depth * 2.0 - 1.0;
vec4 clipPos = vec4(tc * 2.0 - 1.0, z, 1.0);
vec4 viewPos4 = u_InvProjection * clipPos;
return viewPos4.xyz / viewPos4.w;
vec4 clipPos = vec4(uv * 2.0 - 1.0, depth * 2.0 - 1.0, 1.0);
vec4 worldPos = u_InvViewProjection * clipPos;
return worldPos.xyz / worldPos.w;
}
vec3 ReconstructNormalFromDepth(vec2 tc, float depth)
@ -64,17 +73,24 @@ vec3 ReconstructNormalFromDepth(vec2 tc, float depth)
float depthB = texture(u_DepthTexture, tcB).r;
float depthT = texture(u_DepthTexture, tcT).r;
vec3 pL = ReconstructViewPos(tcL, depthL);
vec3 pR = ReconstructViewPos(tcR, depthR);
vec3 pB = ReconstructViewPos(tcB, depthB);
vec3 pT = ReconstructViewPos(tcT, depthT);
vec3 pC = ComputeWorldSpacePosition(tc, depth);
vec3 pR = ComputeWorldSpacePosition(tcR, depthR);
vec3 pT = ComputeWorldSpacePosition(tcT, depthT);
vec3 dx = pR - pL;
vec3 dy = pT - pB;
vec3 dx = pR - pC;
vec3 dy = pT - pC;
return normalize(cross(dx, dy));
}
vec3 ComputeNDCWithZ(vec3 worldPos)
{
vec4 clipPos = u_Projection * u_View * vec4(worldPos, 1.0);
vec3 ndc = clipPos.xyz / clipPos.w;
ndc.xy = ndc.xy * 0.5 + 0.5;
return ndc;
}
void main()
{
float depth = texture(u_DepthTexture, v_TexCoord).r;
@ -95,113 +111,68 @@ void main()
return;
}
vec3 viewPos = ReconstructViewPos(v_TexCoord, depth);
vec3 normal = ReconstructNormalFromDepth(v_TexCoord, depth);
vec3 positionWS = ComputeWorldSpacePosition(v_TexCoord, depth);
vec3 viewWS = normalize(u_CameraPosition - positionWS);
vec3 normalWS = ReconstructNormalFromDepth(v_TexCoord, depth);
vec3 reflectionWS = normalize(reflect(-viewWS, normalWS));
vec3 viewDir = normalize(-viewPos);
float NdotV = max(dot(normal, viewDir), 0.0);
vec3 reflectDir = reflect(-viewDir, normal);
if (dot(reflectDir, normal) < 0.0)
if (dot(reflectionWS, normalWS) < 0.0)
{
o_Color = vec4(0.0);
return;
}
vec3 rayOrigin = viewPos + normal * 0.02;
vec3 rayEnd = rayOrigin + reflectDir * u_MaxDistance;
vec3 rayWS = positionWS + normalWS * u_RayOffset;
vec4 p0 = u_Projection * vec4(rayOrigin, 1.0);
vec4 p1 = u_Projection * vec4(rayEnd, 1.0);
float k0 = 1.0 / p0.w;
float k1 = 1.0 / p1.w;
p0.xyz *= k0;
p1.xyz *= k1;
vec3 v0 = rayOrigin * k0;
vec3 v1 = rayEnd * k1;
vec2 s0 = p0.xy * 0.5 + 0.5;
vec2 s1 = p1.xy * 0.5 + 0.5;
vec2 sDelta = s1 - s0;
float screenDist = length(sDelta * u_ScreenSize);
if (screenDist < 1.0)
for (int i = 0; i < u_Steps; i++)
{
o_Color = vec4(0.0);
return;
}
rayWS += reflectionWS * u_StepSize;
float divisions = min(screenDist, float(u_Steps));
vec3 dV = (v1 - v0) / divisions;
float dK = (k1 - k0) / divisions;
vec2 dS = sDelta / divisions;
vec3 rayNDC = ComputeNDCWithZ(rayWS);
float rayDepth = rayNDC.z;
vec3 curV = v0;
float curK = k0;
vec2 curS = s0;
vec2 raySS = rayNDC.xy * u_ScreenSize;
vec2 hitUV = vec2(0.0);
bool found = false;
for (int i = 0; i < int(divisions); i++)
{
curV += dV;
curK += dK;
curS += dS;
if (curS.x < 0.0 || curS.x > 1.0 || curS.y < 0.0 || curS.y > 1.0)
if (rayNDC.x < 0.0 || rayNDC.x > 1.0 || rayNDC.y < 0.0 || rayNDC.y > 1.0)
break;
float sampleDepth = texture(u_DepthTexture, curS).r;
float surfDepth = LinearizeDepth(sampleDepth);
float rayDepth = -curV.z / curK;
float sceneDepth = texture(u_DepthTexture, rayNDC.xy).r;
float sceneDepthLinear = LinearizeDepth(sceneDepth);
float rayDepthLinear = LinearizeDepth(rayDepth * 0.5 + 0.5);
float depthDiff = rayDepth - surfDepth;
float delta = rayDepthLinear - sceneDepthLinear;
if (depthDiff > 0.0 && depthDiff < u_Thickness)
if (delta >= 0.0 && delta <= u_Thickness)
{
hitUV = curS;
found = true;
break;
vec3 hitNormalWS = ReconstructNormalFromDepth(rayNDC.xy, sceneDepth);
if (dot(hitNormalWS, reflectionWS) > 0.0)
break;
float ssrStrength = saturate(1.0 - roughness * roughness);
float dist = distance(positionWS, rayWS);
float fadeFactor = 1.0 - smoothstep(u_MaxDistance * 0.3, u_MaxDistance, dist);
float edgeFade = 1.0;
edgeFade *= smoothstep(0.0, 0.1, rayNDC.x);
edgeFade *= smoothstep(0.0, 0.1, rayNDC.y);
edgeFade *= smoothstep(0.0, 0.1, 1.0 - rayNDC.x);
edgeFade *= smoothstep(0.0, 0.1, 1.0 - rayNDC.y);
float NdotV = max(dot(normalWS, viewWS), 0.0);
vec3 F0 = mix(vec3(0.04), vec3(1.0), metalness);
vec3 Fresnel = F0 + (1.0 - F0) * pow(1.0 - NdotV, 5.0);
ssrStrength *= fadeFactor * edgeFade * u_Intensity;
vec4 color = texture(u_ColorTexture, rayNDC.xy);
color.rgb *= ssrStrength * Fresnel;
color.a = ssrStrength * dot(Fresnel, vec3(0.333));
o_Color = color;
return;
}
}
if (!found)
{
o_Color = vec4(0.0);
return;
}
vec3 hitNormal = ReconstructNormalFromDepth(hitUV, texture(u_DepthTexture, hitUV).r);
if (dot(hitNormal, -reflectDir) < 0.0)
{
o_Color = vec4(0.0);
return;
}
vec3 reflectColor = texture(u_ColorTexture, hitUV).rgb;
float dist = distance(viewPos, ReconstructViewPos(hitUV, texture(u_DepthTexture, hitUV).r));
float fadeFactor = 1.0 - smoothstep(u_MaxDistance * 0.5, u_MaxDistance, dist);
float edgeFade = 1.0;
edgeFade *= smoothstep(0.0, 0.15, hitUV.x);
edgeFade *= smoothstep(0.0, 0.15, hitUV.y);
edgeFade *= smoothstep(0.0, 0.15, 1.0 - hitUV.x);
edgeFade *= smoothstep(0.0, 0.15, 1.0 - hitUV.y);
vec3 F0 = mix(vec3(0.04), reflectColor, metalness);
vec3 Fresnel = F0 + (1.0 - F0) * pow(1.0 - NdotV, 5.0);
float roughnessFade = 1.0 - roughness * roughness;
vec3 ssrContrib = reflectColor * Fresnel * fadeFactor * edgeFade * roughnessFade * u_Intensity;
float ssrAlpha = length(Fresnel) * fadeFactor * edgeFade * roughnessFade;
o_Color = vec4(ssrContrib, ssrAlpha);
o_Color = vec4(0.0);
}

View File

@ -85,7 +85,6 @@ float MultiSampleDepth(sampler2DMS tex, vec2 tc)
void main()
{
const float gamma = 2.2;
const float pureWhite = 1.0;
// Tonemapping
vec4 msColor = MultiSampleTexture(u_Texture, v_TexCoord);
@ -100,7 +99,7 @@ void main()
if (u_EnableSSR)
{
vec4 ssrSample = texture(u_SSRTexture, v_TexCoord);
color += ssrSample.rgb * ssrSample.a;
color = mix(color, ssrSample.rgb, ssrSample.a);
}
@ -111,14 +110,18 @@ void main()
exposure = u_ManualExposure;
color *= exposure;
vec3 mappedColor = color;
// Reinhard tonemapping operator.
// see: "Photographic Tone Reproduction for Digital Images", eq. 4
float luminance = dot(color, vec3(0.2126, 0.7152, 0.0722));
float mappedLuminance = (luminance * (1.0 + luminance / (pureWhite * pureWhite))) / (1.0 + luminance);
// Scale color by ratio of average luminances.
vec3 mappedColor = (mappedLuminance / luminance) * color;
float luminance = dot(mappedColor, vec3(0.2126, 0.7152, 0.0722));
if (luminance > 0.00001)
{
float a = 2.51;
float b = 0.03;
float c = 2.43;
float d = 0.59;
float e = 0.14;
mappedColor = clamp((mappedColor * (a * mappedColor + b)) / (mappedColor * (c * mappedColor + d) + e), 0.0, 1.0);
}
if (u_FogEnabled > 0.5)
{