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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
vec3 hitNormalWS = ReconstructNormalFromDepth(rayNDC.xy, sceneDepth);
|
||||
if (dot(hitNormalWS, reflectionWS) > 0.0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
o_Color = vec4(0.0);
|
||||
return;
|
||||
}
|
||||
float ssrStrength = saturate(1.0 - roughness * roughness);
|
||||
|
||||
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 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.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);
|
||||
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);
|
||||
|
||||
vec3 F0 = mix(vec3(0.04), reflectColor, metalness);
|
||||
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);
|
||||
|
||||
float roughnessFade = 1.0 - roughness * roughness;
|
||||
ssrStrength *= fadeFactor * edgeFade * u_Intensity;
|
||||
|
||||
vec3 ssrContrib = reflectColor * Fresnel * fadeFactor * edgeFade * roughnessFade * u_Intensity;
|
||||
float ssrAlpha = length(Fresnel) * fadeFactor * edgeFade * roughnessFade;
|
||||
vec4 color = texture(u_ColorTexture, rayNDC.xy);
|
||||
color.rgb *= ssrStrength * Fresnel;
|
||||
color.a = ssrStrength * dot(Fresnel, vec3(0.333));
|
||||
|
||||
o_Color = vec4(ssrContrib, ssrAlpha);
|
||||
o_Color = color;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
o_Color = vec4(0.0);
|
||||
}
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
@ -81,15 +81,20 @@ namespace Prism
|
||||
Ref<Texture2D> NormalTexture;
|
||||
|
||||
// Metalness
|
||||
float Metalness = 0.8f;
|
||||
float Metalness = 0.2f;
|
||||
float MetalnessTexToggle = 0.0f;
|
||||
Ref<Texture2D> MetalnessTexture;
|
||||
|
||||
// Roughness
|
||||
float Roughness = 0.1f;
|
||||
float Roughness = 1.0f;
|
||||
float RoughnessTexToggle = 0.0f;
|
||||
Ref<Texture2D> RoughnessTexture;
|
||||
|
||||
// AO
|
||||
float AO = 1.0f;
|
||||
float AOTexToggle = 0.0f;
|
||||
Ref<Texture2D> AOTexture;
|
||||
|
||||
bool IsDirty = true;
|
||||
bool PreviewIsDirty = true;
|
||||
|
||||
|
||||
@ -123,7 +123,7 @@ namespace Prism
|
||||
out << YAML::Key << "Roughness";
|
||||
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 << "Texture";
|
||||
@ -142,6 +142,29 @@ namespace Prism
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
#define PRISM_AABB_H
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <limits>
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
@ -23,6 +24,28 @@ namespace Prism
|
||||
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.
|
||||
//
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
#include "Prism/Renderer/RHI/RHICommandBuffer.h"
|
||||
#include "Prism/Renderer/SceneRenderer.h"
|
||||
#include "Prism/Scene/Scene.h"
|
||||
#include "Prism/Utilities/StringUtils.h"
|
||||
|
||||
namespace Prism
|
||||
{
|
||||
@ -150,15 +151,18 @@ namespace Prism
|
||||
matInst->Set("u_AlbedoColor", materialAsset->AlbedoColor);
|
||||
matInst->Set("u_Metalness", materialAsset->Metalness);
|
||||
matInst->Set("u_Roughness", materialAsset->Roughness);
|
||||
matInst->Set("u_AO", materialAsset->AO);
|
||||
matInst->Set("u_AlbedoTexToggle", materialAsset->AlbedoTexToggle);
|
||||
matInst->Set("u_NormalTexToggle", materialAsset->NormalTexToggle);
|
||||
matInst->Set("u_MetalnessTexToggle", materialAsset->MetalnessTexToggle);
|
||||
matInst->Set("u_RoughnessTexToggle", materialAsset->RoughnessTexToggle);
|
||||
matInst->Set("u_AOTexToggle", materialAsset->AOTexToggle);
|
||||
|
||||
matInst->Set("u_AlbedoTexture", materialAsset->AlbedoTexture);
|
||||
matInst->Set("u_NormalTexture", materialAsset->NormalTexture);
|
||||
matInst->Set("u_MetalnessTexture", materialAsset->MetalnessTexture);
|
||||
matInst->Set("u_RoughnessTexture", materialAsset->RoughnessTexture);
|
||||
matInst->Set("u_AOTexture", materialAsset->AOTexture);
|
||||
|
||||
float aspect = (float)s_PreviewRenderPass->GetSpecification().TargetFramebuffer->GetWidth() /
|
||||
(float)s_PreviewRenderPass->GetSpecification().TargetFramebuffer->GetHeight();
|
||||
@ -330,7 +334,6 @@ namespace Prism
|
||||
|
||||
if (ImGui::SliderFloat("Value##Roughness", &material->Roughness, 0.0f, 1.0f))
|
||||
{
|
||||
// 自动保存
|
||||
MarkDirty();
|
||||
}
|
||||
|
||||
@ -352,6 +355,35 @@ namespace Prism
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
m_CanvasOrigin = ImGui::GetCursorScreenPos();
|
||||
m_CanvasSize = ImGui::GetContentRegionAvail();
|
||||
|
||||
ed::Begin("MaterialNodeEditor");
|
||||
|
||||
if (m_FirstFrame)
|
||||
@ -518,10 +553,8 @@ namespace Prism
|
||||
drawInputPin(AO, "AO", [&]()
|
||||
{
|
||||
ImGui::SetNextItemWidth(80);
|
||||
float ao = 1.0f; // 如果资产没有 AO 字段可以忽略
|
||||
if (ImGui::SliderFloat("##ao", &ao, 0.0f, 1.0f))
|
||||
{
|
||||
}
|
||||
if (ImGui::SliderFloat("##ao", &m_Asset->AO, 0.0f, 1.0f))
|
||||
MarkDirty();
|
||||
});
|
||||
|
||||
ImGui::EndGroup();
|
||||
@ -550,10 +583,24 @@ namespace Prism
|
||||
|
||||
ImVec2 headerMin = ImGui::GetCursorScreenPos();
|
||||
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 offsetX = (nodeWidth - previewSize) * 0.5f;
|
||||
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));
|
||||
else
|
||||
ImGui::Dummy(ImVec2(previewSize, previewSize));
|
||||
|
||||
if (ImGui::IsItemHovered() && tex)
|
||||
m_PendingTooltip = Utils::GetFilename(tex->GetPath());
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -705,19 +755,22 @@ namespace Prism
|
||||
|
||||
ed::Suspend();
|
||||
|
||||
if (!m_PendingTooltip.empty())
|
||||
{
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::TextUnformatted(m_PendingTooltip.c_str());
|
||||
ImGui::EndTooltip();
|
||||
m_PendingTooltip.clear();
|
||||
}
|
||||
|
||||
const ImGuiPayload* payload = ImGui::GetDragDropPayload();
|
||||
if (payload && payload->IsDataType("asset_payload"))
|
||||
{
|
||||
AssetHandle handle = *(AssetHandle*)payload->Data;
|
||||
if (AssetsManager::IsAssetType(handle, AssetType::Texture))
|
||||
{
|
||||
// 获取画布区域
|
||||
ImVec2 canvasMin = ImGui::GetCursorScreenPos();
|
||||
ImVec2 canvasSize = ImGui::GetContentRegionAvail();
|
||||
|
||||
|
||||
ImGui::SetCursorScreenPos(canvasMin);
|
||||
ImGui::InvisibleButton("##canvas_temp_drop", canvasSize,
|
||||
ImGui::SetCursorScreenPos(m_CanvasOrigin);
|
||||
ImGui::InvisibleButton("##canvas_temp_drop", m_CanvasSize,
|
||||
ImGuiButtonFlags_MouseButtonLeft |
|
||||
ImGuiButtonFlags_MouseButtonRight | ImGuiButtonFlags_MouseButtonMiddle);
|
||||
if (ImGui::BeginDragDropTarget())
|
||||
@ -727,7 +780,6 @@ namespace Prism
|
||||
AssetHandle dropHandle = *(AssetHandle*)dropPayload->Data;
|
||||
if (AssetsManager::IsAssetType(dropHandle, AssetType::Texture))
|
||||
{
|
||||
// 将鼠标位置转换为画布坐标,创建节点
|
||||
ImVec2 mousePos = ImGui::GetMousePos();
|
||||
ImVec2 canvasPos = ed::ScreenToCanvas(mousePos);
|
||||
int newId = m_NextNodeId++;
|
||||
@ -845,6 +897,9 @@ namespace Prism
|
||||
m_Asset->RoughnessTexture = getTexture(GetLinkedTextureHandle(InputPinID(Roughness)));
|
||||
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();
|
||||
}
|
||||
|
||||
@ -875,6 +930,7 @@ namespace Prism
|
||||
addTextureNode(getHandle(m_Asset->NormalTexture), Normal, 150.0f);
|
||||
addTextureNode(getHandle(m_Asset->MetalnessTexture), Metallic, 300.0f);
|
||||
addTextureNode(getHandle(m_Asset->RoughnessTexture), Roughness, 450.0f);
|
||||
addTextureNode(getHandle(m_Asset->AOTexture), AO, 600.0f);
|
||||
|
||||
m_FirstFrame = true;
|
||||
}
|
||||
|
||||
@ -75,6 +75,9 @@ namespace Prism
|
||||
bool m_OpenAlbedoPicker = false;
|
||||
ImVec2 m_AlbedoPickerPos;
|
||||
int m_ContextMenuNodeId = 0;
|
||||
ImVec2 m_CanvasOrigin = ImVec2(0, 0);
|
||||
ImVec2 m_CanvasSize = ImVec2(0, 0);
|
||||
std::string m_PendingTooltip;
|
||||
|
||||
// 引脚ID辅助函数
|
||||
static int InputPinID(int type) { return OUTPUT_NODE_ID * 100 + type; }
|
||||
|
||||
@ -925,6 +925,7 @@ namespace Prism
|
||||
{
|
||||
meshComponent.UpdateMaterials(-1, true);
|
||||
}
|
||||
|
||||
UI::EndPropertyGrid();
|
||||
|
||||
UI::EndTreeNode();
|
||||
|
||||
@ -357,6 +357,31 @@ namespace Prism
|
||||
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,
|
||||
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
|
||||
|
||||
@ -77,6 +77,8 @@ namespace Prism
|
||||
void SetStencilFunc(CompareOp compare, uint32_t ref, uint32_t mask) const override;
|
||||
void SetLineSmooth(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;
|
||||
int32_t GetUniformLocation(uint32_t program, const std::string& name) const override;
|
||||
|
||||
@ -13,7 +13,7 @@ namespace Prism
|
||||
AllocateStorage();
|
||||
|
||||
m_MaterialFlags |= (uint32_t)MaterialFlag::DepthTest;
|
||||
m_MaterialFlags |= (uint32_t)MaterialFlag::Blend;
|
||||
// m_MaterialFlags |= (uint32_t)MaterialFlag::Blend;
|
||||
}
|
||||
|
||||
Material::~Material()
|
||||
@ -155,7 +155,6 @@ namespace Prism
|
||||
// 复制纹理列表(共享纹理引用)
|
||||
newInstance->m_Textures = other->m_Textures;
|
||||
|
||||
// 复制覆盖标记集合
|
||||
newInstance->m_OverriddenValues = other->m_OverriddenValues;
|
||||
|
||||
return newInstance;
|
||||
|
||||
@ -212,7 +212,6 @@ namespace Prism
|
||||
Buffer m_PSUniformStorageBuffer;
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
@ -460,6 +460,34 @@ namespace Prism
|
||||
mi->Set("u_Metalness", metalness);
|
||||
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("------------------------");
|
||||
}
|
||||
|
||||
@ -30,6 +30,7 @@ namespace Prism {
|
||||
enum class BlitFilter { Nearest, Linear };
|
||||
enum class DataType { UnsignedInt };
|
||||
enum class BlitMask { Color, Depth, Stencila };
|
||||
enum class BlendFactor { Zero, One, SrcAlpha, OneMinusSrcAlpha, DstAlpha, OneMinusDstAlpha };
|
||||
|
||||
enum class MemoryBarrierMask {
|
||||
None = 0,
|
||||
@ -98,6 +99,8 @@ namespace Prism {
|
||||
virtual void SetStencilFunc(CompareOp compare, uint32_t ref, uint32_t mask) const = 0;
|
||||
virtual void SetLineSmooth(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,
|
||||
uint32_t srcLevel, uint32_t dstLevel,
|
||||
|
||||
@ -18,6 +18,8 @@ namespace Prism
|
||||
RendererAPIType RendererAPI::s_CurrentRendererAPI = RendererAPIType::OpenGL;
|
||||
Ref<RHIDevice> Renderer::s_Device;
|
||||
Ref<RHICommandBuffer> Renderer::s_CommandBuffer;
|
||||
uint32_t Renderer::s_DrawCallCount = 0;
|
||||
uint32_t Renderer::s_LastFrameDrawCallCount = 0;
|
||||
|
||||
|
||||
struct RendererData
|
||||
@ -127,6 +129,8 @@ namespace Prism
|
||||
|
||||
void Renderer::WaitAndRender()
|
||||
{
|
||||
s_LastFrameDrawCallCount = s_DrawCallCount;
|
||||
s_DrawCallCount = 0;
|
||||
s_Data.m_CommandQueue.Execute();
|
||||
}
|
||||
|
||||
@ -163,6 +167,7 @@ namespace Prism
|
||||
|
||||
void Renderer::SubmitQuad(Ref<MaterialInstance>& material, const glm::mat4& transform)
|
||||
{
|
||||
s_DrawCallCount++;
|
||||
bool depthTest = true;
|
||||
bool cullFace = true;
|
||||
|
||||
@ -185,6 +190,7 @@ namespace Prism
|
||||
|
||||
void Renderer::SubmitFullscreenQuad(Ref<MaterialInstance> material)
|
||||
{
|
||||
s_DrawCallCount++;
|
||||
bool depthTest = true;
|
||||
bool cullFace = true;
|
||||
if (material)
|
||||
@ -203,6 +209,7 @@ namespace Prism
|
||||
|
||||
void Renderer::SubmitFullscreenQuad(const bool depthTest, const bool cullFace)
|
||||
{
|
||||
s_DrawCallCount++;
|
||||
|
||||
s_Data.m_FullscreenQuadVertexBuffer->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)
|
||||
{
|
||||
// auto material = overrideMaterial ? overrideMaterial : mesh->GetMaterialInstance();
|
||||
// auto shader = material->GetShader();
|
||||
|
||||
// TODO: Sort this out
|
||||
mesh->m_VertexBuffer->Bind();
|
||||
mesh->m_Pipeline->Bind();
|
||||
mesh->m_IndexBuffer->Bind();
|
||||
@ -224,8 +227,9 @@ namespace Prism
|
||||
const auto& materials = mesh->GetMaterials();
|
||||
for (Submesh& submesh : mesh->m_Submeshes)
|
||||
{
|
||||
// Material
|
||||
auto material = overrideMaterials.empty() ? materials[submesh.MaterialIndex] : overrideMaterials[submesh.MaterialIndex];
|
||||
|
||||
s_DrawCallCount++;
|
||||
auto shader = material->GetShader();
|
||||
material->Bind();
|
||||
|
||||
@ -242,12 +246,10 @@ namespace Prism
|
||||
|
||||
auto cmd = s_CommandBuffer;
|
||||
Submit([cmd, submesh, material]() {
|
||||
// 状态设置通过 cmd
|
||||
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->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)
|
||||
{
|
||||
// auto material = overrideMaterial ? overrideMaterial : mesh->GetMaterialInstance();
|
||||
// auto shader = material->GetShader();
|
||||
|
||||
// TODO: Sort this out
|
||||
mesh->m_VertexBuffer->Bind();
|
||||
mesh->m_Pipeline->Bind();
|
||||
mesh->m_IndexBuffer->Bind();
|
||||
@ -266,8 +264,9 @@ namespace Prism
|
||||
const auto& materials = mesh->GetMaterials();
|
||||
for (Submesh& submesh : mesh->m_Submeshes)
|
||||
{
|
||||
// Material
|
||||
auto material = overrideMaterial ? overrideMaterial : materials[submesh.MaterialIndex];
|
||||
|
||||
s_DrawCallCount++;
|
||||
auto shader = material->GetShader();
|
||||
material->Bind();
|
||||
|
||||
@ -300,6 +299,7 @@ namespace Prism
|
||||
|
||||
for (Submesh& submesh : mesh->m_Submeshes)
|
||||
{
|
||||
s_DrawCallCount++;
|
||||
if (mesh->m_IsAnimated)
|
||||
{
|
||||
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 DispatchCompute(int x, int y, int z);
|
||||
|
||||
static uint32_t GetDrawCallCount() { return s_LastFrameDrawCallCount; }
|
||||
|
||||
private:
|
||||
static RenderCommandQueue& GetRenderCommandQueue();
|
||||
|
||||
static Ref<RHIDevice> s_Device;
|
||||
static Ref<RHICommandBuffer> s_CommandBuffer;
|
||||
static uint32_t s_DrawCallCount;
|
||||
static uint32_t s_LastFrameDrawCallCount;
|
||||
};
|
||||
|
||||
#if 0
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
#include "Renderer3D.h"
|
||||
|
||||
#include "Prism/Core/Timer.h"
|
||||
#include "Prism/Core/Math/Frustum.h"
|
||||
#include "Prism/Scene/Scene.h"
|
||||
|
||||
#include <limits>
|
||||
@ -116,8 +117,10 @@ namespace Prism
|
||||
Ref<Mesh> mesh;
|
||||
std::vector<Ref<MaterialInstance>> MaterialInstances;
|
||||
glm::mat4 Transform;
|
||||
float DistanceFromCamera = 0.0f;
|
||||
};
|
||||
std::vector<DrawCommand> DrawList;
|
||||
std::vector<DrawCommand> TransparentDrawList;
|
||||
std::vector<DrawCommand> SelectedMeshDrawList;
|
||||
std::vector<DrawCommand> ColliderDrawList;
|
||||
std::vector<DrawCommand> ShadowPassDrawList;
|
||||
@ -145,7 +148,9 @@ namespace Prism
|
||||
float Intensity = 1.0f;
|
||||
float MaxDistance = 30.0f;
|
||||
float Thickness = 0.5f;
|
||||
int Steps = 64;
|
||||
float StepSize = 0.5f;
|
||||
float RayOffset = 0.1f;
|
||||
int Steps = 32;
|
||||
float BlurRadius = 4.0f;
|
||||
|
||||
Ref<Shader> SSRShader;
|
||||
@ -158,6 +163,13 @@ namespace Prism
|
||||
|
||||
SceneRendererOptions Options;
|
||||
|
||||
Frustum CameraFrustum;
|
||||
|
||||
uint32_t MeshesSubmitted = 0;
|
||||
uint32_t MeshesCulled = 0;
|
||||
uint32_t LastFrameMeshesSubmitted = 0;
|
||||
uint32_t LastFrameMeshesCulled = 0;
|
||||
|
||||
Ref<TextureCube> BlackCubeTexture;
|
||||
Ref<Texture2D> BlackTexture;
|
||||
};
|
||||
@ -351,6 +363,9 @@ namespace Prism
|
||||
s_Data.SceneData.SceneEnvironment = scene->m_Environment;
|
||||
s_Data.SceneData.SceneEnvironmentIntensity = scene->m_EnvironmentIntensity;
|
||||
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)
|
||||
@ -360,14 +375,51 @@ namespace Prism
|
||||
|
||||
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.ShadowPassDrawList.push_back({ mesh, overrideMaterials, transform });
|
||||
}
|
||||
|
||||
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.ShadowPassDrawList.push_back({ mesh, overrideMaterials, transform });
|
||||
}
|
||||
@ -572,10 +624,15 @@ namespace Prism
|
||||
}
|
||||
|
||||
s_Data.DrawList.clear();
|
||||
s_Data.TransparentDrawList.clear();
|
||||
s_Data.SelectedMeshDrawList.clear();
|
||||
s_Data.ColliderDrawList.clear();
|
||||
s_Data.ShadowPassDrawList.clear();
|
||||
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()
|
||||
@ -1321,15 +1378,21 @@ namespace Prism
|
||||
|
||||
const auto& sceneCamera = s_Data.SceneData.SceneCamera;
|
||||
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_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->SetFloat("u_CameraNear", sceneCamera.Camera.GetNear());
|
||||
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->SetFloat("u_MaxDistance", s_Data.SSRData.MaxDistance);
|
||||
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);
|
||||
|
||||
Renderer::SubmitFullscreenQuad(nullptr);
|
||||
@ -1381,6 +1444,10 @@ namespace Prism
|
||||
{
|
||||
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("Composite Pass time", s_Stats.CompositePass);
|
||||
@ -1574,6 +1641,8 @@ namespace Prism
|
||||
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::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::EndPropertyGrid();
|
||||
|
||||
@ -143,6 +143,9 @@ namespace Prism
|
||||
MaterialInstances[i]->Set("u_Roughness", desc->Roughness);
|
||||
MaterialInstances[i]->Set("u_RoughnessTexToggle", desc->RoughnessTexToggle);
|
||||
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
|
||||
{
|
||||
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_RoughnessTexToggle", baseMaterial[i]->Get<float>("u_RoughnessTexToggle"));
|
||||
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
|
||||
@ -177,6 +183,9 @@ namespace Prism
|
||||
MaterialInstances[index]->Set("u_Roughness", desc->Roughness);
|
||||
MaterialInstances[index]->Set("u_RoughnessTexToggle", desc->RoughnessTexToggle);
|
||||
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
|
||||
{
|
||||
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_RoughnessTexToggle", baseMaterial[index]->Get<float>("u_RoughnessTexToggle"));
|
||||
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