add aabb cull for mesh, improve NodeEditor view and control
add AO texture
This commit is contained in:
@ -578,6 +578,56 @@ namespace Prism
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
// AO
|
||||||
|
if (ImGui::CollapsingHeader("AO", nullptr, ImGuiTreeNodeFlags_DefaultOpen))
|
||||||
|
{
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(10, 10));
|
||||||
|
float& aoValue = materialInstance->Get<float>("u_AO");
|
||||||
|
bool useAOMap = materialInstance->Get<float>("u_AOTexToggle");
|
||||||
|
Ref<Texture2D> aoMap = materialInstance->TryGetResource<Texture2D>("u_AOTexture");
|
||||||
|
|
||||||
|
ImGui::Image(aoMap ? (ImTextureRef)aoMap->GetRendererID() : (ImTextureRef)m_CheckerboardTex->GetRendererID(), ImVec2(64, 64));
|
||||||
|
if (ImGui::BeginDragDropTarget())
|
||||||
|
{
|
||||||
|
if (const auto data = ImGui::AcceptDragDropPayload("asset_payload"))
|
||||||
|
{
|
||||||
|
AssetHandle assetHandle = *(AssetHandle*)data->Data;
|
||||||
|
if (AssetsManager::IsAssetType(assetHandle, AssetType::Texture))
|
||||||
|
{
|
||||||
|
aoMap = AssetsManager::GetAsset<Texture2D>(assetHandle);
|
||||||
|
shouldUpdate = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndDragDropTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::PopStyleVar();
|
||||||
|
if (ImGui::IsItemHovered())
|
||||||
|
{
|
||||||
|
if (aoMap)
|
||||||
|
{
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
|
||||||
|
ImGui::TextUnformatted(aoMap->GetPath().c_str());
|
||||||
|
ImGui::PopTextWrapPos();
|
||||||
|
ImGui::Image((ImTextureRef)aoMap->GetRendererID(), ImVec2(384, 384));
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Checkbox("Use##AOMap", &useAOMap))
|
||||||
|
{
|
||||||
|
materialInstance->Set<float>("u_AOTexToggle", useAOMap ? 1.0f : 0.0f);
|
||||||
|
shouldUpdate = true;
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::SliderFloat("Value##AOInput", &aoValue, 0.0f, 1.0f))
|
||||||
|
{
|
||||||
|
shouldUpdate = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (shouldUpdate) meshComponent.UpdateMaterials(selectedMaterialIndex);
|
if (shouldUpdate) meshComponent.UpdateMaterials(selectedMaterialIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -130,6 +130,7 @@ uniform sampler2D u_AlbedoTexture;
|
|||||||
uniform sampler2D u_NormalTexture;
|
uniform sampler2D u_NormalTexture;
|
||||||
uniform sampler2D u_MetalnessTexture;
|
uniform sampler2D u_MetalnessTexture;
|
||||||
uniform sampler2D u_RoughnessTexture;
|
uniform sampler2D u_RoughnessTexture;
|
||||||
|
uniform sampler2D u_AOTexture;
|
||||||
|
|
||||||
// environment
|
// environment
|
||||||
uniform samplerCube u_EnvRadianceTex;
|
uniform samplerCube u_EnvRadianceTex;
|
||||||
@ -146,12 +147,14 @@ uniform float u_EnvMapRotation;
|
|||||||
uniform vec4 u_AlbedoColor;
|
uniform vec4 u_AlbedoColor;
|
||||||
uniform float u_Metalness;
|
uniform float u_Metalness;
|
||||||
uniform float u_Roughness;
|
uniform float u_Roughness;
|
||||||
|
uniform float u_AO;
|
||||||
|
|
||||||
// textureToggle
|
// textureToggle
|
||||||
uniform float u_AlbedoTexToggle;
|
uniform float u_AlbedoTexToggle;
|
||||||
uniform float u_NormalTexToggle;
|
uniform float u_NormalTexToggle;
|
||||||
uniform float u_MetalnessTexToggle;
|
uniform float u_MetalnessTexToggle;
|
||||||
uniform float u_RoughnessTexToggle;
|
uniform float u_RoughnessTexToggle;
|
||||||
|
uniform float u_AOTexToggle;
|
||||||
|
|
||||||
// shadow
|
// shadow
|
||||||
const int CSM_CASCADE_COUNT = 4;
|
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 = u_RoughnessTexToggle > 0.5 ? texture(u_RoughnessTexture, vs_Input.TexCoord).r : u_Roughness;
|
||||||
m_Params.Roughness = max(m_Params.Roughness, 0.05);
|
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
|
// normal
|
||||||
m_Params.Normal = normalize(vs_Input.Normal);
|
m_Params.Normal = normalize(vs_Input.Normal);
|
||||||
if (u_NormalTexToggle > 0.5)
|
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);
|
color = vec4(lightContribution + iblContribution, 1.0);
|
||||||
|
|
||||||
|
|||||||
@ -117,6 +117,7 @@ uniform sampler2D u_AlbedoTexture;
|
|||||||
uniform sampler2D u_NormalTexture;
|
uniform sampler2D u_NormalTexture;
|
||||||
uniform sampler2D u_MetalnessTexture;
|
uniform sampler2D u_MetalnessTexture;
|
||||||
uniform sampler2D u_RoughnessTexture;
|
uniform sampler2D u_RoughnessTexture;
|
||||||
|
uniform sampler2D u_AOTexture;
|
||||||
|
|
||||||
// environment
|
// environment
|
||||||
uniform samplerCube u_EnvRadianceTex;
|
uniform samplerCube u_EnvRadianceTex;
|
||||||
@ -133,12 +134,14 @@ uniform float u_EnvMapRotation;
|
|||||||
uniform vec4 u_AlbedoColor;
|
uniform vec4 u_AlbedoColor;
|
||||||
uniform float u_Metalness;
|
uniform float u_Metalness;
|
||||||
uniform float u_Roughness;
|
uniform float u_Roughness;
|
||||||
|
uniform float u_AO;
|
||||||
|
|
||||||
// textureToggle
|
// textureToggle
|
||||||
uniform float u_AlbedoTexToggle;
|
uniform float u_AlbedoTexToggle;
|
||||||
uniform float u_NormalTexToggle;
|
uniform float u_NormalTexToggle;
|
||||||
uniform float u_MetalnessTexToggle;
|
uniform float u_MetalnessTexToggle;
|
||||||
uniform float u_RoughnessTexToggle;
|
uniform float u_RoughnessTexToggle;
|
||||||
|
uniform float u_AOTexToggle;
|
||||||
|
|
||||||
// shadow
|
// shadow
|
||||||
const int CSM_CASCADE_COUNT = 4;
|
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 = u_RoughnessTexToggle > 0.5 ? texture(u_RoughnessTexture, vs_Input.TexCoord).r : u_Roughness;
|
||||||
m_Params.Roughness = max(m_Params.Roughness, 0.05);
|
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
|
// normal
|
||||||
m_Params.Normal = normalize(vs_Input.Normal);
|
m_Params.Normal = normalize(vs_Input.Normal);
|
||||||
if (u_NormalTexToggle > 0.5)
|
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);
|
color = vec4(lightContribution + iblContribution, 1.0);
|
||||||
|
|||||||
@ -25,29 +25,38 @@ uniform sampler2D u_DepthTexture;
|
|||||||
uniform sampler2D u_MaterialInfoTexture;
|
uniform sampler2D u_MaterialInfoTexture;
|
||||||
|
|
||||||
uniform mat4 u_Projection;
|
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 vec2 u_ScreenSize;
|
||||||
uniform float u_CameraNear;
|
uniform float u_CameraNear;
|
||||||
uniform float u_CameraFar;
|
uniform float u_CameraFar;
|
||||||
|
|
||||||
uniform int u_Steps = 64;
|
uniform int u_Steps = 32;
|
||||||
uniform float u_Thickness = 0.5;
|
uniform float u_Thickness = 0.5;
|
||||||
uniform float u_MaxDistance = 30.0;
|
uniform float u_MaxDistance = 30.0;
|
||||||
|
uniform float u_StepSize = 0.5;
|
||||||
|
uniform float u_RayOffset = 0.1;
|
||||||
uniform float u_Intensity = 1.0;
|
uniform float u_Intensity = 1.0;
|
||||||
|
|
||||||
|
float saturate(float x)
|
||||||
|
{
|
||||||
|
return clamp(x, 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
float LinearizeDepth(float depth)
|
float LinearizeDepth(float depth)
|
||||||
{
|
{
|
||||||
float z = depth * 2.0 - 1.0;
|
float z = depth * 2.0 - 1.0;
|
||||||
return (2.0 * u_CameraNear * u_CameraFar) / (u_CameraFar + u_CameraNear - z * (u_CameraFar - u_CameraNear));
|
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(uv * 2.0 - 1.0, depth * 2.0 - 1.0, 1.0);
|
||||||
vec4 clipPos = vec4(tc * 2.0 - 1.0, z, 1.0);
|
vec4 worldPos = u_InvViewProjection * clipPos;
|
||||||
vec4 viewPos4 = u_InvProjection * clipPos;
|
return worldPos.xyz / worldPos.w;
|
||||||
return viewPos4.xyz / viewPos4.w;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 ReconstructNormalFromDepth(vec2 tc, float depth)
|
vec3 ReconstructNormalFromDepth(vec2 tc, float depth)
|
||||||
@ -64,17 +73,24 @@ vec3 ReconstructNormalFromDepth(vec2 tc, float depth)
|
|||||||
float depthB = texture(u_DepthTexture, tcB).r;
|
float depthB = texture(u_DepthTexture, tcB).r;
|
||||||
float depthT = texture(u_DepthTexture, tcT).r;
|
float depthT = texture(u_DepthTexture, tcT).r;
|
||||||
|
|
||||||
vec3 pL = ReconstructViewPos(tcL, depthL);
|
vec3 pC = ComputeWorldSpacePosition(tc, depth);
|
||||||
vec3 pR = ReconstructViewPos(tcR, depthR);
|
vec3 pR = ComputeWorldSpacePosition(tcR, depthR);
|
||||||
vec3 pB = ReconstructViewPos(tcB, depthB);
|
vec3 pT = ComputeWorldSpacePosition(tcT, depthT);
|
||||||
vec3 pT = ReconstructViewPos(tcT, depthT);
|
|
||||||
|
|
||||||
vec3 dx = pR - pL;
|
vec3 dx = pR - pC;
|
||||||
vec3 dy = pT - pB;
|
vec3 dy = pT - pC;
|
||||||
|
|
||||||
return normalize(cross(dx, dy));
|
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()
|
void main()
|
||||||
{
|
{
|
||||||
float depth = texture(u_DepthTexture, v_TexCoord).r;
|
float depth = texture(u_DepthTexture, v_TexCoord).r;
|
||||||
@ -95,113 +111,68 @@ void main()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 viewPos = ReconstructViewPos(v_TexCoord, depth);
|
vec3 positionWS = ComputeWorldSpacePosition(v_TexCoord, depth);
|
||||||
vec3 normal = ReconstructNormalFromDepth(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);
|
if (dot(reflectionWS, normalWS) < 0.0)
|
||||||
float NdotV = max(dot(normal, viewDir), 0.0);
|
|
||||||
|
|
||||||
vec3 reflectDir = reflect(-viewDir, normal);
|
|
||||||
|
|
||||||
if (dot(reflectDir, normal) < 0.0)
|
|
||||||
{
|
{
|
||||||
o_Color = vec4(0.0);
|
o_Color = vec4(0.0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 rayOrigin = viewPos + normal * 0.02;
|
vec3 rayWS = positionWS + normalWS * u_RayOffset;
|
||||||
vec3 rayEnd = rayOrigin + reflectDir * u_MaxDistance;
|
|
||||||
|
|
||||||
vec4 p0 = u_Projection * vec4(rayOrigin, 1.0);
|
for (int i = 0; i < u_Steps; i++)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
o_Color = vec4(0.0);
|
rayWS += reflectionWS * u_StepSize;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
float divisions = min(screenDist, float(u_Steps));
|
vec3 rayNDC = ComputeNDCWithZ(rayWS);
|
||||||
vec3 dV = (v1 - v0) / divisions;
|
float rayDepth = rayNDC.z;
|
||||||
float dK = (k1 - k0) / divisions;
|
|
||||||
vec2 dS = sDelta / divisions;
|
|
||||||
|
|
||||||
vec3 curV = v0;
|
vec2 raySS = rayNDC.xy * u_ScreenSize;
|
||||||
float curK = k0;
|
|
||||||
vec2 curS = s0;
|
|
||||||
|
|
||||||
vec2 hitUV = vec2(0.0);
|
if (rayNDC.x < 0.0 || rayNDC.x > 1.0 || rayNDC.y < 0.0 || rayNDC.y > 1.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)
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
float sampleDepth = texture(u_DepthTexture, curS).r;
|
float sceneDepth = texture(u_DepthTexture, rayNDC.xy).r;
|
||||||
float surfDepth = LinearizeDepth(sampleDepth);
|
float sceneDepthLinear = LinearizeDepth(sceneDepth);
|
||||||
float rayDepth = -curV.z / curK;
|
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;
|
vec3 hitNormalWS = ReconstructNormalFromDepth(rayNDC.xy, sceneDepth);
|
||||||
found = true;
|
if (dot(hitNormalWS, reflectionWS) > 0.0)
|
||||||
break;
|
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);
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -85,7 +85,6 @@ float MultiSampleDepth(sampler2DMS tex, vec2 tc)
|
|||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
const float gamma = 2.2;
|
const float gamma = 2.2;
|
||||||
const float pureWhite = 1.0;
|
|
||||||
|
|
||||||
// Tonemapping
|
// Tonemapping
|
||||||
vec4 msColor = MultiSampleTexture(u_Texture, v_TexCoord);
|
vec4 msColor = MultiSampleTexture(u_Texture, v_TexCoord);
|
||||||
@ -100,7 +99,7 @@ void main()
|
|||||||
if (u_EnableSSR)
|
if (u_EnableSSR)
|
||||||
{
|
{
|
||||||
vec4 ssrSample = texture(u_SSRTexture, v_TexCoord);
|
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;
|
exposure = u_ManualExposure;
|
||||||
color *= exposure;
|
color *= exposure;
|
||||||
|
|
||||||
|
vec3 mappedColor = color;
|
||||||
|
|
||||||
// Reinhard tonemapping operator.
|
float luminance = dot(mappedColor, vec3(0.2126, 0.7152, 0.0722));
|
||||||
// see: "Photographic Tone Reproduction for Digital Images", eq. 4
|
if (luminance > 0.00001)
|
||||||
float luminance = dot(color, vec3(0.2126, 0.7152, 0.0722));
|
{
|
||||||
float mappedLuminance = (luminance * (1.0 + luminance / (pureWhite * pureWhite))) / (1.0 + luminance);
|
float a = 2.51;
|
||||||
|
float b = 0.03;
|
||||||
// Scale color by ratio of average luminances.
|
float c = 2.43;
|
||||||
vec3 mappedColor = (mappedLuminance / luminance) * color;
|
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)
|
if (u_FogEnabled > 0.5)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -81,15 +81,20 @@ namespace Prism
|
|||||||
Ref<Texture2D> NormalTexture;
|
Ref<Texture2D> NormalTexture;
|
||||||
|
|
||||||
// Metalness
|
// Metalness
|
||||||
float Metalness = 0.8f;
|
float Metalness = 0.2f;
|
||||||
float MetalnessTexToggle = 0.0f;
|
float MetalnessTexToggle = 0.0f;
|
||||||
Ref<Texture2D> MetalnessTexture;
|
Ref<Texture2D> MetalnessTexture;
|
||||||
|
|
||||||
// Roughness
|
// Roughness
|
||||||
float Roughness = 0.1f;
|
float Roughness = 1.0f;
|
||||||
float RoughnessTexToggle = 0.0f;
|
float RoughnessTexToggle = 0.0f;
|
||||||
Ref<Texture2D> RoughnessTexture;
|
Ref<Texture2D> RoughnessTexture;
|
||||||
|
|
||||||
|
// AO
|
||||||
|
float AO = 1.0f;
|
||||||
|
float AOTexToggle = 0.0f;
|
||||||
|
Ref<Texture2D> AOTexture;
|
||||||
|
|
||||||
bool IsDirty = true;
|
bool IsDirty = true;
|
||||||
bool PreviewIsDirty = true;
|
bool PreviewIsDirty = true;
|
||||||
|
|
||||||
|
|||||||
@ -123,7 +123,7 @@ namespace Prism
|
|||||||
out << YAML::Key << "Roughness";
|
out << YAML::Key << "Roughness";
|
||||||
out << YAML::BeginMap;
|
out << YAML::BeginMap;
|
||||||
{
|
{
|
||||||
out << YAML::Key << "Value" << YAML::Value << material->Roughness; // 粗糙度数值
|
out << YAML::Key << "Value" << YAML::Value << material->Roughness;
|
||||||
out << YAML::Key << "TexToggle" << YAML::Value << material->RoughnessTexToggle;
|
out << YAML::Key << "TexToggle" << YAML::Value << material->RoughnessTexToggle;
|
||||||
|
|
||||||
out << YAML::Key << "Texture";
|
out << YAML::Key << "Texture";
|
||||||
@ -142,6 +142,29 @@ namespace Prism
|
|||||||
}
|
}
|
||||||
out << YAML::EndMap;
|
out << YAML::EndMap;
|
||||||
|
|
||||||
|
// AO
|
||||||
|
out << YAML::Key << "AO";
|
||||||
|
out << YAML::BeginMap;
|
||||||
|
{
|
||||||
|
out << YAML::Key << "Value" << YAML::Value << material->AO;
|
||||||
|
out << YAML::Key << "TexToggle" << YAML::Value << material->AOTexToggle;
|
||||||
|
|
||||||
|
out << YAML::Key << "Texture";
|
||||||
|
out << YAML::BeginMap;
|
||||||
|
if (material->AOTexture)
|
||||||
|
{
|
||||||
|
out << YAML::Key << "AssetHandle" << YAML::Value << material->AOTexture->Handle;
|
||||||
|
out << YAML::Key << "AssetPath" << YAML::Value << material->AOTexture->FilePath;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out << YAML::Key << "AssetHandle" << YAML::Value << 0;
|
||||||
|
out << YAML::Key << "AssetPath" << YAML::Value << "";
|
||||||
|
}
|
||||||
|
out << YAML::EndMap;
|
||||||
|
}
|
||||||
|
out << YAML::EndMap;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -279,6 +302,32 @@ namespace Prism
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ==================== AO ====================
|
||||||
|
if (data["AO"])
|
||||||
|
{
|
||||||
|
auto aoNode = data["AO"];
|
||||||
|
material->AO = aoNode["Value"].as<float>();
|
||||||
|
material->AOTexToggle = aoNode["TexToggle"].as<float>();
|
||||||
|
|
||||||
|
if (aoNode["Texture"])
|
||||||
|
{
|
||||||
|
auto texNode = aoNode["Texture"];
|
||||||
|
UUID texHandle = 0;
|
||||||
|
std::string texPath;
|
||||||
|
if (texNode["AssetHandle"])
|
||||||
|
texHandle = texNode["AssetHandle"].as<uint64_t>();
|
||||||
|
if (texNode["AssetPath"])
|
||||||
|
texPath = texNode["AssetPath"].as<std::string>();
|
||||||
|
|
||||||
|
if (texHandle != 0 && AssetsManager::IsAssetHandleValid(texHandle))
|
||||||
|
material->AOTexture = AssetsManager::GetAsset<Texture2D>(texHandle);
|
||||||
|
else if (!texPath.empty())
|
||||||
|
material->AOTexture = Texture2D::Create(texPath);
|
||||||
|
else
|
||||||
|
material->AOTexture = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return material;
|
return material;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
#define PRISM_AABB_H
|
#define PRISM_AABB_H
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
namespace Prism
|
namespace Prism
|
||||||
{
|
{
|
||||||
@ -23,6 +24,28 @@ namespace Prism
|
|||||||
return Min.x <= Max.x && Min.y <= Max.y && Min.z <= Max.z;
|
return Min.x <= Max.x && Min.y <= Max.y && Min.z <= Max.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AABB Transform(const glm::mat4& m) const
|
||||||
|
{
|
||||||
|
glm::vec3 corners[8] = {
|
||||||
|
{Min.x, Min.y, Min.z}, {Min.x, Min.y, Max.z},
|
||||||
|
{Min.x, Max.y, Min.z}, {Min.x, Max.y, Max.z},
|
||||||
|
{Max.x, Min.y, Min.z}, {Max.x, Min.y, Max.z},
|
||||||
|
{Max.x, Max.y, Min.z}, {Max.x, Max.y, Max.z}
|
||||||
|
};
|
||||||
|
|
||||||
|
glm::vec3 newMin(std::numeric_limits<float>::max());
|
||||||
|
glm::vec3 newMax(std::numeric_limits<float>::lowest());
|
||||||
|
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
glm::vec3 c = glm::vec3(m * glm::vec4(corners[i], 1.0f));
|
||||||
|
newMin = glm::min(newMin, c);
|
||||||
|
newMax = glm::max(newMax, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
return AABB(newMin, newMax);
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
64
Prism/src/Prism/Core/Math/Frustum.h
Normal file
64
Prism/src/Prism/Core/Math/Frustum.h
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
#ifndef PRISM_FRUSTUM_H
|
||||||
|
#define PRISM_FRUSTUM_H
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include "Prism/Core/Math/AABB.h"
|
||||||
|
|
||||||
|
namespace Prism
|
||||||
|
{
|
||||||
|
struct Frustum
|
||||||
|
{
|
||||||
|
glm::vec4 Planes[6];
|
||||||
|
|
||||||
|
enum PlaneIndex
|
||||||
|
{
|
||||||
|
Left = 0, Right, Bottom, Top, Near, Far
|
||||||
|
};
|
||||||
|
|
||||||
|
static Frustum FromViewProjection(const glm::mat4& vp)
|
||||||
|
{
|
||||||
|
Frustum f;
|
||||||
|
glm::mat4 t = glm::transpose(vp);
|
||||||
|
glm::vec4 row0 = t[0];
|
||||||
|
glm::vec4 row1 = t[1];
|
||||||
|
glm::vec4 row2 = t[2];
|
||||||
|
glm::vec4 row3 = t[3];
|
||||||
|
|
||||||
|
f.Planes[Left] = row3 + row0;
|
||||||
|
f.Planes[Right] = row3 - row0;
|
||||||
|
f.Planes[Bottom] = row3 + row1;
|
||||||
|
f.Planes[Top] = row3 - row1;
|
||||||
|
f.Planes[Near] = row3 + row2;
|
||||||
|
f.Planes[Far] = row3 - row2;
|
||||||
|
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
float len = glm::length(glm::vec3(f.Planes[i]));
|
||||||
|
if (len > 0.0001f)
|
||||||
|
f.Planes[i] /= len;
|
||||||
|
}
|
||||||
|
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsInside(const AABB& aabb) const
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
const glm::vec4& p = Planes[i];
|
||||||
|
glm::vec3 normal(p.x, p.y, p.z);
|
||||||
|
|
||||||
|
glm::vec3 positive = aabb.Min;
|
||||||
|
if (p.x >= 0) positive.x = aabb.Max.x;
|
||||||
|
if (p.y >= 0) positive.y = aabb.Max.y;
|
||||||
|
if (p.z >= 0) positive.z = aabb.Max.z;
|
||||||
|
|
||||||
|
if (glm::dot(normal, positive) + p.w < 0.0f)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -1,4 +1,4 @@
|
|||||||
//
|
//
|
||||||
// Created by Atdunbg on 2026/2/14.
|
// Created by Atdunbg on 2026/2/14.
|
||||||
//
|
//
|
||||||
|
|
||||||
@ -15,6 +15,7 @@
|
|||||||
#include "Prism/Renderer/RHI/RHICommandBuffer.h"
|
#include "Prism/Renderer/RHI/RHICommandBuffer.h"
|
||||||
#include "Prism/Renderer/SceneRenderer.h"
|
#include "Prism/Renderer/SceneRenderer.h"
|
||||||
#include "Prism/Scene/Scene.h"
|
#include "Prism/Scene/Scene.h"
|
||||||
|
#include "Prism/Utilities/StringUtils.h"
|
||||||
|
|
||||||
namespace Prism
|
namespace Prism
|
||||||
{
|
{
|
||||||
@ -150,15 +151,18 @@ namespace Prism
|
|||||||
matInst->Set("u_AlbedoColor", materialAsset->AlbedoColor);
|
matInst->Set("u_AlbedoColor", materialAsset->AlbedoColor);
|
||||||
matInst->Set("u_Metalness", materialAsset->Metalness);
|
matInst->Set("u_Metalness", materialAsset->Metalness);
|
||||||
matInst->Set("u_Roughness", materialAsset->Roughness);
|
matInst->Set("u_Roughness", materialAsset->Roughness);
|
||||||
|
matInst->Set("u_AO", materialAsset->AO);
|
||||||
matInst->Set("u_AlbedoTexToggle", materialAsset->AlbedoTexToggle);
|
matInst->Set("u_AlbedoTexToggle", materialAsset->AlbedoTexToggle);
|
||||||
matInst->Set("u_NormalTexToggle", materialAsset->NormalTexToggle);
|
matInst->Set("u_NormalTexToggle", materialAsset->NormalTexToggle);
|
||||||
matInst->Set("u_MetalnessTexToggle", materialAsset->MetalnessTexToggle);
|
matInst->Set("u_MetalnessTexToggle", materialAsset->MetalnessTexToggle);
|
||||||
matInst->Set("u_RoughnessTexToggle", materialAsset->RoughnessTexToggle);
|
matInst->Set("u_RoughnessTexToggle", materialAsset->RoughnessTexToggle);
|
||||||
|
matInst->Set("u_AOTexToggle", materialAsset->AOTexToggle);
|
||||||
|
|
||||||
matInst->Set("u_AlbedoTexture", materialAsset->AlbedoTexture);
|
matInst->Set("u_AlbedoTexture", materialAsset->AlbedoTexture);
|
||||||
matInst->Set("u_NormalTexture", materialAsset->NormalTexture);
|
matInst->Set("u_NormalTexture", materialAsset->NormalTexture);
|
||||||
matInst->Set("u_MetalnessTexture", materialAsset->MetalnessTexture);
|
matInst->Set("u_MetalnessTexture", materialAsset->MetalnessTexture);
|
||||||
matInst->Set("u_RoughnessTexture", materialAsset->RoughnessTexture);
|
matInst->Set("u_RoughnessTexture", materialAsset->RoughnessTexture);
|
||||||
|
matInst->Set("u_AOTexture", materialAsset->AOTexture);
|
||||||
|
|
||||||
float aspect = (float)s_PreviewRenderPass->GetSpecification().TargetFramebuffer->GetWidth() /
|
float aspect = (float)s_PreviewRenderPass->GetSpecification().TargetFramebuffer->GetWidth() /
|
||||||
(float)s_PreviewRenderPass->GetSpecification().TargetFramebuffer->GetHeight();
|
(float)s_PreviewRenderPass->GetSpecification().TargetFramebuffer->GetHeight();
|
||||||
@ -330,7 +334,6 @@ namespace Prism
|
|||||||
|
|
||||||
if (ImGui::SliderFloat("Value##Roughness", &material->Roughness, 0.0f, 1.0f))
|
if (ImGui::SliderFloat("Value##Roughness", &material->Roughness, 0.0f, 1.0f))
|
||||||
{
|
{
|
||||||
// 自动保存
|
|
||||||
MarkDirty();
|
MarkDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -352,6 +355,35 @@ namespace Prism
|
|||||||
|
|
||||||
ImGui::Unindent();
|
ImGui::Unindent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AO
|
||||||
|
if (ImGui::CollapsingHeader("AO", ImGuiTreeNodeFlags_DefaultOpen))
|
||||||
|
{
|
||||||
|
ImGui::Indent();
|
||||||
|
|
||||||
|
if (ImGui::SliderFloat("Value##AO", &material->AO, 0.0f, 1.0f))
|
||||||
|
{
|
||||||
|
MarkDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool useAOMap = (material->AOTexToggle > 0.5f);
|
||||||
|
if (ImGui::Checkbox("Use Texture##AO", &useAOMap))
|
||||||
|
{
|
||||||
|
material->AOTexToggle = useAOMap ? 1.0f : 0.0f;
|
||||||
|
MarkDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawTextureSlot(material->AOTexture, [&](const Ref<Texture2D>& newTex)
|
||||||
|
{
|
||||||
|
material->AOTexture = newTex;
|
||||||
|
material->AOTexToggle = true;
|
||||||
|
MarkDirty();
|
||||||
|
});
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::Text("AO Texture");
|
||||||
|
|
||||||
|
ImGui::Unindent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -411,6 +443,9 @@ namespace Prism
|
|||||||
MarkDirty();
|
MarkDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_CanvasOrigin = ImGui::GetCursorScreenPos();
|
||||||
|
m_CanvasSize = ImGui::GetContentRegionAvail();
|
||||||
|
|
||||||
ed::Begin("MaterialNodeEditor");
|
ed::Begin("MaterialNodeEditor");
|
||||||
|
|
||||||
if (m_FirstFrame)
|
if (m_FirstFrame)
|
||||||
@ -518,10 +553,8 @@ namespace Prism
|
|||||||
drawInputPin(AO, "AO", [&]()
|
drawInputPin(AO, "AO", [&]()
|
||||||
{
|
{
|
||||||
ImGui::SetNextItemWidth(80);
|
ImGui::SetNextItemWidth(80);
|
||||||
float ao = 1.0f; // 如果资产没有 AO 字段可以忽略
|
if (ImGui::SliderFloat("##ao", &m_Asset->AO, 0.0f, 1.0f))
|
||||||
if (ImGui::SliderFloat("##ao", &ao, 0.0f, 1.0f))
|
MarkDirty();
|
||||||
{
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ImGui::EndGroup();
|
ImGui::EndGroup();
|
||||||
@ -550,10 +583,24 @@ namespace Prism
|
|||||||
|
|
||||||
ImVec2 headerMin = ImGui::GetCursorScreenPos();
|
ImVec2 headerMin = ImGui::GetCursorScreenPos();
|
||||||
ImGui::BeginGroup();
|
ImGui::BeginGroup();
|
||||||
float headerMaxY = DrawNodeHeader("Texture2D", nodeWidth);
|
|
||||||
|
bool hasTexture = (textureHandle != 0);
|
||||||
|
std::string nodeTitle = "Texture2D";
|
||||||
|
if (hasTexture)
|
||||||
|
{
|
||||||
|
Ref<Texture2D> tex = AssetsManager::GetAsset<Texture2D>(textureHandle);
|
||||||
|
if (tex)
|
||||||
|
{
|
||||||
|
std::string name = Utils::GetFilename(tex->GetPath());
|
||||||
|
if (name.length() > 14)
|
||||||
|
name = name.substr(0, 11) + "...";
|
||||||
|
if (!name.empty())
|
||||||
|
nodeTitle = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
float headerMaxY = DrawNodeHeader(nodeTitle.c_str(), nodeWidth);
|
||||||
|
|
||||||
// 纹理预览
|
// 纹理预览
|
||||||
bool hasTexture = (textureHandle != 0);
|
|
||||||
float previewSize = 80.0f;
|
float previewSize = 80.0f;
|
||||||
float offsetX = (nodeWidth - previewSize) * 0.5f;
|
float offsetX = (nodeWidth - previewSize) * 0.5f;
|
||||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + offsetX);
|
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + offsetX);
|
||||||
@ -565,6 +612,9 @@ namespace Prism
|
|||||||
ImGui::Image((ImTextureID)(intptr_t)tex->GetRendererID(), ImVec2(previewSize, previewSize), ImVec2(0,1), ImVec2(1,0));
|
ImGui::Image((ImTextureID)(intptr_t)tex->GetRendererID(), ImVec2(previewSize, previewSize), ImVec2(0,1), ImVec2(1,0));
|
||||||
else
|
else
|
||||||
ImGui::Dummy(ImVec2(previewSize, previewSize));
|
ImGui::Dummy(ImVec2(previewSize, previewSize));
|
||||||
|
|
||||||
|
if (ImGui::IsItemHovered() && tex)
|
||||||
|
m_PendingTooltip = Utils::GetFilename(tex->GetPath());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -705,19 +755,22 @@ namespace Prism
|
|||||||
|
|
||||||
ed::Suspend();
|
ed::Suspend();
|
||||||
|
|
||||||
|
if (!m_PendingTooltip.empty())
|
||||||
|
{
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::TextUnformatted(m_PendingTooltip.c_str());
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
m_PendingTooltip.clear();
|
||||||
|
}
|
||||||
|
|
||||||
const ImGuiPayload* payload = ImGui::GetDragDropPayload();
|
const ImGuiPayload* payload = ImGui::GetDragDropPayload();
|
||||||
if (payload && payload->IsDataType("asset_payload"))
|
if (payload && payload->IsDataType("asset_payload"))
|
||||||
{
|
{
|
||||||
AssetHandle handle = *(AssetHandle*)payload->Data;
|
AssetHandle handle = *(AssetHandle*)payload->Data;
|
||||||
if (AssetsManager::IsAssetType(handle, AssetType::Texture))
|
if (AssetsManager::IsAssetType(handle, AssetType::Texture))
|
||||||
{
|
{
|
||||||
// 获取画布区域
|
ImGui::SetCursorScreenPos(m_CanvasOrigin);
|
||||||
ImVec2 canvasMin = ImGui::GetCursorScreenPos();
|
ImGui::InvisibleButton("##canvas_temp_drop", m_CanvasSize,
|
||||||
ImVec2 canvasSize = ImGui::GetContentRegionAvail();
|
|
||||||
|
|
||||||
|
|
||||||
ImGui::SetCursorScreenPos(canvasMin);
|
|
||||||
ImGui::InvisibleButton("##canvas_temp_drop", canvasSize,
|
|
||||||
ImGuiButtonFlags_MouseButtonLeft |
|
ImGuiButtonFlags_MouseButtonLeft |
|
||||||
ImGuiButtonFlags_MouseButtonRight | ImGuiButtonFlags_MouseButtonMiddle);
|
ImGuiButtonFlags_MouseButtonRight | ImGuiButtonFlags_MouseButtonMiddle);
|
||||||
if (ImGui::BeginDragDropTarget())
|
if (ImGui::BeginDragDropTarget())
|
||||||
@ -727,7 +780,6 @@ namespace Prism
|
|||||||
AssetHandle dropHandle = *(AssetHandle*)dropPayload->Data;
|
AssetHandle dropHandle = *(AssetHandle*)dropPayload->Data;
|
||||||
if (AssetsManager::IsAssetType(dropHandle, AssetType::Texture))
|
if (AssetsManager::IsAssetType(dropHandle, AssetType::Texture))
|
||||||
{
|
{
|
||||||
// 将鼠标位置转换为画布坐标,创建节点
|
|
||||||
ImVec2 mousePos = ImGui::GetMousePos();
|
ImVec2 mousePos = ImGui::GetMousePos();
|
||||||
ImVec2 canvasPos = ed::ScreenToCanvas(mousePos);
|
ImVec2 canvasPos = ed::ScreenToCanvas(mousePos);
|
||||||
int newId = m_NextNodeId++;
|
int newId = m_NextNodeId++;
|
||||||
@ -845,6 +897,9 @@ namespace Prism
|
|||||||
m_Asset->RoughnessTexture = getTexture(GetLinkedTextureHandle(InputPinID(Roughness)));
|
m_Asset->RoughnessTexture = getTexture(GetLinkedTextureHandle(InputPinID(Roughness)));
|
||||||
m_Asset->RoughnessTexToggle = m_Asset->RoughnessTexture ? 1.0f : 0.0f;
|
m_Asset->RoughnessTexToggle = m_Asset->RoughnessTexture ? 1.0f : 0.0f;
|
||||||
|
|
||||||
|
m_Asset->AOTexture = getTexture(GetLinkedTextureHandle(InputPinID(AO)));
|
||||||
|
m_Asset->AOTexToggle = m_Asset->AOTexture ? 1.0f : 0.0f;
|
||||||
|
|
||||||
MarkDirty();
|
MarkDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -875,6 +930,7 @@ namespace Prism
|
|||||||
addTextureNode(getHandle(m_Asset->NormalTexture), Normal, 150.0f);
|
addTextureNode(getHandle(m_Asset->NormalTexture), Normal, 150.0f);
|
||||||
addTextureNode(getHandle(m_Asset->MetalnessTexture), Metallic, 300.0f);
|
addTextureNode(getHandle(m_Asset->MetalnessTexture), Metallic, 300.0f);
|
||||||
addTextureNode(getHandle(m_Asset->RoughnessTexture), Roughness, 450.0f);
|
addTextureNode(getHandle(m_Asset->RoughnessTexture), Roughness, 450.0f);
|
||||||
|
addTextureNode(getHandle(m_Asset->AOTexture), AO, 600.0f);
|
||||||
|
|
||||||
m_FirstFrame = true;
|
m_FirstFrame = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -75,6 +75,9 @@ namespace Prism
|
|||||||
bool m_OpenAlbedoPicker = false;
|
bool m_OpenAlbedoPicker = false;
|
||||||
ImVec2 m_AlbedoPickerPos;
|
ImVec2 m_AlbedoPickerPos;
|
||||||
int m_ContextMenuNodeId = 0;
|
int m_ContextMenuNodeId = 0;
|
||||||
|
ImVec2 m_CanvasOrigin = ImVec2(0, 0);
|
||||||
|
ImVec2 m_CanvasSize = ImVec2(0, 0);
|
||||||
|
std::string m_PendingTooltip;
|
||||||
|
|
||||||
// 引脚ID辅助函数
|
// 引脚ID辅助函数
|
||||||
static int InputPinID(int type) { return OUTPUT_NODE_ID * 100 + type; }
|
static int InputPinID(int type) { return OUTPUT_NODE_ID * 100 + type; }
|
||||||
|
|||||||
@ -925,6 +925,7 @@ namespace Prism
|
|||||||
{
|
{
|
||||||
meshComponent.UpdateMaterials(-1, true);
|
meshComponent.UpdateMaterials(-1, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
UI::EndPropertyGrid();
|
UI::EndPropertyGrid();
|
||||||
|
|
||||||
UI::EndTreeNode();
|
UI::EndTreeNode();
|
||||||
|
|||||||
@ -357,6 +357,31 @@ namespace Prism
|
|||||||
glDepthMask(enable ? GL_TRUE : GL_FALSE);
|
glDepthMask(enable ? GL_TRUE : GL_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GLenum MapBlendFactor(BlendFactor factor)
|
||||||
|
{
|
||||||
|
switch (factor)
|
||||||
|
{
|
||||||
|
case BlendFactor::Zero: return GL_ZERO;
|
||||||
|
case BlendFactor::One: return GL_ONE;
|
||||||
|
case BlendFactor::SrcAlpha: return GL_SRC_ALPHA;
|
||||||
|
case BlendFactor::OneMinusSrcAlpha: return GL_ONE_MINUS_SRC_ALPHA;
|
||||||
|
case BlendFactor::DstAlpha: return GL_DST_ALPHA;
|
||||||
|
case BlendFactor::OneMinusDstAlpha: return GL_ONE_MINUS_DST_ALPHA;
|
||||||
|
}
|
||||||
|
return GL_ONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLCommandBuffer::SetBlend(const bool enable) const
|
||||||
|
{
|
||||||
|
if (enable) glEnable(GL_BLEND);
|
||||||
|
else glDisable(GL_BLEND);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLCommandBuffer::SetBlendFunc(BlendFactor src, BlendFactor dst) const
|
||||||
|
{
|
||||||
|
glBlendFunc(MapBlendFactor(src), MapBlendFactor(dst));
|
||||||
|
}
|
||||||
|
|
||||||
void OpenGLCommandBuffer::CopyImageSubData(uint32_t srcTexture, uint32_t dstTexture, uint32_t srcLevel,
|
void OpenGLCommandBuffer::CopyImageSubData(uint32_t srcTexture, uint32_t dstTexture, uint32_t srcLevel,
|
||||||
uint32_t dstLevel, uint32_t srcX, uint32_t srcY, uint32_t srcZ, uint32_t dstX, uint32_t dstY, uint32_t dstZ,
|
uint32_t dstLevel, uint32_t srcX, uint32_t srcY, uint32_t srcZ, uint32_t dstX, uint32_t dstY, uint32_t dstZ,
|
||||||
uint32_t width, uint32_t height, uint32_t depth) const
|
uint32_t width, uint32_t height, uint32_t depth) const
|
||||||
|
|||||||
@ -77,6 +77,8 @@ namespace Prism
|
|||||||
void SetStencilFunc(CompareOp compare, uint32_t ref, uint32_t mask) const override;
|
void SetStencilFunc(CompareOp compare, uint32_t ref, uint32_t mask) const override;
|
||||||
void SetLineSmooth(bool enable) const override;
|
void SetLineSmooth(bool enable) const override;
|
||||||
void SetDepthWrite(bool enable) const override;
|
void SetDepthWrite(bool enable) const override;
|
||||||
|
void SetBlend(bool enable) const override;
|
||||||
|
void SetBlendFunc(BlendFactor src, BlendFactor dst) const override;
|
||||||
|
|
||||||
void CopyImageSubData(uint32_t srcTexture, uint32_t dstTexture, uint32_t srcLevel, uint32_t dstLevel, uint32_t srcX, uint32_t srcY, uint32_t srcZ, uint32_t dstX, uint32_t dstY, uint32_t dstZ, uint32_t width, uint32_t height, uint32_t depth) const override;
|
void CopyImageSubData(uint32_t srcTexture, uint32_t dstTexture, uint32_t srcLevel, uint32_t dstLevel, uint32_t srcX, uint32_t srcY, uint32_t srcZ, uint32_t dstX, uint32_t dstY, uint32_t dstZ, uint32_t width, uint32_t height, uint32_t depth) const override;
|
||||||
int32_t GetUniformLocation(uint32_t program, const std::string& name) const override;
|
int32_t GetUniformLocation(uint32_t program, const std::string& name) const override;
|
||||||
|
|||||||
@ -13,7 +13,7 @@ namespace Prism
|
|||||||
AllocateStorage();
|
AllocateStorage();
|
||||||
|
|
||||||
m_MaterialFlags |= (uint32_t)MaterialFlag::DepthTest;
|
m_MaterialFlags |= (uint32_t)MaterialFlag::DepthTest;
|
||||||
m_MaterialFlags |= (uint32_t)MaterialFlag::Blend;
|
// m_MaterialFlags |= (uint32_t)MaterialFlag::Blend;
|
||||||
}
|
}
|
||||||
|
|
||||||
Material::~Material()
|
Material::~Material()
|
||||||
@ -155,7 +155,6 @@ namespace Prism
|
|||||||
// 复制纹理列表(共享纹理引用)
|
// 复制纹理列表(共享纹理引用)
|
||||||
newInstance->m_Textures = other->m_Textures;
|
newInstance->m_Textures = other->m_Textures;
|
||||||
|
|
||||||
// 复制覆盖标记集合
|
|
||||||
newInstance->m_OverriddenValues = other->m_OverriddenValues;
|
newInstance->m_OverriddenValues = other->m_OverriddenValues;
|
||||||
|
|
||||||
return newInstance;
|
return newInstance;
|
||||||
|
|||||||
@ -212,7 +212,6 @@ namespace Prism
|
|||||||
Buffer m_PSUniformStorageBuffer;
|
Buffer m_PSUniformStorageBuffer;
|
||||||
std::vector<Ref<Texture>> m_Textures;
|
std::vector<Ref<Texture>> m_Textures;
|
||||||
|
|
||||||
// TODO: This is temporary; come up with a proper system to track overrides
|
|
||||||
std::unordered_set<std::string> m_OverriddenValues;
|
std::unordered_set<std::string> m_OverriddenValues;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -460,6 +460,34 @@ namespace Prism
|
|||||||
mi->Set("u_Metalness", metalness);
|
mi->Set("u_Metalness", metalness);
|
||||||
mi->Set("u_MetalnessTexToggle", 0.0f);
|
mi->Set("u_MetalnessTexToggle", 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AO map
|
||||||
|
mi->Set("u_AO", 1.0f);
|
||||||
|
mi->Set("u_AOTexToggle", 0.0f);
|
||||||
|
|
||||||
|
if (aiMaterial->GetTexture(aiTextureType_AMBIENT_OCCLUSION, 0, &aiTexPath) == AI_SUCCESS)
|
||||||
|
{
|
||||||
|
std::filesystem::path path = filename;
|
||||||
|
auto parentPath = path.parent_path();
|
||||||
|
parentPath /= std::string(aiTexPath.data);
|
||||||
|
std::string texturePath = parentPath.string();
|
||||||
|
|
||||||
|
PM_MESH_LOG(" AO map path = {0}", texturePath);
|
||||||
|
auto texture = AssetsManager::TryGetAsset<Texture2D>(texturePath);
|
||||||
|
if (texture && texture->Loaded())
|
||||||
|
{
|
||||||
|
mi->Set("u_AOTexture", texture);
|
||||||
|
mi->Set("u_AOTexToggle", 1.0f);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PM_CORE_ERROR(" Could not load AO texture: {0}", texturePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PM_MESH_LOG(" No AO map");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
PM_MESH_LOG("------------------------");
|
PM_MESH_LOG("------------------------");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,6 +30,7 @@ namespace Prism {
|
|||||||
enum class BlitFilter { Nearest, Linear };
|
enum class BlitFilter { Nearest, Linear };
|
||||||
enum class DataType { UnsignedInt };
|
enum class DataType { UnsignedInt };
|
||||||
enum class BlitMask { Color, Depth, Stencila };
|
enum class BlitMask { Color, Depth, Stencila };
|
||||||
|
enum class BlendFactor { Zero, One, SrcAlpha, OneMinusSrcAlpha, DstAlpha, OneMinusDstAlpha };
|
||||||
|
|
||||||
enum class MemoryBarrierMask {
|
enum class MemoryBarrierMask {
|
||||||
None = 0,
|
None = 0,
|
||||||
@ -98,6 +99,8 @@ namespace Prism {
|
|||||||
virtual void SetStencilFunc(CompareOp compare, uint32_t ref, uint32_t mask) const = 0;
|
virtual void SetStencilFunc(CompareOp compare, uint32_t ref, uint32_t mask) const = 0;
|
||||||
virtual void SetLineSmooth(bool enable) const = 0;
|
virtual void SetLineSmooth(bool enable) const = 0;
|
||||||
virtual void SetDepthWrite(bool enable) const = 0;
|
virtual void SetDepthWrite(bool enable) const = 0;
|
||||||
|
virtual void SetBlend(bool enable) const = 0;
|
||||||
|
virtual void SetBlendFunc(BlendFactor src, BlendFactor dst) const = 0;
|
||||||
|
|
||||||
virtual void CopyImageSubData(uint32_t srcTexture, uint32_t dstTexture,
|
virtual void CopyImageSubData(uint32_t srcTexture, uint32_t dstTexture,
|
||||||
uint32_t srcLevel, uint32_t dstLevel,
|
uint32_t srcLevel, uint32_t dstLevel,
|
||||||
|
|||||||
@ -18,6 +18,8 @@ namespace Prism
|
|||||||
RendererAPIType RendererAPI::s_CurrentRendererAPI = RendererAPIType::OpenGL;
|
RendererAPIType RendererAPI::s_CurrentRendererAPI = RendererAPIType::OpenGL;
|
||||||
Ref<RHIDevice> Renderer::s_Device;
|
Ref<RHIDevice> Renderer::s_Device;
|
||||||
Ref<RHICommandBuffer> Renderer::s_CommandBuffer;
|
Ref<RHICommandBuffer> Renderer::s_CommandBuffer;
|
||||||
|
uint32_t Renderer::s_DrawCallCount = 0;
|
||||||
|
uint32_t Renderer::s_LastFrameDrawCallCount = 0;
|
||||||
|
|
||||||
|
|
||||||
struct RendererData
|
struct RendererData
|
||||||
@ -127,6 +129,8 @@ namespace Prism
|
|||||||
|
|
||||||
void Renderer::WaitAndRender()
|
void Renderer::WaitAndRender()
|
||||||
{
|
{
|
||||||
|
s_LastFrameDrawCallCount = s_DrawCallCount;
|
||||||
|
s_DrawCallCount = 0;
|
||||||
s_Data.m_CommandQueue.Execute();
|
s_Data.m_CommandQueue.Execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,6 +167,7 @@ namespace Prism
|
|||||||
|
|
||||||
void Renderer::SubmitQuad(Ref<MaterialInstance>& material, const glm::mat4& transform)
|
void Renderer::SubmitQuad(Ref<MaterialInstance>& material, const glm::mat4& transform)
|
||||||
{
|
{
|
||||||
|
s_DrawCallCount++;
|
||||||
bool depthTest = true;
|
bool depthTest = true;
|
||||||
bool cullFace = true;
|
bool cullFace = true;
|
||||||
|
|
||||||
@ -185,6 +190,7 @@ namespace Prism
|
|||||||
|
|
||||||
void Renderer::SubmitFullscreenQuad(Ref<MaterialInstance> material)
|
void Renderer::SubmitFullscreenQuad(Ref<MaterialInstance> material)
|
||||||
{
|
{
|
||||||
|
s_DrawCallCount++;
|
||||||
bool depthTest = true;
|
bool depthTest = true;
|
||||||
bool cullFace = true;
|
bool cullFace = true;
|
||||||
if (material)
|
if (material)
|
||||||
@ -203,6 +209,7 @@ namespace Prism
|
|||||||
|
|
||||||
void Renderer::SubmitFullscreenQuad(const bool depthTest, const bool cullFace)
|
void Renderer::SubmitFullscreenQuad(const bool depthTest, const bool cullFace)
|
||||||
{
|
{
|
||||||
|
s_DrawCallCount++;
|
||||||
|
|
||||||
s_Data.m_FullscreenQuadVertexBuffer->Bind();
|
s_Data.m_FullscreenQuadVertexBuffer->Bind();
|
||||||
s_Data.m_FullscreenQuadPipeline->Bind();
|
s_Data.m_FullscreenQuadPipeline->Bind();
|
||||||
@ -213,10 +220,6 @@ namespace Prism
|
|||||||
|
|
||||||
void Renderer::SubmitMesh(Ref<Mesh>& mesh, const glm::mat4& transform, const std::vector<Ref<MaterialInstance>>& overrideMaterials)
|
void Renderer::SubmitMesh(Ref<Mesh>& mesh, const glm::mat4& transform, const std::vector<Ref<MaterialInstance>>& overrideMaterials)
|
||||||
{
|
{
|
||||||
// auto material = overrideMaterial ? overrideMaterial : mesh->GetMaterialInstance();
|
|
||||||
// auto shader = material->GetShader();
|
|
||||||
|
|
||||||
// TODO: Sort this out
|
|
||||||
mesh->m_VertexBuffer->Bind();
|
mesh->m_VertexBuffer->Bind();
|
||||||
mesh->m_Pipeline->Bind();
|
mesh->m_Pipeline->Bind();
|
||||||
mesh->m_IndexBuffer->Bind();
|
mesh->m_IndexBuffer->Bind();
|
||||||
@ -224,8 +227,9 @@ namespace Prism
|
|||||||
const auto& materials = mesh->GetMaterials();
|
const auto& materials = mesh->GetMaterials();
|
||||||
for (Submesh& submesh : mesh->m_Submeshes)
|
for (Submesh& submesh : mesh->m_Submeshes)
|
||||||
{
|
{
|
||||||
// Material
|
|
||||||
auto material = overrideMaterials.empty() ? materials[submesh.MaterialIndex] : overrideMaterials[submesh.MaterialIndex];
|
auto material = overrideMaterials.empty() ? materials[submesh.MaterialIndex] : overrideMaterials[submesh.MaterialIndex];
|
||||||
|
|
||||||
|
s_DrawCallCount++;
|
||||||
auto shader = material->GetShader();
|
auto shader = material->GetShader();
|
||||||
material->Bind();
|
material->Bind();
|
||||||
|
|
||||||
@ -242,12 +246,10 @@ namespace Prism
|
|||||||
|
|
||||||
auto cmd = s_CommandBuffer;
|
auto cmd = s_CommandBuffer;
|
||||||
Submit([cmd, submesh, material]() {
|
Submit([cmd, submesh, material]() {
|
||||||
// 状态设置通过 cmd
|
|
||||||
cmd->SetDepthTest(material->GetFlag(MaterialFlag::DepthTest));
|
cmd->SetDepthTest(material->GetFlag(MaterialFlag::DepthTest));
|
||||||
cmd->SetDepthFunc(CompareOp::LessEqual); // 对应 GL_LEQUAL
|
cmd->SetDepthFunc(CompareOp::LessEqual);
|
||||||
cmd->SetCullMode(material->GetFlag(MaterialFlag::TwoSided) ? CullMode::None : CullMode::Back);
|
cmd->SetCullMode(material->GetFlag(MaterialFlag::TwoSided) ? CullMode::None : CullMode::Back);
|
||||||
|
|
||||||
// 绘制
|
|
||||||
cmd->DrawIndexed(PrimitiveType::Triangles, submesh.IndexCount, 1, submesh.BaseIndex, submesh.BaseVertex, 0);
|
cmd->DrawIndexed(PrimitiveType::Triangles, submesh.IndexCount, 1, submesh.BaseIndex, submesh.BaseVertex, 0);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -255,10 +257,6 @@ namespace Prism
|
|||||||
|
|
||||||
void Renderer::SubmitMesh(Ref<Mesh>& mesh, const glm::mat4& transform, const Ref<MaterialInstance>& overrideMaterial)
|
void Renderer::SubmitMesh(Ref<Mesh>& mesh, const glm::mat4& transform, const Ref<MaterialInstance>& overrideMaterial)
|
||||||
{
|
{
|
||||||
// auto material = overrideMaterial ? overrideMaterial : mesh->GetMaterialInstance();
|
|
||||||
// auto shader = material->GetShader();
|
|
||||||
|
|
||||||
// TODO: Sort this out
|
|
||||||
mesh->m_VertexBuffer->Bind();
|
mesh->m_VertexBuffer->Bind();
|
||||||
mesh->m_Pipeline->Bind();
|
mesh->m_Pipeline->Bind();
|
||||||
mesh->m_IndexBuffer->Bind();
|
mesh->m_IndexBuffer->Bind();
|
||||||
@ -266,8 +264,9 @@ namespace Prism
|
|||||||
const auto& materials = mesh->GetMaterials();
|
const auto& materials = mesh->GetMaterials();
|
||||||
for (Submesh& submesh : mesh->m_Submeshes)
|
for (Submesh& submesh : mesh->m_Submeshes)
|
||||||
{
|
{
|
||||||
// Material
|
|
||||||
auto material = overrideMaterial ? overrideMaterial : materials[submesh.MaterialIndex];
|
auto material = overrideMaterial ? overrideMaterial : materials[submesh.MaterialIndex];
|
||||||
|
|
||||||
|
s_DrawCallCount++;
|
||||||
auto shader = material->GetShader();
|
auto shader = material->GetShader();
|
||||||
material->Bind();
|
material->Bind();
|
||||||
|
|
||||||
@ -300,6 +299,7 @@ namespace Prism
|
|||||||
|
|
||||||
for (Submesh& submesh : mesh->m_Submeshes)
|
for (Submesh& submesh : mesh->m_Submeshes)
|
||||||
{
|
{
|
||||||
|
s_DrawCallCount++;
|
||||||
if (mesh->m_IsAnimated)
|
if (mesh->m_IsAnimated)
|
||||||
{
|
{
|
||||||
const auto& boneTransform = mesh->GetBoneTransforms();
|
const auto& boneTransform = mesh->GetBoneTransforms();
|
||||||
|
|||||||
@ -70,11 +70,15 @@ namespace Prism
|
|||||||
static void DrawAABB(const Ref<Mesh>& mesh,const glm::mat4& transform, const glm::vec4& color = glm::vec4(1.0f));
|
static void DrawAABB(const Ref<Mesh>& mesh,const glm::mat4& transform, const glm::vec4& color = glm::vec4(1.0f));
|
||||||
static void DispatchCompute(int x, int y, int z);
|
static void DispatchCompute(int x, int y, int z);
|
||||||
|
|
||||||
|
static uint32_t GetDrawCallCount() { return s_LastFrameDrawCallCount; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static RenderCommandQueue& GetRenderCommandQueue();
|
static RenderCommandQueue& GetRenderCommandQueue();
|
||||||
|
|
||||||
static Ref<RHIDevice> s_Device;
|
static Ref<RHIDevice> s_Device;
|
||||||
static Ref<RHICommandBuffer> s_CommandBuffer;
|
static Ref<RHICommandBuffer> s_CommandBuffer;
|
||||||
|
static uint32_t s_DrawCallCount;
|
||||||
|
static uint32_t s_LastFrameDrawCallCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
#include "Renderer3D.h"
|
#include "Renderer3D.h"
|
||||||
|
|
||||||
#include "Prism/Core/Timer.h"
|
#include "Prism/Core/Timer.h"
|
||||||
|
#include "Prism/Core/Math/Frustum.h"
|
||||||
#include "Prism/Scene/Scene.h"
|
#include "Prism/Scene/Scene.h"
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
@ -116,8 +117,10 @@ namespace Prism
|
|||||||
Ref<Mesh> mesh;
|
Ref<Mesh> mesh;
|
||||||
std::vector<Ref<MaterialInstance>> MaterialInstances;
|
std::vector<Ref<MaterialInstance>> MaterialInstances;
|
||||||
glm::mat4 Transform;
|
glm::mat4 Transform;
|
||||||
|
float DistanceFromCamera = 0.0f;
|
||||||
};
|
};
|
||||||
std::vector<DrawCommand> DrawList;
|
std::vector<DrawCommand> DrawList;
|
||||||
|
std::vector<DrawCommand> TransparentDrawList;
|
||||||
std::vector<DrawCommand> SelectedMeshDrawList;
|
std::vector<DrawCommand> SelectedMeshDrawList;
|
||||||
std::vector<DrawCommand> ColliderDrawList;
|
std::vector<DrawCommand> ColliderDrawList;
|
||||||
std::vector<DrawCommand> ShadowPassDrawList;
|
std::vector<DrawCommand> ShadowPassDrawList;
|
||||||
@ -145,7 +148,9 @@ namespace Prism
|
|||||||
float Intensity = 1.0f;
|
float Intensity = 1.0f;
|
||||||
float MaxDistance = 30.0f;
|
float MaxDistance = 30.0f;
|
||||||
float Thickness = 0.5f;
|
float Thickness = 0.5f;
|
||||||
int Steps = 64;
|
float StepSize = 0.5f;
|
||||||
|
float RayOffset = 0.1f;
|
||||||
|
int Steps = 32;
|
||||||
float BlurRadius = 4.0f;
|
float BlurRadius = 4.0f;
|
||||||
|
|
||||||
Ref<Shader> SSRShader;
|
Ref<Shader> SSRShader;
|
||||||
@ -158,6 +163,13 @@ namespace Prism
|
|||||||
|
|
||||||
SceneRendererOptions Options;
|
SceneRendererOptions Options;
|
||||||
|
|
||||||
|
Frustum CameraFrustum;
|
||||||
|
|
||||||
|
uint32_t MeshesSubmitted = 0;
|
||||||
|
uint32_t MeshesCulled = 0;
|
||||||
|
uint32_t LastFrameMeshesSubmitted = 0;
|
||||||
|
uint32_t LastFrameMeshesCulled = 0;
|
||||||
|
|
||||||
Ref<TextureCube> BlackCubeTexture;
|
Ref<TextureCube> BlackCubeTexture;
|
||||||
Ref<Texture2D> BlackTexture;
|
Ref<Texture2D> BlackTexture;
|
||||||
};
|
};
|
||||||
@ -351,6 +363,9 @@ namespace Prism
|
|||||||
s_Data.SceneData.SceneEnvironment = scene->m_Environment;
|
s_Data.SceneData.SceneEnvironment = scene->m_Environment;
|
||||||
s_Data.SceneData.SceneEnvironmentIntensity = scene->m_EnvironmentIntensity;
|
s_Data.SceneData.SceneEnvironmentIntensity = scene->m_EnvironmentIntensity;
|
||||||
s_Data.SceneData.SceneLightEnvironment = scene->m_LightEnvironment;
|
s_Data.SceneData.SceneLightEnvironment = scene->m_LightEnvironment;
|
||||||
|
|
||||||
|
glm::mat4 vp = camera.Camera.GetProjectionMatrix() * camera.ViewMatrix;
|
||||||
|
s_Data.CameraFrustum = Frustum::FromViewProjection(vp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer3D::EndScene(Ref<RenderPass>& renderPass)
|
void Renderer3D::EndScene(Ref<RenderPass>& renderPass)
|
||||||
@ -360,14 +375,51 @@ namespace Prism
|
|||||||
|
|
||||||
void Renderer3D::SubmitMesh(const Ref<Mesh>& mesh, const glm::mat4& transform, const std::vector<Ref<MaterialInstance>>& overrideMaterials)
|
void Renderer3D::SubmitMesh(const Ref<Mesh>& mesh, const glm::mat4& transform, const std::vector<Ref<MaterialInstance>>& overrideMaterials)
|
||||||
{
|
{
|
||||||
// TODO: Culling, sorting, etc.
|
s_Data.MeshesSubmitted++;
|
||||||
|
|
||||||
|
AABB worldAABB = mesh->GetBoundingBox().Transform(transform);
|
||||||
|
if (!s_Data.CameraFrustum.IsInside(worldAABB))
|
||||||
|
{
|
||||||
|
s_Data.MeshesCulled++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isTransparent = false;
|
||||||
|
if (!overrideMaterials.empty())
|
||||||
|
{
|
||||||
|
for (auto& mi : overrideMaterials)
|
||||||
|
{
|
||||||
|
if (mi && mi->GetFlag(MaterialFlag::Blend))
|
||||||
|
{
|
||||||
|
isTransparent = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto& materials = mesh->GetMaterials();
|
||||||
|
for (auto& mi : materials)
|
||||||
|
{
|
||||||
|
if (mi && mi->GetFlag(MaterialFlag::Blend))
|
||||||
|
{
|
||||||
|
isTransparent = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isTransparent)
|
||||||
|
s_Data.TransparentDrawList.push_back({ mesh, overrideMaterials, transform });
|
||||||
|
else
|
||||||
|
s_Data.DrawList.push_back({ mesh, overrideMaterials, transform });
|
||||||
|
|
||||||
s_Data.DrawList.push_back({ mesh, overrideMaterials, transform });
|
|
||||||
s_Data.ShadowPassDrawList.push_back({ mesh, overrideMaterials, transform });
|
s_Data.ShadowPassDrawList.push_back({ mesh, overrideMaterials, transform });
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer3D::SubmitSelectedMesh(const Ref<Mesh>& mesh, const glm::mat4& transform, const std::vector<Ref<MaterialInstance>>& overrideMaterials)
|
void Renderer3D::SubmitSelectedMesh(const Ref<Mesh>& mesh, const glm::mat4& transform, const std::vector<Ref<MaterialInstance>>& overrideMaterials)
|
||||||
{
|
{
|
||||||
|
s_Data.MeshesSubmitted++;
|
||||||
s_Data.SelectedMeshDrawList.push_back({ mesh, overrideMaterials, transform });
|
s_Data.SelectedMeshDrawList.push_back({ mesh, overrideMaterials, transform });
|
||||||
s_Data.ShadowPassDrawList.push_back({ mesh, overrideMaterials, transform });
|
s_Data.ShadowPassDrawList.push_back({ mesh, overrideMaterials, transform });
|
||||||
}
|
}
|
||||||
@ -572,10 +624,15 @@ namespace Prism
|
|||||||
}
|
}
|
||||||
|
|
||||||
s_Data.DrawList.clear();
|
s_Data.DrawList.clear();
|
||||||
|
s_Data.TransparentDrawList.clear();
|
||||||
s_Data.SelectedMeshDrawList.clear();
|
s_Data.SelectedMeshDrawList.clear();
|
||||||
s_Data.ColliderDrawList.clear();
|
s_Data.ColliderDrawList.clear();
|
||||||
s_Data.ShadowPassDrawList.clear();
|
s_Data.ShadowPassDrawList.clear();
|
||||||
s_Data.SceneData = {};
|
s_Data.SceneData = {};
|
||||||
|
s_Data.LastFrameMeshesSubmitted = s_Data.MeshesSubmitted;
|
||||||
|
s_Data.LastFrameMeshesCulled = s_Data.MeshesCulled;
|
||||||
|
s_Data.MeshesSubmitted = 0;
|
||||||
|
s_Data.MeshesCulled = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer3D::AutoExposurePass()
|
void Renderer3D::AutoExposurePass()
|
||||||
@ -1321,15 +1378,21 @@ namespace Prism
|
|||||||
|
|
||||||
const auto& sceneCamera = s_Data.SceneData.SceneCamera;
|
const auto& sceneCamera = s_Data.SceneData.SceneCamera;
|
||||||
const auto cameraProjection = sceneCamera.Camera.GetProjectionMatrix();
|
const auto cameraProjection = sceneCamera.Camera.GetProjectionMatrix();
|
||||||
|
const auto viewMatrix = sceneCamera.ViewMatrix;
|
||||||
|
const glm::vec3 cameraPosition = glm::inverse(viewMatrix)[3];
|
||||||
|
|
||||||
s_Data.SSRData.SSRShader->SetMat4("u_Projection", cameraProjection);
|
s_Data.SSRData.SSRShader->SetMat4("u_Projection", cameraProjection);
|
||||||
s_Data.SSRData.SSRShader->SetMat4("u_InvProjection", glm::inverse(cameraProjection));
|
s_Data.SSRData.SSRShader->SetMat4("u_View", viewMatrix);
|
||||||
|
s_Data.SSRData.SSRShader->SetMat4("u_InvViewProjection", glm::inverse(cameraProjection * viewMatrix));
|
||||||
|
s_Data.SSRData.SSRShader->SetFloat3("u_CameraPosition", cameraPosition);
|
||||||
s_Data.SSRData.SSRShader->SetFloat2("u_ScreenSize", glm::vec2((float)width, (float)height));
|
s_Data.SSRData.SSRShader->SetFloat2("u_ScreenSize", glm::vec2((float)width, (float)height));
|
||||||
s_Data.SSRData.SSRShader->SetFloat("u_CameraNear", sceneCamera.Camera.GetNear());
|
s_Data.SSRData.SSRShader->SetFloat("u_CameraNear", sceneCamera.Camera.GetNear());
|
||||||
s_Data.SSRData.SSRShader->SetFloat("u_CameraFar", sceneCamera.Camera.GetFar());
|
s_Data.SSRData.SSRShader->SetFloat("u_CameraFar", sceneCamera.Camera.GetFar());
|
||||||
s_Data.SSRData.SSRShader->SetInt("u_Steps", s_Data.SSRData.Steps);
|
s_Data.SSRData.SSRShader->SetInt("u_Steps", s_Data.SSRData.Steps);
|
||||||
s_Data.SSRData.SSRShader->SetFloat("u_MaxDistance", s_Data.SSRData.MaxDistance);
|
s_Data.SSRData.SSRShader->SetFloat("u_MaxDistance", s_Data.SSRData.MaxDistance);
|
||||||
s_Data.SSRData.SSRShader->SetFloat("u_Thickness", s_Data.SSRData.Thickness);
|
s_Data.SSRData.SSRShader->SetFloat("u_Thickness", s_Data.SSRData.Thickness);
|
||||||
|
s_Data.SSRData.SSRShader->SetFloat("u_StepSize", s_Data.SSRData.StepSize);
|
||||||
|
s_Data.SSRData.SSRShader->SetFloat("u_RayOffset", s_Data.SSRData.RayOffset);
|
||||||
s_Data.SSRData.SSRShader->SetFloat("u_Intensity", s_Data.SSRData.Intensity);
|
s_Data.SSRData.SSRShader->SetFloat("u_Intensity", s_Data.SSRData.Intensity);
|
||||||
|
|
||||||
Renderer::SubmitFullscreenQuad(nullptr);
|
Renderer::SubmitFullscreenQuad(nullptr);
|
||||||
@ -1381,8 +1444,12 @@ namespace Prism
|
|||||||
{
|
{
|
||||||
ImGui::Begin("Scene Renderer");
|
ImGui::Begin("Scene Renderer");
|
||||||
|
|
||||||
|
ImGui::Text("Draw Calls: %u", Renderer::GetDrawCallCount());
|
||||||
|
ImGui::Text("Meshes Submitted: %u", s_Data.LastFrameMeshesSubmitted);
|
||||||
|
ImGui::Text("Meshes Culled: %u", s_Data.LastFrameMeshesCulled);
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
UI::Property("Geometry Pass time", s_Stats.GeometryPass);
|
UI::Property("Geometry Pass time", s_Stats.GeometryPass);
|
||||||
UI::Property("Composite Pass time", s_Stats.CompositePass);
|
UI::Property("Composite Pass time", s_Stats.CompositePass);
|
||||||
UI::Property("Shadow Pass time", s_Stats.ShadowPass);
|
UI::Property("Shadow Pass time", s_Stats.ShadowPass);
|
||||||
UI::Property("AutoExposure Pass time", s_Stats.AutoExposurePass);
|
UI::Property("AutoExposure Pass time", s_Stats.AutoExposurePass);
|
||||||
@ -1574,6 +1641,8 @@ namespace Prism
|
|||||||
UI::Property("Max Distance", s_Data.SSRData.MaxDistance, 0.1f, 1.0f, 200.0f);
|
UI::Property("Max Distance", s_Data.SSRData.MaxDistance, 0.1f, 1.0f, 200.0f);
|
||||||
UI::Property("Thickness", s_Data.SSRData.Thickness, 0.01f, 0.01f, 5.0f);
|
UI::Property("Thickness", s_Data.SSRData.Thickness, 0.01f, 0.01f, 5.0f);
|
||||||
UI::PropertySlider("Steps", s_Data.SSRData.Steps, 1, 128);
|
UI::PropertySlider("Steps", s_Data.SSRData.Steps, 1, 128);
|
||||||
|
UI::Property("Step Size", s_Data.SSRData.StepSize, 0.01f, 0.01f, 5.0f);
|
||||||
|
UI::Property("Ray Offset", s_Data.SSRData.RayOffset, 0.01f, 0.0f, 1.0f);
|
||||||
UI::Property("Blur Radius", s_Data.SSRData.BlurRadius, 0.1f, 0.0f, 10.0f);
|
UI::Property("Blur Radius", s_Data.SSRData.BlurRadius, 0.1f, 0.0f, 10.0f);
|
||||||
}
|
}
|
||||||
UI::EndPropertyGrid();
|
UI::EndPropertyGrid();
|
||||||
|
|||||||
@ -143,6 +143,9 @@ namespace Prism
|
|||||||
MaterialInstances[i]->Set("u_Roughness", desc->Roughness);
|
MaterialInstances[i]->Set("u_Roughness", desc->Roughness);
|
||||||
MaterialInstances[i]->Set("u_RoughnessTexToggle", desc->RoughnessTexToggle);
|
MaterialInstances[i]->Set("u_RoughnessTexToggle", desc->RoughnessTexToggle);
|
||||||
MaterialInstances[i]->Set("u_RoughnessTexture", desc->RoughnessTexture);
|
MaterialInstances[i]->Set("u_RoughnessTexture", desc->RoughnessTexture);
|
||||||
|
MaterialInstances[i]->Set("u_AO", desc->AO);
|
||||||
|
MaterialInstances[i]->Set("u_AOTexToggle", desc->AOTexToggle);
|
||||||
|
MaterialInstances[i]->Set("u_AOTexture", desc->AOTexture);
|
||||||
}else
|
}else
|
||||||
{
|
{
|
||||||
auto& baseMaterial = Mesh->GetMaterials();
|
auto& baseMaterial = Mesh->GetMaterials();
|
||||||
@ -158,6 +161,9 @@ namespace Prism
|
|||||||
MaterialInstances[i]->Set("u_Roughness", baseMaterial[0]->Get<float>("u_Roughness"));
|
MaterialInstances[i]->Set("u_Roughness", baseMaterial[0]->Get<float>("u_Roughness"));
|
||||||
MaterialInstances[i]->Set("u_RoughnessTexToggle", baseMaterial[i]->Get<float>("u_RoughnessTexToggle"));
|
MaterialInstances[i]->Set("u_RoughnessTexToggle", baseMaterial[i]->Get<float>("u_RoughnessTexToggle"));
|
||||||
MaterialInstances[i]->Set("u_RoughnessTexture", baseMaterial[i]->TryGetResource<Texture2D>("u_RoughnessTexture"));
|
MaterialInstances[i]->Set("u_RoughnessTexture", baseMaterial[i]->TryGetResource<Texture2D>("u_RoughnessTexture"));
|
||||||
|
MaterialInstances[i]->Set("u_AO", baseMaterial[i]->Get<float>("u_AO"));
|
||||||
|
MaterialInstances[i]->Set("u_AOTexToggle", baseMaterial[i]->Get<float>("u_AOTexToggle"));
|
||||||
|
MaterialInstances[i]->Set("u_AOTexture", baseMaterial[i]->TryGetResource<Texture2D>("u_AOTexture"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else
|
}else
|
||||||
@ -177,6 +183,9 @@ namespace Prism
|
|||||||
MaterialInstances[index]->Set("u_Roughness", desc->Roughness);
|
MaterialInstances[index]->Set("u_Roughness", desc->Roughness);
|
||||||
MaterialInstances[index]->Set("u_RoughnessTexToggle", desc->RoughnessTexToggle);
|
MaterialInstances[index]->Set("u_RoughnessTexToggle", desc->RoughnessTexToggle);
|
||||||
MaterialInstances[index]->Set("u_RoughnessTexture", desc->RoughnessTexture);
|
MaterialInstances[index]->Set("u_RoughnessTexture", desc->RoughnessTexture);
|
||||||
|
MaterialInstances[index]->Set("u_AO", desc->AO);
|
||||||
|
MaterialInstances[index]->Set("u_AOTexToggle", desc->AOTexToggle);
|
||||||
|
MaterialInstances[index]->Set("u_AOTexture", desc->AOTexture);
|
||||||
}else
|
}else
|
||||||
{
|
{
|
||||||
auto& baseMaterial = Mesh->GetMaterials();
|
auto& baseMaterial = Mesh->GetMaterials();
|
||||||
@ -192,6 +201,9 @@ namespace Prism
|
|||||||
MaterialInstances[index]->Set("u_Roughness", baseMaterial[0]->Get<float>("u_Roughness"));
|
MaterialInstances[index]->Set("u_Roughness", baseMaterial[0]->Get<float>("u_Roughness"));
|
||||||
MaterialInstances[index]->Set("u_RoughnessTexToggle", baseMaterial[index]->Get<float>("u_RoughnessTexToggle"));
|
MaterialInstances[index]->Set("u_RoughnessTexToggle", baseMaterial[index]->Get<float>("u_RoughnessTexToggle"));
|
||||||
MaterialInstances[index]->Set("u_RoughnessTexture", baseMaterial[index]->TryGetResource<Texture2D>("u_RoughnessTexture"));
|
MaterialInstances[index]->Set("u_RoughnessTexture", baseMaterial[index]->TryGetResource<Texture2D>("u_RoughnessTexture"));
|
||||||
|
MaterialInstances[index]->Set("u_AO", baseMaterial[index]->Get<float>("u_AO"));
|
||||||
|
MaterialInstances[index]->Set("u_AOTexToggle", baseMaterial[index]->Get<float>("u_AOTexToggle"));
|
||||||
|
MaterialInstances[index]->Set("u_AOTexture", baseMaterial[index]->TryGetResource<Texture2D>("u_AOTexture"));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user