add mouse picking, add more hdr environment maps
This commit is contained in:
@ -149,7 +149,7 @@ namespace Prism
|
||||
|
||||
auto secondEntity = m_Scene->CreateEntity("Gun Entity");
|
||||
secondEntity->Transform() = glm::translate(glm::mat4(1.0f), { 5, 5, 5 }) * glm::scale(glm::mat4(1.0f), {10, 10, 10});
|
||||
mesh = CreateRef<Mesh>("assets/models/m1911/m1911.fbx");
|
||||
mesh = CreateRef<Mesh>("assets/models/m1911/m1911Materials.fbx");
|
||||
secondEntity->SetMesh(mesh);
|
||||
}
|
||||
|
||||
@ -208,9 +208,12 @@ namespace Prism
|
||||
// Editor
|
||||
m_CheckerboardTex = Texture2D::Create("assets/editor/Checkerboard.tga");
|
||||
|
||||
// lights
|
||||
m_Light.Direction = {-0.5f, -0.5f, 1.0f};
|
||||
m_Light.Radiance = {1.0f, 1.0f, 1.0f};
|
||||
// set lights
|
||||
auto& light = m_Scene->GetLight();
|
||||
light.Direction = { -0.5f, -0.5f, 1.0f };
|
||||
light.Radiance = { 1.0f, 1.0f, 1.0f };
|
||||
|
||||
m_CurrentlySelectedTransform = &m_MeshEntity->Transform();
|
||||
}
|
||||
|
||||
void EditorLayer::OnDetach()
|
||||
@ -228,7 +231,6 @@ namespace Prism
|
||||
m_MeshMaterial->Set("u_AlbedoColor", m_AlbedoInput.Color);
|
||||
m_MeshMaterial->Set("u_Metalness", m_MetalnessInput.Value);
|
||||
m_MeshMaterial->Set("u_Roughness", m_RoughnessInput.Value);
|
||||
m_MeshMaterial->Set("lights", m_Light);
|
||||
m_MeshMaterial->Set("u_AlbedoTexToggle", m_AlbedoInput.UseTexture ? 1.0f : 0.0f);
|
||||
m_MeshMaterial->Set("u_NormalTexToggle", m_NormalInput.UseTexture ? 1.0f : 0.0f);
|
||||
m_MeshMaterial->Set("u_MetalnessTexToggle", m_MetalnessInput.UseTexture ? 1.0f : 0.0f);
|
||||
@ -236,7 +238,8 @@ namespace Prism
|
||||
m_MeshMaterial->Set("u_EnvMapRotation", m_EnvMapRotation);
|
||||
|
||||
m_SphereBaseMaterial->Set("u_AlbedoColor", m_AlbedoInput.Color);
|
||||
m_SphereBaseMaterial->Set("lights", m_Light);
|
||||
// m_SphereBaseMaterial->Set("lights", m_Light);
|
||||
m_SphereBaseMaterial->Set("lights", m_Scene->GetLight());
|
||||
m_SphereBaseMaterial->Set("u_RadiancePrefilter", m_RadiancePrefilter ? 1.0f : 0.0f);
|
||||
m_SphereBaseMaterial->Set("u_AlbedoTexToggle", m_AlbedoInput.UseTexture ? 1.0f : 0.0f);
|
||||
m_SphereBaseMaterial->Set("u_NormalTexToggle", m_NormalInput.UseTexture ? 1.0f : 0.0f);
|
||||
@ -264,8 +267,19 @@ namespace Prism
|
||||
Renderer::BeginRenderPass(SceneRenderer::GetFinalRenderPass(), false);
|
||||
auto viewProj = m_Scene->GetCamera().GetViewProjection();
|
||||
Renderer2D::BeginScene(viewProj, false);
|
||||
// Prism::Renderer2D::DrawQuad({ 0, 0, 0 }, { 4.0f, 5.0f }, { 1.0f, 1.0f, 0.5f, 1.0f });
|
||||
Renderer::DrawAABB(m_MeshEntity->GetMesh());
|
||||
Renderer::DrawAABB(m_MeshEntity->GetMesh(), m_MeshEntity->Transform());
|
||||
|
||||
Renderer2D::EndScene();
|
||||
Renderer::EndRenderPass();
|
||||
}
|
||||
|
||||
if (!m_SelectedSubmeshes.empty())
|
||||
{
|
||||
Renderer::BeginRenderPass(SceneRenderer::GetFinalRenderPass(), false);
|
||||
const auto viewProj = m_Scene->GetCamera().GetViewProjection();
|
||||
Renderer2D::BeginScene(viewProj, false);
|
||||
const auto& submesh = m_SelectedSubmeshes[0];
|
||||
Renderer::DrawAABB(submesh.Mesh->BoundingBox, m_MeshEntity->GetTransform() * submesh.Mesh->Transform);
|
||||
Renderer2D::EndScene();
|
||||
Renderer::EndRenderPass();
|
||||
}
|
||||
@ -441,9 +455,10 @@ namespace Prism
|
||||
ImGui::Columns(2);
|
||||
ImGui::AlignTextToFramePadding();
|
||||
|
||||
Property("Light Direction", m_Light.Direction);
|
||||
Property("Light Radiance", m_Light.Radiance, PropertyFlag::ColorProperty);
|
||||
Property("Light Multiplier", m_LightMultiplier, 0.0f, 5.0f);
|
||||
auto& light = m_Scene->GetLight();
|
||||
Property("Light Direction", light.Direction);
|
||||
Property("Light Radiance", light.Radiance, PropertyFlag::ColorProperty);
|
||||
Property("Light Multiplier", light.Multiplier, 0.0f, 5.0f);
|
||||
Property("Exposure", m_ActiveScene->GetCamera().GetExposure(), 0.0f, 5.0f);
|
||||
|
||||
Property("Radiance Prefiltering", m_RadiancePrefilter);
|
||||
@ -642,6 +657,8 @@ namespace Prism
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
|
||||
ImGui::Begin("Viewport");
|
||||
|
||||
auto viewportOffset = ImGui::GetCursorPos(); // includes tab bar
|
||||
auto viewportSize = ImGui::GetContentRegionAvail();
|
||||
SceneRenderer::SetViewportSize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y);
|
||||
m_ActiveScene->GetCamera().SetProjectionMatrix(glm::perspectiveFov(glm::radians(45.0f), viewportSize.x, viewportSize.y, 0.1f, 10000.0f));
|
||||
@ -649,13 +666,19 @@ namespace Prism
|
||||
ImGui::Image((ImTextureRef)SceneRenderer::GetFinalColorBufferRendererID(), viewportSize, { 0, 1 }, { 1, 0 });
|
||||
|
||||
|
||||
static int counter = 0;
|
||||
auto windowSize = ImGui::GetWindowSize();
|
||||
ImVec2 minBound = ImGui::GetWindowPos();
|
||||
minBound.x += viewportOffset.x;
|
||||
minBound.y += viewportOffset.y;
|
||||
|
||||
ImVec2 maxBound = { minBound.x + windowSize.x, minBound.y + windowSize.y };
|
||||
m_ViewportBounds[0] = { minBound.x, minBound.y };
|
||||
m_ViewportBounds[1] = { maxBound.x, maxBound.y };
|
||||
m_AllowViewportCameraEvents = ImGui::IsMouseHoveringRect(minBound, maxBound);
|
||||
|
||||
// ImGuizmo
|
||||
if (m_GizmoType != -1)
|
||||
if (m_GizmoType != -1 && m_CurrentlySelectedTransform)
|
||||
{
|
||||
const auto rw = (float)ImGui::GetWindowWidth();
|
||||
const auto rh = (float)ImGui::GetWindowHeight();
|
||||
@ -663,7 +686,15 @@ namespace Prism
|
||||
ImGuizmo::SetDrawlist();
|
||||
ImGuizmo::SetRect(ImGui::GetWindowPos().x, ImGui::GetWindowPos().y, rw, rh);
|
||||
const auto& camera = m_ActiveScene->GetCamera();
|
||||
ImGuizmo::Manipulate(glm::value_ptr(camera.GetViewMatrix()), glm::value_ptr(camera.GetProjectionMatrix()), (ImGuizmo::OPERATION)m_GizmoType, ImGuizmo::LOCAL, glm::value_ptr(m_MeshEntity->Transform()));
|
||||
|
||||
bool snap = Input::IsKeyPressed(PM_KEY_LEFT_CONTROL);
|
||||
ImGuizmo::Manipulate(glm::value_ptr(camera.GetViewMatrix()),
|
||||
glm::value_ptr(camera.GetProjectionMatrix()),
|
||||
(ImGuizmo::OPERATION)m_GizmoType,
|
||||
ImGuizmo::LOCAL,
|
||||
glm::value_ptr(m_MeshEntity->Transform()),
|
||||
nullptr,
|
||||
snap ? &m_SnapValue : nullptr);
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
@ -678,6 +709,7 @@ namespace Prism
|
||||
|
||||
EventDispatcher dispatcher(e);
|
||||
dispatcher.Dispatch<KeyPressedEvent>(PM_BIND_EVENT_FN(EditorLayer::OnKeyPressedEvent));
|
||||
dispatcher.Dispatch<MouseButtonPressedEvent>(PM_BIND_EVENT_FN(EditorLayer::OnMouseButtonPressedEvent));
|
||||
}
|
||||
|
||||
bool EditorLayer::OnKeyPressedEvent(KeyPressedEvent& e)
|
||||
@ -714,9 +746,85 @@ namespace Prism
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EditorLayer::OnMouseButtonPressedEvent(MouseButtonPressedEvent& e)
|
||||
{
|
||||
auto [mx, my] = Input::GetMousePosition();
|
||||
if (e.GetMouseButton() == PM_MOUSE_BUTTON_LEFT && !Input::IsKeyPressed(PM_KEY_LEFT_ALT) && !ImGuizmo::IsOver())
|
||||
{
|
||||
auto [mouseX, mouseY] = GetMouseViewportSpace();
|
||||
if (mouseX > -1.0f && mouseX < 1.0f && mouseY > -1.0f && mouseY < 1.0f)
|
||||
{
|
||||
auto [origin, direction] = CastRay(mouseX, mouseY);
|
||||
|
||||
m_SelectedSubmeshes.clear();
|
||||
const auto mesh = m_MeshEntity->GetMesh();
|
||||
auto& submeshes = mesh->GetSubmeshes();
|
||||
float lastT = std::numeric_limits<float>::max();
|
||||
for (uint32_t i = 0; i < submeshes.size(); i++)
|
||||
{
|
||||
auto& submesh = submeshes[i];
|
||||
Ray ray = {
|
||||
glm::inverse(m_MeshEntity->GetTransform() * submesh.Transform) * glm::vec4(origin, 1.0f),
|
||||
glm::inverse(glm::mat3(m_MeshEntity->GetTransform()) * glm::mat3(submesh.Transform)) * direction
|
||||
};
|
||||
|
||||
float t;
|
||||
bool intersects = ray.IntersectsAABB(submesh.BoundingBox, t);
|
||||
if (intersects)
|
||||
{
|
||||
const auto& triangleCache = mesh->GetTriangleCache(i);
|
||||
for (const auto& triangle : triangleCache)
|
||||
{
|
||||
if (ray.IntersectsTriangle(triangle.V0.Position, triangle.V1.Position, triangle.V2.Position, t))
|
||||
{
|
||||
PM_CLIENT_WARN("INTERSECTION: {0}, t={1}", submesh.NodeName, t);
|
||||
m_SelectedSubmeshes.push_back({ &submesh, t });
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
std::sort(m_SelectedSubmeshes.begin(), m_SelectedSubmeshes.end(), [](auto& a, auto& b) { return a.Distance < b.Distance; });
|
||||
|
||||
// TODO: Handle mesh being deleted, etc.
|
||||
if (!m_SelectedSubmeshes.empty())
|
||||
m_CurrentlySelectedTransform = &m_SelectedSubmeshes[0].Mesh->Transform;
|
||||
else
|
||||
m_CurrentlySelectedTransform = &m_MeshEntity->Transform();
|
||||
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void EditorLayer::ShowBoundingBoxes(bool show, bool onTop)
|
||||
{
|
||||
SceneRenderer::GetOptions().ShowBoundingBoxes = show && !onTop;
|
||||
m_DrawOnTopBoundingBoxes = show && onTop;
|
||||
}
|
||||
|
||||
std::pair<float, float> EditorLayer::GetMouseViewportSpace() const
|
||||
{
|
||||
auto [mx, my] = ImGui::GetMousePos(); // Input::GetMousePosition();
|
||||
mx -= m_ViewportBounds[0].x;
|
||||
my -= m_ViewportBounds[0].y;
|
||||
const auto viewportWidth = m_ViewportBounds[1].x - m_ViewportBounds[0].x;
|
||||
const auto viewportHeight = m_ViewportBounds[1].y - m_ViewportBounds[0].y;
|
||||
|
||||
return { (mx / viewportWidth) * 2.0f - 1.0f, ((my / viewportHeight) * 2.0f - 1.0f) * -1.0f };
|
||||
}
|
||||
|
||||
std::pair<glm::vec3, glm::vec3> EditorLayer::CastRay(const float mx, const float my) const
|
||||
{
|
||||
glm::vec4 mouseClipPos = { mx, my, -1.0f, 1.0f };
|
||||
|
||||
const auto inverseProj = glm::inverse(m_Scene->GetCamera().GetProjectionMatrix());
|
||||
const auto inverseView = glm::inverse(glm::mat3(m_Scene->GetCamera().GetViewMatrix()));
|
||||
|
||||
const glm::vec4 ray = inverseProj * mouseClipPos;
|
||||
glm::vec3 rayPos = m_Scene->GetCamera().GetPosition();
|
||||
glm::vec3 rayDir = inverseView * glm::vec3(ray);
|
||||
|
||||
return { rayPos, rayDir };
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,9 +24,14 @@ namespace Prism
|
||||
|
||||
private:
|
||||
bool OnKeyPressedEvent(KeyPressedEvent& e);
|
||||
bool OnMouseButtonPressedEvent(MouseButtonPressedEvent& e);
|
||||
|
||||
void ShowBoundingBoxes(bool show, bool onTop = false);
|
||||
|
||||
private:
|
||||
std::pair<float, float> GetMouseViewportSpace() const;
|
||||
std::pair<glm::vec3, glm::vec3> CastRay(float mx, float my) const;
|
||||
|
||||
private:
|
||||
Scope<SceneHierarchyPanel> m_SceneHierarchyPanel;
|
||||
|
||||
@ -36,25 +41,27 @@ namespace Prism
|
||||
|
||||
Entity* m_MeshEntity = nullptr;
|
||||
|
||||
Ref<Shader> m_BrushShader;
|
||||
Ref<Mesh> m_PlaneMesh;
|
||||
Ref<Material> m_SphereBaseMaterial;
|
||||
|
||||
Ref<Material> m_MeshMaterial;
|
||||
|
||||
Ref<RenderPass> m_GeoPass, m_CompositePass;
|
||||
|
||||
Ref<MaterialInstance> m_GridMaterial;
|
||||
|
||||
std::vector<Ref<MaterialInstance>> m_MetalSphereMaterialInstances;
|
||||
std::vector<Ref<MaterialInstance>> m_DielectricSphereMaterialInstances;
|
||||
|
||||
float m_GridScale = 16.025f, m_GridSize = 0.025f;
|
||||
float m_MeshScale = 1.0f;
|
||||
|
||||
|
||||
// Imguizmo
|
||||
glm::vec2 m_ViewportBounds[2];
|
||||
int m_GizmoType = -1; // -1 = no gizmo
|
||||
float m_SnapValue = 0.5f;
|
||||
|
||||
struct SelectedSubmesh
|
||||
{
|
||||
Submesh* Mesh;
|
||||
float Distance;
|
||||
};
|
||||
std::vector<SelectedSubmesh> m_SelectedSubmeshes;
|
||||
glm::mat4* m_CurrentlySelectedTransform = nullptr;
|
||||
|
||||
// configure button
|
||||
bool m_AllowViewportCameraEvents = false;
|
||||
@ -97,14 +104,6 @@ namespace Prism
|
||||
RoughnessInput m_RoughnessInput;
|
||||
|
||||
|
||||
struct Light
|
||||
{
|
||||
glm::vec3 Direction;
|
||||
glm::vec3 Radiance;
|
||||
};
|
||||
Light m_Light;
|
||||
float m_LightMultiplier = 0.3f;
|
||||
|
||||
// PBR params
|
||||
bool m_RadiancePrefilter = false;
|
||||
|
||||
|
||||
BIN
Editor/assets/env/pink_sunrise_4k.hdr
vendored
Normal file
BIN
Editor/assets/env/pink_sunrise_4k.hdr
vendored
Normal file
Binary file not shown.
BIN
Editor/assets/env/rooitou_park_4k.hdr
vendored
Normal file
BIN
Editor/assets/env/rooitou_park_4k.hdr
vendored
Normal file
Binary file not shown.
BIN
Editor/assets/env/venice_dawn_1_4k.hdr
vendored
Normal file
BIN
Editor/assets/env/venice_dawn_1_4k.hdr
vendored
Normal file
Binary file not shown.
BIN
Editor/assets/meshes/TestScene.blend
Normal file
BIN
Editor/assets/meshes/TestScene.blend
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -46,7 +46,7 @@ void main()
|
||||
vec4 localPosition = boneTransform * vec4(a_Position, 1.0);
|
||||
|
||||
vs_Output.WorldPosition = vec3(u_Transform * boneTransform * vec4(a_Position, 1.0));
|
||||
vs_Output.Normal = mat3(boneTransform) * a_Normal;
|
||||
vs_Output.Normal = mat3(u_Transform) * mat3(boneTransform) * a_Normal;
|
||||
vs_Output.TexCoord = vec2(a_TexCoord.x, 1.0 - a_TexCoord.y);
|
||||
vs_Output.WorldNormals = mat3(u_Transform) * mat3(a_Tangent, a_Binormal, a_Normal);
|
||||
vs_Output.Binormal = mat3(boneTransform) * a_Binormal;
|
||||
@ -68,6 +68,7 @@ const vec3 Fdielectric = vec3(0.04);
|
||||
struct Light {
|
||||
vec3 Direction;
|
||||
vec3 Radiance;
|
||||
float Multiplier;
|
||||
};
|
||||
|
||||
in VertexOutput
|
||||
@ -256,7 +257,7 @@ vec3 Lighting(vec3 F0)
|
||||
for(int i = 0; i < LightCount; i++)
|
||||
{
|
||||
vec3 Li = -lights.Direction;
|
||||
vec3 Lradiance = lights.Radiance;
|
||||
vec3 Lradiance = lights.Radiance * lights.Multiplier;
|
||||
vec3 Lh = normalize(Li + m_Params.View);
|
||||
|
||||
// Calculate angles between surface normal and various light vectors.
|
||||
@ -288,7 +289,7 @@ vec3 IBL(vec3 F0, vec3 Lr)
|
||||
int u_EnvRadianceTexLevels = textureQueryLevels(u_EnvRadianceTex);
|
||||
float NoV = clamp(m_Params.NdotV, 0.0, 1.0);
|
||||
vec3 R = 2.0 * dot(m_Params.View, m_Params.Normal) * m_Params.Normal - m_Params.View;
|
||||
vec3 specularIrradiance = textureLod(u_EnvRadianceTex, RotateVectorAboutY(u_EnvMapRotation, Lr), (m_Params.Roughness * m_Params.Roughness) * u_EnvRadianceTexLevels).rgb;
|
||||
vec3 specularIrradiance = textureLod(u_EnvRadianceTex, RotateVectorAboutY(u_EnvMapRotation, Lr), (m_Params.Roughness) * u_EnvRadianceTexLevels).rgb;
|
||||
|
||||
// Sample BRDF Lut, 1.0 - roughness for y-coord because texture was generated (in Sparky) for gloss model
|
||||
vec2 specularBRDF = texture(u_BRDFLUTTexture, vec2(m_Params.NdotV, 1.0 - m_Params.Roughness)).rg;
|
||||
@ -322,7 +323,7 @@ void main()
|
||||
// Fresnel reflectance, metals use albedo
|
||||
vec3 F0 = mix(Fdielectric, m_Params.Albedo, m_Params.Metalness);
|
||||
|
||||
vec3 lightContribution = vec3(0.0);//Lighting(F0);
|
||||
vec3 lightContribution = Lighting(F0);
|
||||
vec3 iblContribution = IBL(F0, Lr);
|
||||
|
||||
color = vec4(lightContribution + iblContribution, 1.0);
|
||||
|
||||
@ -57,6 +57,7 @@ const vec3 Fdielectric = vec3(0.04);
|
||||
struct Light {
|
||||
vec3 Direction;
|
||||
vec3 Radiance;
|
||||
float Multiplier;
|
||||
};
|
||||
|
||||
in VertexOutput
|
||||
@ -246,7 +247,7 @@ vec3 Lighting(vec3 F0)
|
||||
for(int i = 0; i < LightCount; i++)
|
||||
{
|
||||
vec3 Li = -lights.Direction;
|
||||
vec3 Lradiance = lights.Radiance;
|
||||
vec3 Lradiance = lights.Radiance * lights.Multiplier;
|
||||
vec3 Lh = normalize(Li + m_Params.View);
|
||||
|
||||
// Calculate angles between surface normal and various light vectors.
|
||||
@ -271,15 +272,15 @@ vec3 Lighting(vec3 F0)
|
||||
vec3 IBL(vec3 F0, vec3 Lr)
|
||||
{
|
||||
vec3 irradiance = texture(u_EnvIrradianceTex, m_Params.Normal).rgb;
|
||||
// vec3 F = fresnelSchlickRoughness(F0, m_Params.NdotV, m_Params.Roughness);
|
||||
vec3 F = fresnelSchlick(F0, m_Params.NdotV);
|
||||
vec3 F = fresnelSchlickRoughness(F0, m_Params.NdotV, m_Params.Roughness);
|
||||
// vec3 F = fresnelSchlickR(F0, m_Params.NdotV);
|
||||
vec3 kd = (1.0 - F) * (1.0 - m_Params.Metalness);
|
||||
vec3 diffuseIBL = m_Params.Albedo * irradiance;
|
||||
|
||||
int u_EnvRadianceTexLevels = textureQueryLevels(u_EnvRadianceTex);
|
||||
float NoV = clamp(m_Params.NdotV, 0.0, 1.0);
|
||||
vec3 R = 2.0 * dot(m_Params.View, m_Params.Normal) * m_Params.Normal - m_Params.View;
|
||||
vec3 specularIrradiance = textureLod(u_EnvRadianceTex, RotateVectorAboutY(u_EnvMapRotation, Lr), (m_Params.Roughness * m_Params.Roughness) * u_EnvRadianceTexLevels).rgb;
|
||||
vec3 specularIrradiance = textureLod(u_EnvRadianceTex, RotateVectorAboutY(u_EnvMapRotation, Lr), (m_Params.Roughness) * u_EnvRadianceTexLevels).rgb;
|
||||
|
||||
// Sample BRDF Lut, 1.0 - roughness for y-coord because texture was generated (in Sparky) for gloss model
|
||||
vec2 specularBRDF = texture(u_BRDFLUTTexture, vec2(m_Params.NdotV, 1.0 - m_Params.Roughness)).rg;
|
||||
@ -317,5 +318,5 @@ void main()
|
||||
vec3 iblContribution = IBL(F0, Lr);
|
||||
|
||||
color = vec4(lightContribution + iblContribution, 1.0);
|
||||
color = vec4(iblContribution, 1.0);
|
||||
// color = vec4(iblContribution, 1.0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user