Default shader and mesh
This commit is contained in:
parent
2d15ff8c07
commit
818941460f
@ -77,21 +77,8 @@ namespace Deer {
|
|||||||
static Scope<GPUMesh> buildResource(const BaseDataType& baseData);
|
static Scope<GPUMesh> buildResource(const BaseDataType& baseData);
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace MeshManager {
|
namespace Builtin {
|
||||||
uint16_t loadModel(const Path&);
|
Resource<GPUMesh> cube();
|
||||||
uint16_t loadModel(const MeshData&, const Path&);
|
Resource<GPUMesh> sphere();
|
||||||
VertexArray& getModel(uint16_t model_id);
|
} // namespace Builtin
|
||||||
const Path& getModelName(uint16_t model_id);
|
|
||||||
|
|
||||||
void unloadAllModels();
|
|
||||||
} // namespace MeshManager
|
|
||||||
|
|
||||||
namespace DataStore {
|
|
||||||
void saveModel(const MeshData&, const Path& name);
|
|
||||||
void loadModel(MeshData&, const Path& name);
|
|
||||||
|
|
||||||
void saveBinModel(const MeshData&, const Path& name);
|
|
||||||
|
|
||||||
void createExampleMeshData();
|
|
||||||
} // namespace DataStore
|
|
||||||
} // namespace Deer
|
} // namespace Deer
|
||||||
@ -37,4 +37,9 @@ namespace Deer {
|
|||||||
namespace DataStore {
|
namespace DataStore {
|
||||||
void loadShader(ShaderData& data, const Path& name);
|
void loadShader(ShaderData& data, const Path& name);
|
||||||
} // namespace DataStore
|
} // namespace DataStore
|
||||||
|
|
||||||
|
namespace Builtin {
|
||||||
|
Resource<Shader> simpleShader();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Deer
|
} // namespace Deer
|
||||||
125
Deer/src/DeerRender/Mesh/BuiltinCube.cpp
Normal file
125
Deer/src/DeerRender/Mesh/BuiltinCube.cpp
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
#include "DeerRender/Mesh.h"
|
||||||
|
|
||||||
|
namespace Deer {
|
||||||
|
namespace Builtin {
|
||||||
|
|
||||||
|
// Vertex positions (duplicated per face for correct normals)
|
||||||
|
VertexPosition cubeVertexPositions[] = {
|
||||||
|
// Front (+Z)
|
||||||
|
VertexPosition(-0.5f, -0.5f, 0.5f),
|
||||||
|
VertexPosition(0.5f, -0.5f, 0.5f),
|
||||||
|
VertexPosition(0.5f, 0.5f, 0.5f),
|
||||||
|
VertexPosition(-0.5f, 0.5f, 0.5f),
|
||||||
|
|
||||||
|
// Back (-Z)
|
||||||
|
VertexPosition(0.5f, -0.5f, -0.5f),
|
||||||
|
VertexPosition(-0.5f, -0.5f, -0.5f),
|
||||||
|
VertexPosition(-0.5f, 0.5f, -0.5f),
|
||||||
|
VertexPosition(0.5f, 0.5f, -0.5f),
|
||||||
|
|
||||||
|
// Left (-X)
|
||||||
|
VertexPosition(-0.5f, -0.5f, -0.5f),
|
||||||
|
VertexPosition(-0.5f, -0.5f, 0.5f),
|
||||||
|
VertexPosition(-0.5f, 0.5f, 0.5f),
|
||||||
|
VertexPosition(-0.5f, 0.5f, -0.5f),
|
||||||
|
|
||||||
|
// Right (+X)
|
||||||
|
VertexPosition(0.5f, -0.5f, 0.5f),
|
||||||
|
VertexPosition(0.5f, -0.5f, -0.5f),
|
||||||
|
VertexPosition(0.5f, 0.5f, -0.5f),
|
||||||
|
VertexPosition(0.5f, 0.5f, 0.5f),
|
||||||
|
|
||||||
|
// Top (+Y)
|
||||||
|
VertexPosition(-0.5f, 0.5f, 0.5f),
|
||||||
|
VertexPosition(0.5f, 0.5f, 0.5f),
|
||||||
|
VertexPosition(0.5f, 0.5f, -0.5f),
|
||||||
|
VertexPosition(-0.5f, 0.5f, -0.5f),
|
||||||
|
|
||||||
|
// Bottom (-Y)
|
||||||
|
VertexPosition(-0.5f, -0.5f, -0.5f),
|
||||||
|
VertexPosition(0.5f, -0.5f, -0.5f),
|
||||||
|
VertexPosition(0.5f, -0.5f, 0.5f),
|
||||||
|
VertexPosition(-0.5f, -0.5f, 0.5f),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Normals per vertex
|
||||||
|
VertexNormal cubeVertexNormals[] = {
|
||||||
|
// Front (+Z)
|
||||||
|
VertexNormal(0, 0, 64),
|
||||||
|
VertexNormal(0, 0, 64),
|
||||||
|
VertexNormal(0, 0, 64),
|
||||||
|
VertexNormal(0, 0, 64),
|
||||||
|
|
||||||
|
// Back (-Z)
|
||||||
|
VertexNormal(0, 0, -64),
|
||||||
|
VertexNormal(0, 0, -64),
|
||||||
|
VertexNormal(0, 0, -64),
|
||||||
|
VertexNormal(0, 0, -64),
|
||||||
|
|
||||||
|
// Left (-X)
|
||||||
|
VertexNormal(-64, 0, 0),
|
||||||
|
VertexNormal(-64, 0, 0),
|
||||||
|
VertexNormal(-64, 0, 0),
|
||||||
|
VertexNormal(-64, 0, 0),
|
||||||
|
|
||||||
|
// Right (+X)
|
||||||
|
VertexNormal(64, 0, 0),
|
||||||
|
VertexNormal(64, 0, 0),
|
||||||
|
VertexNormal(64, 0, 0),
|
||||||
|
VertexNormal(64, 0, 0),
|
||||||
|
|
||||||
|
// Top (+Y)
|
||||||
|
VertexNormal(0, 64, 0),
|
||||||
|
VertexNormal(0, 64, 0),
|
||||||
|
VertexNormal(0, 64, 0),
|
||||||
|
VertexNormal(0, 64, 0),
|
||||||
|
|
||||||
|
// Bottom (-Y)
|
||||||
|
VertexNormal(0, -64, 0),
|
||||||
|
VertexNormal(0, -64, 0),
|
||||||
|
VertexNormal(0, -64, 0),
|
||||||
|
VertexNormal(0, -64, 0),
|
||||||
|
};
|
||||||
|
|
||||||
|
uint32_t cubeIndices[] = {
|
||||||
|
// Front
|
||||||
|
0, 1, 2, 0, 2, 3,
|
||||||
|
// Back
|
||||||
|
4, 5, 6, 4, 6, 7,
|
||||||
|
// Left
|
||||||
|
8, 9, 10, 8, 10, 11,
|
||||||
|
// Right
|
||||||
|
12, 13, 14, 12, 14, 15,
|
||||||
|
// Top
|
||||||
|
16, 17, 18, 16, 18, 19,
|
||||||
|
// Bottom
|
||||||
|
20, 21, 22, 20, 22, 23};
|
||||||
|
|
||||||
|
} // namespace Builtin
|
||||||
|
Resource<GPUMesh> Builtin::cube() {
|
||||||
|
Resource<GPUMesh> cubeMesh = ResourceManager<GPUMesh>::getResource("Builtin:Cube");
|
||||||
|
if (cubeMesh.isValid())
|
||||||
|
return cubeMesh;
|
||||||
|
|
||||||
|
MeshData meshData;
|
||||||
|
|
||||||
|
meshData.createVertices(24); // 4 vertices per face * 6 faces
|
||||||
|
meshData.createIndices(36); // 6 indices per face * 6 faces
|
||||||
|
|
||||||
|
// Fill positions
|
||||||
|
for (size_t i = 0; i < 24; i++)
|
||||||
|
meshData.getVertexPosition()[i] = cubeVertexPositions[i];
|
||||||
|
|
||||||
|
// Fill normals
|
||||||
|
for (size_t i = 0; i < 24; i++) {
|
||||||
|
meshData.getVertexNormal()[i] = cubeVertexNormals[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill indices
|
||||||
|
for (size_t i = 0; i < 36; i++)
|
||||||
|
meshData.getIndexData()[i] = cubeIndices[i];
|
||||||
|
|
||||||
|
return ResourceManager<GPUMesh>::loadResourceFromData(meshData, "Builtin:Cube");
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Deer
|
||||||
76
Deer/src/DeerRender/Mesh/BuiltinSphere.cpp
Normal file
76
Deer/src/DeerRender/Mesh/BuiltinSphere.cpp
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
#include "DeerRender/Mesh.h"
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
namespace Deer {
|
||||||
|
namespace Builtin {
|
||||||
|
// Sphere parameters
|
||||||
|
constexpr int SPHERE_SEGMENTS = 32; // longitude
|
||||||
|
constexpr int SPHERE_RINGS = 16; // latitude
|
||||||
|
} // namespace Builtin
|
||||||
|
|
||||||
|
Resource<GPUMesh> Builtin::sphere() {
|
||||||
|
Resource<GPUMesh> sphereMesh = ResourceManager<GPUMesh>::getResource("Builtin:Sphere");
|
||||||
|
if (sphereMesh.isValid())
|
||||||
|
return sphereMesh;
|
||||||
|
|
||||||
|
MeshData meshData;
|
||||||
|
|
||||||
|
const int vertexCount = (SPHERE_RINGS + 1) * (SPHERE_SEGMENTS + 1);
|
||||||
|
const int indexCount = SPHERE_RINGS * SPHERE_SEGMENTS * 6;
|
||||||
|
|
||||||
|
meshData.createVertices(vertexCount);
|
||||||
|
meshData.createIndices(indexCount);
|
||||||
|
|
||||||
|
VertexPosition* positions = meshData.getVertexPosition();
|
||||||
|
VertexNormal* normals = meshData.getVertexNormal();
|
||||||
|
uint32_t* indices = meshData.getIndexData();
|
||||||
|
|
||||||
|
// Generate vertices
|
||||||
|
int v = 0;
|
||||||
|
for (int y = 0; y <= SPHERE_RINGS; y++) {
|
||||||
|
float theta = y * M_PI / SPHERE_RINGS; // 0..pi
|
||||||
|
float sinTheta = sinf(theta);
|
||||||
|
float cosTheta = cosf(theta);
|
||||||
|
|
||||||
|
for (int x = 0; x <= SPHERE_SEGMENTS; x++) {
|
||||||
|
float phi = x * 2.0f * M_PI / SPHERE_SEGMENTS; // 0..2pi
|
||||||
|
float sinPhi = sinf(phi);
|
||||||
|
float cosPhi = cosf(phi);
|
||||||
|
|
||||||
|
float px = cosPhi * sinTheta * 0.5f; // scale to radius 0.5
|
||||||
|
float py = cosTheta * 0.5f;
|
||||||
|
float pz = sinPhi * sinTheta * 0.5f;
|
||||||
|
|
||||||
|
positions[v] = VertexPosition(px, py, pz);
|
||||||
|
|
||||||
|
// Normal is just position normalized and scaled to int8_t range
|
||||||
|
normals[v] = VertexNormal(
|
||||||
|
static_cast<int8_t>(px * 127.0f),
|
||||||
|
static_cast<int8_t>(py * 127.0f),
|
||||||
|
static_cast<int8_t>(pz * 127.0f));
|
||||||
|
|
||||||
|
v++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate indices
|
||||||
|
int idx = 0;
|
||||||
|
for (int y = 0; y < SPHERE_RINGS; y++) {
|
||||||
|
for (int x = 0; x < SPHERE_SEGMENTS; x++) {
|
||||||
|
int a = y * (SPHERE_SEGMENTS + 1) + x;
|
||||||
|
int b = a + SPHERE_SEGMENTS + 1;
|
||||||
|
|
||||||
|
indices[idx++] = a;
|
||||||
|
indices[idx++] = a + 1;
|
||||||
|
indices[idx++] = b;
|
||||||
|
|
||||||
|
indices[idx++] = b;
|
||||||
|
indices[idx++] = a + 1;
|
||||||
|
indices[idx++] = b + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ResourceManager<GPUMesh>::loadResourceFromData(meshData, "Builtin:Sphere");
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Deer
|
||||||
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
namespace Deer {
|
namespace Deer {
|
||||||
class FrameBuffer;
|
class FrameBuffer;
|
||||||
|
class GPUMesh;
|
||||||
|
|
||||||
namespace Scripting {
|
namespace Scripting {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -47,6 +48,5 @@ namespace Deer {
|
|||||||
bool frameBuffer_isValid(Resource<FrameBuffer>&);
|
bool frameBuffer_isValid(Resource<FrameBuffer>&);
|
||||||
void frameBuffer_resize(int, int, Resource<FrameBuffer>&);
|
void frameBuffer_resize(int, int, Resource<FrameBuffer>&);
|
||||||
Resource<FrameBuffer> createFrameBuffer(std::string& name, int sixeX, int sizeY);
|
Resource<FrameBuffer> createFrameBuffer(std::string& name, int sixeX, int sizeY);
|
||||||
|
|
||||||
} // namespace Scripting
|
} // namespace Scripting
|
||||||
} // namespace Deer
|
} // namespace Deer
|
||||||
@ -49,6 +49,10 @@ namespace Deer {
|
|||||||
|
|
||||||
scriptEngine->SetDefaultNamespace("Resource");
|
scriptEngine->SetDefaultNamespace("Resource");
|
||||||
REGISTER_GLOBAL_FUNC(scriptEngine, "FrameBuffer createFrameBuffer(string&in name, int sizeX, int sizeY)", createFrameBuffer);
|
REGISTER_GLOBAL_FUNC(scriptEngine, "FrameBuffer createFrameBuffer(string&in name, int sizeX, int sizeY)", createFrameBuffer);
|
||||||
|
scriptEngine->SetDefaultNamespace("Builtin");
|
||||||
|
REGISTER_GLOBAL_FUNC(scriptEngine, "GPUMesh cube()", Builtin::cube);
|
||||||
|
REGISTER_GLOBAL_FUNC(scriptEngine, "GPUMesh sphere()", Builtin::sphere);
|
||||||
|
REGISTER_GLOBAL_FUNC(scriptEngine, "Shader simpleShader()", Builtin::simpleShader);
|
||||||
scriptEngine->SetDefaultNamespace("");
|
scriptEngine->SetDefaultNamespace("");
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
|||||||
105
Deer/src/DeerRender/Shader/BuiltinSimpleShader.cpp
Normal file
105
Deer/src/DeerRender/Shader/BuiltinSimpleShader.cpp
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
#include "DeerRender/Shader.h"
|
||||||
|
|
||||||
|
namespace Deer {
|
||||||
|
namespace Builtin {
|
||||||
|
const char* vertexSimpleShader = R"(
|
||||||
|
#version 410 core
|
||||||
|
|
||||||
|
// Vertex attributes
|
||||||
|
layout(location = 0) in vec3 v_position;
|
||||||
|
layout(location = 1) in vec3 v_normal;
|
||||||
|
layout(location = 2) in vec2 v_UV;
|
||||||
|
|
||||||
|
// Outputs to fragment shader
|
||||||
|
out vec3 normalWS;
|
||||||
|
out vec3 normalVS;
|
||||||
|
out vec3 positionVS;
|
||||||
|
|
||||||
|
// Uniforms
|
||||||
|
uniform mat4 u_worldMatrix;
|
||||||
|
uniform mat4 u_viewMatrix;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = u_viewMatrix * u_worldMatrix * vec4(v_position, 1.0);
|
||||||
|
positionVS = gl_Position.xyz;
|
||||||
|
|
||||||
|
mat3 normalMatrix = transpose(inverse(mat3(u_worldMatrix)));
|
||||||
|
normalWS = normalize(normalMatrix * v_normal);
|
||||||
|
|
||||||
|
mat3 normalMatrixView = transpose(inverse(mat3(u_viewMatrix * u_worldMatrix)));
|
||||||
|
normalVS = normalize(normalMatrixView * v_normal);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
)";
|
||||||
|
|
||||||
|
const char* fragmentSimpleShader = R"(
|
||||||
|
#version 410 core
|
||||||
|
|
||||||
|
// Fragment outputs
|
||||||
|
layout(location = 0) out vec4 fragColor;
|
||||||
|
layout(location = 1) out int objectID;
|
||||||
|
|
||||||
|
// Inputs from vertex shader
|
||||||
|
in vec3 normalWS;
|
||||||
|
in vec3 normalVS;
|
||||||
|
in vec3 positionVS;
|
||||||
|
|
||||||
|
// Uniforms
|
||||||
|
uniform int u_objectID;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Directional light
|
||||||
|
vec3 lightDir = normalize(vec3(1.0, 7.0, 3.0));
|
||||||
|
|
||||||
|
// Base light intensity
|
||||||
|
float light = clamp(dot(normalWS, lightDir) * 0.8 + 0.2, 0.0, 1.0);
|
||||||
|
|
||||||
|
// Gradient from purple (dark) to cyan (lit)
|
||||||
|
vec3 gradientColor = mix(
|
||||||
|
vec3(0.9412, 0.4471, 0.7137),
|
||||||
|
vec3(1.0, 0.9725, 0.5255),
|
||||||
|
light
|
||||||
|
);
|
||||||
|
|
||||||
|
// Rim/fresnel effect
|
||||||
|
float rim = 0.5 - dot(normalWS, normalize(lightDir)) * 0.5;
|
||||||
|
float rimValue = rim * rim * rim * rim;
|
||||||
|
vec3 rimColor = vec3(1.0, 0.8, 0.5) * (rim * rim * rim * rim);
|
||||||
|
|
||||||
|
vec3 mixedColor = mix(
|
||||||
|
gradientColor,
|
||||||
|
vec3(1, 1, 1) ,
|
||||||
|
rimValue
|
||||||
|
);
|
||||||
|
|
||||||
|
//float fresnel = dot(, vec3(0, 0, -1));
|
||||||
|
//fresnel = fresnel * fresnel;
|
||||||
|
|
||||||
|
float fresnel = 1 + dot(normalize(positionVS), normalize(normalVS));
|
||||||
|
fresnel = fresnel * fresnel * fresnel * fresnel;
|
||||||
|
|
||||||
|
// Combine everything
|
||||||
|
fragColor = vec4(mixedColor + vec3(fresnel, fresnel, fresnel), 1.0);
|
||||||
|
|
||||||
|
// Object ID output
|
||||||
|
objectID = u_objectID;
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
} // namespace Builtin
|
||||||
|
|
||||||
|
Resource<Shader> Builtin::simpleShader() {
|
||||||
|
Resource<Shader> shader = ResourceManager<Shader>::getResource("Builtin:SimpleShader");
|
||||||
|
|
||||||
|
if (shader.isValid())
|
||||||
|
return shader;
|
||||||
|
|
||||||
|
ShaderData shaderData;
|
||||||
|
shaderData.fragmentShader = fragmentSimpleShader;
|
||||||
|
shaderData.vertexShader = vertexSimpleShader;
|
||||||
|
|
||||||
|
return ResourceManager<Shader>::loadResourceFromData(shaderData, "Builtin:SimpleShader");
|
||||||
|
}
|
||||||
|
} // namespace Deer
|
||||||
@ -105,8 +105,6 @@ namespace Deer {
|
|||||||
|
|
||||||
StudioPanel::render();
|
StudioPanel::render();
|
||||||
|
|
||||||
ImGui::ShowDemoWindow();
|
|
||||||
|
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
|
|
||||||
Engine::endRender();
|
Engine::endRender();
|
||||||
|
|||||||
@ -16,7 +16,7 @@ class CameraComponentRender {
|
|||||||
float nearZ = cameraComponent.nearZ;
|
float nearZ = cameraComponent.nearZ;
|
||||||
float farZ = cameraComponent.farZ;
|
float farZ = cameraComponent.farZ;
|
||||||
|
|
||||||
fov = ImGui::magicSlider("FOV", fov, 0.1f);
|
fov = ImGui::magicSlider("Fov", fov, 0.1f);
|
||||||
if (fov > 180.0f) fov = 180.0f;
|
if (fov > 180.0f) fov = 180.0f;
|
||||||
if (fov < 1.0f) fov = 1.0f;
|
if (fov < 1.0f) fov = 1.0f;
|
||||||
|
|
||||||
|
|||||||
@ -70,7 +70,6 @@ class EntityNodeUI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void renderInteraction() {
|
void renderInteraction() {
|
||||||
|
|
||||||
// Drag and drop
|
// Drag and drop
|
||||||
ImGui::dragDropSource("ENTITY", any(entity), entity.name);
|
ImGui::dragDropSource("ENTITY", any(entity), entity.name);
|
||||||
ImGui::dragDropTarget("ENTITY", ReciverFunction(this.entityDrop));
|
ImGui::dragDropTarget("ENTITY", ReciverFunction(this.entityDrop));
|
||||||
@ -114,6 +113,9 @@ class EntityNodeUI {
|
|||||||
entity.createChild("node");
|
entity.createChild("node");
|
||||||
rootPanel.onInit();
|
rootPanel.onInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGui::separator();
|
||||||
|
ImGui::subMenu("3d Object", SimpleFunction(this.render3dObjectMenu));
|
||||||
} else {
|
} else {
|
||||||
if (ImGui::menuItem("Add child")) {
|
if (ImGui::menuItem("Add child")) {
|
||||||
entity.createChild("node");
|
entity.createChild("node");
|
||||||
@ -129,6 +131,33 @@ class EntityNodeUI {
|
|||||||
entity.destroy();
|
entity.destroy();
|
||||||
rootPanel.onInit();
|
rootPanel.onInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGui::separator();
|
||||||
|
ImGui::subMenu("3d Object", SimpleFunction(this.render3dObjectMenu));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void render3dObjectMenu() {
|
||||||
|
if (ImGui::menuItem("Cube")) {
|
||||||
|
Entity child = entity.createChild("node");
|
||||||
|
MeshComponent childMesh = child.addComponent<MeshComponent>();
|
||||||
|
childMesh.meshResource = Builtin::cube();
|
||||||
|
|
||||||
|
ShaderComponent childShader = child.addComponent<ShaderComponent>();
|
||||||
|
childShader.shader = Builtin::simpleShader();
|
||||||
|
|
||||||
|
rootPanel.onInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::menuItem("Sphere")) {
|
||||||
|
Entity child = entity.createChild("node");
|
||||||
|
MeshComponent childMesh = child.addComponent<MeshComponent>();
|
||||||
|
childMesh.meshResource = Builtin::sphere();
|
||||||
|
|
||||||
|
ShaderComponent childShader = child.addComponent<ShaderComponent>();
|
||||||
|
childShader.shader = Builtin::simpleShader();
|
||||||
|
|
||||||
|
rootPanel.onInit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,7 +210,6 @@ class TreePanel : Panel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void onImGui() {
|
void onImGui() {
|
||||||
|
|
||||||
if (infoChanged) {
|
if (infoChanged) {
|
||||||
Entity root = World::getRoot();
|
Entity root = World::getRoot();
|
||||||
@rootNode = @EntityNodeUI(root, this);
|
@rootNode = @EntityNodeUI(root, this);
|
||||||
@ -189,6 +217,10 @@ class TreePanel : Panel {
|
|||||||
infoChanged = false;
|
infoChanged = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
rootNode.render();
|
ImGui::contextMenuPopup("POP_ROOT", SimpleFunction(rootNode.renderContextMenu));
|
||||||
|
|
||||||
|
for (uint i = 0; i < rootNode.children.length(); i++) {
|
||||||
|
if (rootNode.children[i].entity.exists) rootNode.children[i].render();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,43 +1,83 @@
|
|||||||
#type vertex
|
#type vertex
|
||||||
#version 410 core
|
#version 410 core
|
||||||
|
|
||||||
|
// Vertex attributes
|
||||||
layout(location = 0) in vec3 v_position;
|
layout(location = 0) in vec3 v_position;
|
||||||
layout(location = 1) in vec3 v_normal;
|
layout(location = 1) in vec3 v_normal;
|
||||||
layout(location = 2) in vec2 v_UV;
|
layout(location = 2) in vec2 v_UV;
|
||||||
|
|
||||||
out vec3 normal;
|
// Outputs to fragment shader
|
||||||
out vec2 uv;
|
out vec3 normalWS;
|
||||||
|
out vec3 normalVS;
|
||||||
|
out vec3 positionVS;
|
||||||
|
|
||||||
uniform mat4 u_viewMatrix;
|
// Uniforms
|
||||||
uniform mat4 u_worldMatrix;
|
uniform mat4 u_worldMatrix;
|
||||||
|
uniform mat4 u_viewMatrix;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
uv = v_UV;
|
|
||||||
normal = mat3(u_worldMatrix) * v_normal; // transform normals into world space
|
|
||||||
|
|
||||||
gl_Position = u_viewMatrix * u_worldMatrix * vec4(v_position, 1.0);
|
gl_Position = u_viewMatrix * u_worldMatrix * vec4(v_position, 1.0);
|
||||||
|
positionVS = gl_Position.xyz;
|
||||||
|
|
||||||
|
mat3 normalMatrix = transpose(inverse(mat3(u_worldMatrix)));
|
||||||
|
normalWS = normalize(normalMatrix * v_normal);
|
||||||
|
|
||||||
|
mat3 normalMatrixView = transpose(inverse(mat3(u_viewMatrix * u_worldMatrix)));
|
||||||
|
normalVS = normalize(normalMatrixView * v_normal);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#type fragment
|
#type fragment
|
||||||
#version 410 core
|
#version 410 core
|
||||||
|
|
||||||
|
// Fragment outputs
|
||||||
layout(location = 0) out vec4 fragColor;
|
layout(location = 0) out vec4 fragColor;
|
||||||
layout(location = 1) out int objectID;
|
layout(location = 1) out int objectID;
|
||||||
|
|
||||||
in vec3 normal;
|
// Inputs from vertex shader
|
||||||
in vec2 uv;
|
in vec3 normalWS;
|
||||||
|
in vec3 normalVS;
|
||||||
|
in vec3 positionVS;
|
||||||
|
|
||||||
uniform sampler2D u_Texture;
|
// Uniforms
|
||||||
uniform int u_objectID;
|
uniform int u_objectID;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec3 lightDir = normalize(vec3(1.0, 7.0, 3.0)) * 0.2f + 0.8f;
|
// Directional light
|
||||||
float light = clamp(dot(normalize(normal), lightDir), 0.1, 1.0);
|
vec3 lightDir = normalize(vec3(1.0, 7.0, 3.0));
|
||||||
|
|
||||||
fragColor = vec4(light, light, light, 1);
|
// Base light intensity
|
||||||
// fragColor = vec4(uv.r, uv.g, 0, 1);
|
float light = clamp(dot(normalWS, lightDir) * 0.8 + 0.2, 0.0, 1.0);
|
||||||
|
|
||||||
|
// Gradient from purple (dark) to cyan (lit)
|
||||||
|
vec3 gradientColor = mix(
|
||||||
|
vec3(0.9412, 0.4471, 0.7137),
|
||||||
|
vec3(1.0, 0.9725, 0.5255),
|
||||||
|
light
|
||||||
|
);
|
||||||
|
|
||||||
|
// Rim/fresnel effect
|
||||||
|
float rim = 0.5 - dot(normalWS, normalize(lightDir)) * 0.5;
|
||||||
|
float rimValue = rim * rim * rim * rim;
|
||||||
|
vec3 rimColor = vec3(1.0, 0.8, 0.5) * (rim * rim * rim * rim);
|
||||||
|
|
||||||
|
vec3 mixedColor = mix(
|
||||||
|
gradientColor,
|
||||||
|
vec3(1, 1, 1) ,
|
||||||
|
rimValue
|
||||||
|
);
|
||||||
|
|
||||||
|
//float fresnel = dot(, vec3(0, 0, -1));
|
||||||
|
//fresnel = fresnel * fresnel;
|
||||||
|
|
||||||
|
float fresnel = 1 + dot(normalize(positionVS), normalize(normalVS));
|
||||||
|
fresnel = fresnel * fresnel * fresnel * fresnel;
|
||||||
|
|
||||||
|
// Combine everything
|
||||||
|
fragColor = vec4(mixedColor + vec3(fresnel, fresnel, fresnel), 1.0);
|
||||||
|
|
||||||
|
// Object ID output
|
||||||
objectID = u_objectID;
|
objectID = u_objectID;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,7 +67,7 @@ DockSpace ID=0x0AC2E849 Window=0xD0388BC8 Pos=0,26 Size=2560,1345 Split=Y
|
|||||||
DockNode ID=0x00000003 Parent=0x0AC2E849 SizeRef=2560,926 Split=X
|
DockNode ID=0x00000003 Parent=0x0AC2E849 SizeRef=2560,926 Split=X
|
||||||
DockNode ID=0x00000001 Parent=0x00000003 SizeRef=1230,1336 Split=X Selected=0x16E3C1E7
|
DockNode ID=0x00000001 Parent=0x00000003 SizeRef=1230,1336 Split=X Selected=0x16E3C1E7
|
||||||
DockNode ID=0x00000005 Parent=0x00000001 SizeRef=569,572 CentralNode=1 Selected=0x16E3C1E7
|
DockNode ID=0x00000005 Parent=0x00000001 SizeRef=569,572 CentralNode=1 Selected=0x16E3C1E7
|
||||||
DockNode ID=0x00000006 Parent=0x00000001 SizeRef=1299,572 Selected=0x5E5F7166
|
DockNode ID=0x00000006 Parent=0x00000001 SizeRef=1299,572 Selected=0x0F5FFC8C
|
||||||
DockNode ID=0x00000002 Parent=0x00000003 SizeRef=688,1336 Selected=0x9876A79B
|
DockNode ID=0x00000002 Parent=0x00000003 SizeRef=688,1336 Selected=0x9876A79B
|
||||||
DockNode ID=0x00000004 Parent=0x0AC2E849 SizeRef=2560,418 Selected=0x018A0F9B
|
DockNode ID=0x00000004 Parent=0x0AC2E849 SizeRef=2560,418 Selected=0x018A0F9B
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user