Parallax mapping working on single triangle
This commit is contained in:
parent
7fc46d36a1
commit
14b43239b5
10
Game.cpp
10
Game.cpp
@ -146,7 +146,7 @@ namespace ZL
|
|||||||
renderer.shaderManager.AddShaderFromFiles("defaultAtmosphere", "./shaders/defaultAtmosphere.vertex", "./shaders/defaultAtmosphere.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("defaultAtmosphere", "./shaders/defaultAtmosphere.vertex", "./shaders/defaultAtmosphere.fragment", CONST_ZIP_FILE);
|
||||||
renderer.shaderManager.AddShaderFromFiles("defaultColor2", "./shaders/defaultColor_fog2.vertex", "./shaders/defaultColor_fog2_desktop.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("defaultColor2", "./shaders/defaultColor_fog2.vertex", "./shaders/defaultColor_fog2_desktop.fragment", CONST_ZIP_FILE);
|
||||||
renderer.shaderManager.AddShaderFromFiles("defaultColorStones", "./shaders/defaultColor_fog_stones.vertex", "./shaders/defaultColor_fog_stones_desktop.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("defaultColorStones", "./shaders/defaultColor_fog_stones.vertex", "./shaders/defaultColor_fog_stones_desktop.fragment", CONST_ZIP_FILE);
|
||||||
//renderer.shaderManager.AddShaderFromFiles("defaultColorBake", "./shaders/defaultColor_fog_bake.vertex", "./shaders/defaultColor_fog_stones_bake.fragment", CONST_ZIP_FILE);
|
renderer.shaderManager.AddShaderFromFiles("defaultColorBake", "./shaders/defaultColor_bake.vertex", "./shaders/defaultColor_bake_desktop.fragment", CONST_ZIP_FILE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
cubemapTexture = std::make_shared<Texture>(
|
cubemapTexture = std::make_shared<Texture>(
|
||||||
@ -173,6 +173,7 @@ namespace ZL
|
|||||||
spaceship.AssignFrom(spaceshipBase);
|
spaceship.AssignFrom(spaceshipBase);
|
||||||
spaceship.RefreshVBO();
|
spaceship.RefreshVBO();
|
||||||
|
|
||||||
|
|
||||||
//Boxes
|
//Boxes
|
||||||
boxTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/box/box.png", CONST_ZIP_FILE));
|
boxTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/box/box.png", CONST_ZIP_FILE));
|
||||||
boxBase = LoadFromTextFile02("./resources/box/box.txt", CONST_ZIP_FILE);
|
boxBase = LoadFromTextFile02("./resources/box/box.txt", CONST_ZIP_FILE);
|
||||||
@ -473,6 +474,7 @@ namespace ZL
|
|||||||
skyPercent = (1900.f - distance) / 900.f;
|
skyPercent = (1900.f - distance) / 900.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
drawCubemap(skyPercent);
|
drawCubemap(skyPercent);
|
||||||
planetObject.draw(renderer);
|
planetObject.draw(renderer);
|
||||||
if (planetObject.distanceToPlanetSurface(Environment::shipPosition) > 100.f)
|
if (planetObject.distanceToPlanetSurface(Environment::shipPosition) > 100.f)
|
||||||
@ -636,7 +638,11 @@ namespace ZL
|
|||||||
}
|
}
|
||||||
if (event.key.keysym.sym == SDLK_q)
|
if (event.key.keysym.sym == SDLK_q)
|
||||||
{
|
{
|
||||||
planetObject.y += 1;
|
|
||||||
|
Environment::shipPosition = { 0, 0, 25000 };
|
||||||
|
//Environment::shipPosition = { 50000, 50000, 50000 };
|
||||||
|
|
||||||
|
//planetObject.y += 1;
|
||||||
}
|
}
|
||||||
if (event.key.keysym.sym == SDLK_w)
|
if (event.key.keysym.sym == SDLK_w)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -199,6 +199,7 @@ namespace ZL {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector<int> PlanetData::getTrianglesUnderCamera(const Vector3f& viewerPosition) {
|
std::vector<int> PlanetData::getTrianglesUnderCamera(const Vector3f& viewerPosition) {
|
||||||
// Âûçûâàåì ðåêóðñèþ ñ òåêóùèì LOD
|
// Âûçûâàåì ðåêóðñèþ ñ òåêóùèì LOD
|
||||||
return recursiveTriangleSearch(currentLod, viewerPosition, planetMeshLods);
|
return recursiveTriangleSearch(currentLod, viewerPosition, planetMeshLods);
|
||||||
@ -316,41 +317,51 @@ namespace ZL {
|
|||||||
|
|
||||||
LodLevel PlanetData::trianglesToVertices(const std::vector<Triangle>& geometry) {
|
LodLevel PlanetData::trianglesToVertices(const std::vector<Triangle>& geometry) {
|
||||||
LodLevel result;
|
LodLevel result;
|
||||||
|
result.triangles = geometry;
|
||||||
|
|
||||||
result.triangles = geometry;
|
size_t vertexCount = geometry.size() * 3;
|
||||||
|
result.vertexData.PositionData.reserve(vertexCount);
|
||||||
|
result.vertexData.NormalData.reserve(vertexCount);
|
||||||
|
result.vertexData.TexCoordData.reserve(vertexCount);
|
||||||
|
result.vertexData.TangentData.reserve(vertexCount); // Äîáàâëÿåì ðåçåðâ
|
||||||
|
result.vertexData.BinormalData.reserve(vertexCount);
|
||||||
|
result.VertexIDs.reserve(vertexCount);
|
||||||
|
|
||||||
result.vertexData.PositionData.reserve(geometry.size() * 3);
|
|
||||||
result.vertexData.NormalData.reserve(geometry.size() * 3);
|
|
||||||
result.vertexData.TexCoordData.reserve(geometry.size() * 3); // <-- ÐÅÇÅÐÂÈÐÓÅÌ
|
|
||||||
//buffer.TexCoord3Data.reserve(triangles.size() * 3); // <-- ÐÅÇÅÐÂÈÐÓÅÌ
|
|
||||||
|
|
||||||
// Ñòàíäàðòíûå UV-êîîðäèíàòû äëÿ ïîêðûòèÿ îäíîãî òðåóãîëüíèêà
|
|
||||||
// Ïîêðûâàåò òåêñòóðîé âñþ ãðàíü.
|
|
||||||
/*const std::array<Vector2f, 3> triangleUVs = {
|
|
||||||
Vector2f(0.5f, 1.0f),
|
|
||||||
Vector2f(0.0f, 1.0f - sqrt(3)*0.5),
|
|
||||||
Vector2f(1.0f, 1.0f - sqrt(3) * 0.5),
|
|
||||||
|
|
||||||
};*/
|
|
||||||
const std::array<Vector2f, 3> triangleUVs = {
|
const std::array<Vector2f, 3> triangleUVs = {
|
||||||
Vector2f(0.5f, 1.0f),
|
Vector2f(0.5f, 1.0f),
|
||||||
Vector2f(0.0f, 0.0f),
|
Vector2f(0.0f, 0.0f),
|
||||||
Vector2f(1.0f, 0.0f),
|
Vector2f(1.0f, 0.0f)
|
||||||
|
|
||||||
};
|
};
|
||||||
result.VertexIDs.reserve(geometry.size() * 3); // Çàïîëíÿåì ID çäåñü
|
|
||||||
|
|
||||||
for (const auto& t : geometry) {
|
for (const auto& t : geometry) {
|
||||||
|
// --- Âû÷èñëÿåì ëîêàëüíûé áàçèñ òðåóãîëüíèêà (êàê â GetRotationForTriangle) ---
|
||||||
|
Vector3f vA = t.data[0];
|
||||||
|
Vector3f vB = t.data[1];
|
||||||
|
Vector3f vC = t.data[2];
|
||||||
|
|
||||||
|
Vector3f x_axis = (vC - vB).normalized(); // Íàïðàâëåíèå U
|
||||||
|
|
||||||
|
Vector3f edge1 = vB - vA;
|
||||||
|
Vector3f edge2 = vC - vA;
|
||||||
|
Vector3f z_axis = edge1.cross(edge2).normalized(); // Íîðìàëü ïëîñêîñòè
|
||||||
|
|
||||||
|
// Ïðîâåðêà íàïðàâëåíèÿ íîðìàëè íàðóæó (îò öåíòðà ïëàíåòû)
|
||||||
|
Vector3f centerToTri = (vA + vB + vC).normalized();
|
||||||
|
if (z_axis.dot(centerToTri) < 0) {
|
||||||
|
z_axis = z_axis * -1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3f y_axis = z_axis.cross(x_axis).normalized(); // Íàïðàâëåíèå V
|
||||||
|
|
||||||
for (int i = 0; i < 3; ++i) {
|
for (int i = 0; i < 3; ++i) {
|
||||||
// Çàïîëíÿåì PositionData
|
|
||||||
result.vertexData.PositionData.push_back(t.data[i]);
|
result.vertexData.PositionData.push_back(t.data[i]);
|
||||||
|
result.vertexData.NormalData.push_back(z_axis); // Ïëîñêàÿ íîðìàëü ãðàíè äëÿ Parallax
|
||||||
// Çàïîëíÿåì NormalData (íîðìàëü = íîðìàëèçîâàííàÿ ïîçèöèÿ íà ñôåðå)
|
|
||||||
result.vertexData.NormalData.push_back(t.data[i].normalized());
|
|
||||||
result.vertexData.TexCoordData.push_back(triangleUVs[i]);
|
result.vertexData.TexCoordData.push_back(triangleUVs[i]);
|
||||||
//result.vertexData.TexCoord2Data.push_back(triangleUVs2[i]);
|
|
||||||
|
|
||||||
// Çàïîëíÿåì VertexIDs
|
// Çàïèñûâàåì âû÷èñëåííûé áàçèñ â êàæäóþ âåðøèíó òðåóãîëüíèêà
|
||||||
|
result.vertexData.TangentData.push_back(x_axis);
|
||||||
|
result.vertexData.BinormalData.push_back(y_axis);
|
||||||
|
|
||||||
result.VertexIDs.push_back(t.ids[i]);
|
result.VertexIDs.push_back(t.ids[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -361,14 +372,16 @@ namespace ZL {
|
|||||||
LodLevel PlanetData::generateSphere(int subdivisions, float noiseCoeff) {
|
LodLevel PlanetData::generateSphere(int subdivisions, float noiseCoeff) {
|
||||||
// 1. Èñõîäíûé îêòàýäð è ïðèñâîåíèå ID
|
// 1. Èñõîäíûé îêòàýäð è ïðèñâîåíèå ID
|
||||||
std::vector<Triangle> geometry = {
|
std::vector<Triangle> geometry = {
|
||||||
{{ 0.0f, 1.0f, 0.0f}, { 0.0f, 0.0f, 1.0f}, { 1.0f, 0.0f, 0.0f}}, // 0
|
// Âåðõíÿÿ ïîëóñôåðà (Y > 0)
|
||||||
{{ 0.0f, 1.0f, 0.0f}, { 1.0f, 0.0f, 0.0f}, { 0.0f, 0.0f, -1.0f}}, // 1
|
{{ 0.0f, 1.0f, 0.0f}, { 1.0f, 0.0f, 0.0f}, { 0.0f, 0.0f, 1.0f}}, // 0
|
||||||
{{ 0.0f, 1.0f, 0.0f}, { 0.0f, 0.0f, -1.0f}, {-1.0f, 0.0f, 0.0f}}, // 2
|
{{ 0.0f, 1.0f, 0.0f}, { 0.0f, 0.0f, -1.0f}, { 1.0f, 0.0f, 0.0f}}, // 1
|
||||||
{{ 0.0f, 1.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}, { 0.0f, 0.0f, 1.0f}}, // 3
|
{{ 0.0f, 1.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}, { 0.0f, 0.0f, -1.0f}}, // 2
|
||||||
{{ 0.0f, -1.0f, 0.0f}, { 1.0f, 0.0f, 0.0f}, { 0.0f, 0.0f, 1.0f}}, // 4
|
{{ 0.0f, 1.0f, 0.0f}, { 0.0f, 0.0f, 1.0f}, {-1.0f, 0.0f, 0.0f}}, // 3
|
||||||
{{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 1.0f}, {-1.0f, 0.0f, 0.0f}}, // 5
|
// Íèæíÿÿ ïîëóñôåðà (Y < 0)
|
||||||
{{ 0.0f, -1.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}, { 0.0f, 0.0f, -1.0f}}, // 6
|
{{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, 1.0f}, { 1.0f, 0.0f, 0.0f}}, // 4
|
||||||
{{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, -1.0f}, { 1.0f, 0.0f, 0.0f}} // 7
|
{{ 0.0f, -1.0f, 0.0f}, { 1.0f, 0.0f, 0.0f}, { 0.0f, 0.0f, -1.0f}}, // 5
|
||||||
|
{{ 0.0f, -1.0f, 0.0f}, { 0.0f, 0.0f, -1.0f}, {-1.0f, 0.0f, 0.0f}}, // 6
|
||||||
|
{{ 0.0f, -1.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}, { 0.0f, 0.0f, 1.0f}} // 7
|
||||||
};
|
};
|
||||||
|
|
||||||
// Ïðèñâîåíèå ID èñõîäíûì âåðøèíàì
|
// Ïðèñâîåíèå ID èñõîäíûì âåðøèíàì
|
||||||
@ -420,7 +433,7 @@ namespace ZL {
|
|||||||
Vector3f dir = lodLevel.vertexData.PositionData[i].normalized();
|
Vector3f dir = lodLevel.vertexData.PositionData[i].normalized();
|
||||||
lodLevel.vertexData.PositionData[i] = dir * perlin.getSurfaceHeight(dir, noiseCoeff);
|
lodLevel.vertexData.PositionData[i] = dir * perlin.getSurfaceHeight(dir, noiseCoeff);
|
||||||
// Îáðàòèòå âíèìàíèå: NormalData îñòàåòñÿ (dir), êàê â âàøåì êîäå
|
// Îáðàòèòå âíèìàíèå: NormalData îñòàåòñÿ (dir), êàê â âàøåì êîäå
|
||||||
lodLevel.vertexData.NormalData[i] = dir;
|
//lodLevel.vertexData.NormalData[i] = dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -16,8 +16,8 @@ namespace ZL {
|
|||||||
|
|
||||||
VertexID generateEdgeID(const VertexID& id1, const VertexID& id2);
|
VertexID generateEdgeID(const VertexID& id1, const VertexID& id2);
|
||||||
|
|
||||||
constexpr static int MAX_LOD_LEVELS = 6;
|
//constexpr static int MAX_LOD_LEVELS = 6;
|
||||||
//constexpr static int MAX_LOD_LEVELS = 2;
|
constexpr static int MAX_LOD_LEVELS = 1;
|
||||||
|
|
||||||
struct Triangle
|
struct Triangle
|
||||||
{
|
{
|
||||||
|
|||||||
130
PlanetObject.cpp
130
PlanetObject.cpp
@ -22,6 +22,7 @@ namespace ZL {
|
|||||||
// Нам нужна грань BC: от (0, 0, 20000) до (20000, 0, 0)
|
// Нам нужна грань BC: от (0, 0, 20000) до (20000, 0, 0)
|
||||||
Vector3f x_axis = (vC - vB).normalized();
|
Vector3f x_axis = (vC - vB).normalized();
|
||||||
|
|
||||||
|
|
||||||
// 2. Вычисляем нормаль (ось Z).
|
// 2. Вычисляем нормаль (ось Z).
|
||||||
// Порядок cross product (AB x AC) определит "лицевую" сторону.
|
// Порядок cross product (AB x AC) определит "лицевую" сторону.
|
||||||
Vector3f edge1 = vB - vA;
|
Vector3f edge1 = vB - vA;
|
||||||
@ -72,47 +73,34 @@ namespace ZL {
|
|||||||
// Берем максимальный LOD для начальной отрисовки
|
// Берем максимальный LOD для начальной отрисовки
|
||||||
int lodIndex = planetData.getMaxLodIndex();
|
int lodIndex = planetData.getMaxLodIndex();
|
||||||
planetRenderStruct.data = planetData.getLodLevel(lodIndex).vertexData;
|
planetRenderStruct.data = planetData.getLodLevel(lodIndex).vertexData;
|
||||||
|
/*planetRenderStruct.data.PositionData[0] = planetRenderStruct.data.PositionData[6 * 3];
|
||||||
|
planetRenderStruct.data.PositionData[0+1] = planetRenderStruct.data.PositionData[6 * 3+1];
|
||||||
|
planetRenderStruct.data.PositionData[0+2] = planetRenderStruct.data.PositionData[6 * 3+2];
|
||||||
|
*/
|
||||||
|
planetRenderStruct.data.PositionData.resize(3);
|
||||||
|
/*planetRenderStruct.data.NormalData[0] = Vector3f{1.0,1.0,1.0}.normalized();
|
||||||
|
planetRenderStruct.data.NormalData[1] = Vector3f{ 1.0,1.0,1.0 }.normalized();
|
||||||
|
planetRenderStruct.data.NormalData[2] = Vector3f{ 1.0,1.0,1.0 }.normalized();*/
|
||||||
planetRenderStruct.RefreshVBO();
|
planetRenderStruct.RefreshVBO();
|
||||||
|
|
||||||
planetRenderStructCut.data = planetData.getLodLevel(lodIndex).vertexData;
|
planetRenderStructCut.data = planetData.getLodLevel(lodIndex).vertexData;
|
||||||
/*planetRenderStructCut.data.PositionData[0] = planetRenderStructCut.data.PositionData[3 * 1 + 0];
|
|
||||||
planetRenderStructCut.data.PositionData[1] = planetRenderStructCut.data.PositionData[3 * 1 + 1];
|
|
||||||
planetRenderStructCut.data.PositionData[2] = planetRenderStructCut.data.PositionData[3 * 1 + 2];
|
|
||||||
*/
|
|
||||||
planetRenderStructCut.data.PositionData.resize(3);
|
planetRenderStructCut.data.PositionData.resize(3);
|
||||||
|
|
||||||
/*
|
|
||||||
Vector4f q1 = QuatFromRotateAroundX(-M_PI * 45.0 / 180.0);
|
|
||||||
Vector4f q2 = QuatFromRotateAroundY(M_PI * 45.0 / 180.0);
|
|
||||||
//Vector4f q3 = {-cos(0.5*M_PI * x / 180.0), -cos(0.5 * M_PI * x / 180.0), -cos(0.5 * M_PI * x / 180.0),sin(0.5 * M_PI * x / 180.0) };
|
|
||||||
|
|
||||||
Matrix3f r1 = QuatToMatrix(q1);
|
|
||||||
|
|
||||||
Matrix3f r2 = QuatToMatrix(q2);
|
|
||||||
|
|
||||||
//Matrix3f r3 = QuatToMatrix(q3);
|
|
||||||
|
|
||||||
Matrix3f m = MultMatrixMatrix(r2, r1);
|
|
||||||
|
|
||||||
Matrix3f invr = InverseMatrix(m);
|
|
||||||
|
|
||||||
planetRenderStructCut.data.RotateByMatrix(invr);*/
|
|
||||||
|
|
||||||
planetRenderStructCut.RefreshVBO();
|
planetRenderStructCut.RefreshVBO();
|
||||||
//sandTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/sand2.png", ""));
|
//sandTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/sand2.png", ""));
|
||||||
sandTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/sandx.png", ""));
|
sandTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/sand2.png", ""));
|
||||||
stoneTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/rockx.png", ""));
|
stoneTexture = std::make_unique<Texture>(CreateTextureDataFromPng("./resources/rock.png", ""));
|
||||||
|
|
||||||
// Атмосфера
|
// Атмосфера
|
||||||
planetAtmosphereRenderStruct.data = planetData.getAtmosphereLod().vertexData;
|
planetAtmosphereRenderStruct.data = planetData.getAtmosphereLod().vertexData;
|
||||||
planetAtmosphereRenderStruct.RefreshVBO();
|
planetAtmosphereRenderStruct.RefreshVBO();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
planetStones = CreateStoneGroupData(777, planetData.getLodLevel(lodIndex));
|
planetStones = CreateStoneGroupData(777, planetData.getLodLevel(lodIndex));
|
||||||
planetStones.inflate({ 0/*,1,2,3,4,5,6,7*/ });
|
planetStones.inflate({ 0/*,1,2,3,4,5,6,7*/ });
|
||||||
planetStonesRenderStruct.AssignFrom(planetStones.mesh);
|
planetStonesToBakeRenderStruct.AssignFrom(planetStones.mesh);
|
||||||
planetStonesRenderStruct.RefreshVBO();
|
planetStonesToBakeRenderStruct.RefreshVBO();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -170,9 +158,12 @@ namespace ZL {
|
|||||||
planetRenderYellowStruct.RefreshVBO();
|
planetRenderYellowStruct.RefreshVBO();
|
||||||
|
|
||||||
// --- ОБНОВЛЯЕМ КАМНИ (через новую структуру StoneGroup) ---
|
// --- ОБНОВЛЯЕМ КАМНИ (через новую структуру StoneGroup) ---
|
||||||
//planetStones.inflate(triangleIndicesToDraw);
|
if (triangleIndicesToDraw.size() > 0)
|
||||||
// Используем AssignFrom, он внутри сам вызывает RefreshVBO
|
{
|
||||||
//planetStonesRenderStruct.AssignFrom(planetStones.mesh);
|
planetStones.inflate(triangleIndicesToDraw);
|
||||||
|
// Используем AssignFrom, он внутри сам вызывает RefreshVBO
|
||||||
|
planetStonesRenderStruct.AssignFrom(planetStones.mesh);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -185,11 +176,13 @@ namespace ZL {
|
|||||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
static const std::string defaultShaderName2 = "defaultColor2";
|
|
||||||
|
static const std::string defaultShaderName2 = "defaultColorBake";
|
||||||
static const std::string vPositionName = "vPosition";
|
static const std::string vPositionName = "vPosition";
|
||||||
static const std::string vTexCoordName = "vTexCoord";
|
static const std::string vTexCoordName = "vTexCoord";
|
||||||
static const std::string textureUniformName = "Texture";
|
static const std::string textureUniformName = "Texture";
|
||||||
|
|
||||||
|
|
||||||
renderer.shaderManager.PushShader(defaultShaderName2);
|
renderer.shaderManager.PushShader(defaultShaderName2);
|
||||||
renderer.RenderUniform1i(textureUniformName, 0);
|
renderer.RenderUniform1i(textureUniformName, 0);
|
||||||
renderer.EnableVertexAttribArray(vPositionName);
|
renderer.EnableVertexAttribArray(vPositionName);
|
||||||
@ -232,33 +225,48 @@ namespace ZL {
|
|||||||
renderer.PushProjectionMatrix(
|
renderer.PushProjectionMatrix(
|
||||||
centerX - width*0.5, centerX + width * 0.5,
|
centerX - width*0.5, centerX + width * 0.5,
|
||||||
centerY - height * 0.5, centerY + height * 0.5,
|
centerY - height * 0.5, centerY + height * 0.5,
|
||||||
currentZNear, currentZFar);
|
//currentZNear, currentZFar);
|
||||||
|
150, 200000);
|
||||||
|
|
||||||
renderer.PushMatrix();
|
renderer.PushMatrix();
|
||||||
renderer.LoadIdentity();
|
renderer.LoadIdentity();
|
||||||
|
|
||||||
|
|
||||||
// Сдвигаем камеру по Z
|
// Сдвигаем камеру по Z
|
||||||
renderer.TranslateMatrix(Vector3f{ 0, 0, -45000 });
|
renderer.TranslateMatrix(Vector3f{ 0, 0, -45000 });
|
||||||
|
|
||||||
// Применяем вращение
|
// Применяем вращение
|
||||||
renderer.RotateMatrix(mr);
|
renderer.RotateMatrix(mr);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Извлекаем нормаль треугольника (это 3-й столбец нашей матрицы вращения)
|
||||||
|
Vector3f planeNormal = { mr.m[2], mr.m[5], mr.m[8] };
|
||||||
|
//Vector3f planeNormal = { 0,0,1 };
|
||||||
|
|
||||||
|
renderer.RenderUniform3fv("uPlanePoint", &tr.data[0].v[0]);
|
||||||
|
renderer.RenderUniform3fv("uPlaneNormal", &planeNormal.v[0]);
|
||||||
|
renderer.RenderUniform1f("uMaxHeight", 8000.f); // Соответствует BASE_SCALE + perturbation
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, sandTexture->getTexID());
|
glBindTexture(GL_TEXTURE_2D, sandTexture->getTexID());
|
||||||
|
|
||||||
renderer.DrawVertexRenderStruct(planetRenderStructCut);
|
renderer.DrawVertexRenderStruct(planetRenderStructCut);
|
||||||
|
|
||||||
glClear(GL_DEPTH_BUFFER_BIT);
|
//glClear(GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
if (planetStonesRenderStruct.data.PositionData.size() > 0)
|
glEnable(GL_CULL_FACE);
|
||||||
|
glCullFace(GL_BACK); // Отсекаем задние грани
|
||||||
|
if (planetStonesToBakeRenderStruct.data.PositionData.size() > 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, stoneTexture->getTexID());
|
glBindTexture(GL_TEXTURE_2D, stoneTexture->getTexID());
|
||||||
renderer.DrawVertexRenderStruct(planetStonesRenderStruct);
|
renderer.DrawVertexRenderStruct(planetStonesToBakeRenderStruct);
|
||||||
CheckGlError();
|
CheckGlError();
|
||||||
}
|
}
|
||||||
|
glDisable(GL_CULL_FACE); // Не забываем выключить, чтобы не сломать остальной рендер
|
||||||
|
|
||||||
renderer.PopMatrix();
|
renderer.PopMatrix();
|
||||||
renderer.PopProjectionMatrix();
|
renderer.PopProjectionMatrix();
|
||||||
renderer.DisableVertexAttribArray(vTexCoordName);
|
renderer.DisableVertexAttribArray(vTexCoordName);
|
||||||
@ -272,7 +280,6 @@ namespace ZL {
|
|||||||
|
|
||||||
prepareDrawData();
|
prepareDrawData();
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
if (stoneMapFB == nullptr)
|
if (stoneMapFB == nullptr)
|
||||||
{
|
{
|
||||||
@ -286,11 +293,12 @@ namespace ZL {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bakeStoneTexture(renderer);
|
//bakeStoneTexture(renderer);
|
||||||
|
|
||||||
glViewport(0, 0, Environment::width, Environment::height);
|
glViewport(0, 0, Environment::width, Environment::height);
|
||||||
//--------------------------
|
//--------------------------
|
||||||
|
|
||||||
|
|
||||||
drawPlanet(renderer);
|
drawPlanet(renderer);
|
||||||
//drawYellowZone(renderer);
|
//drawYellowZone(renderer);
|
||||||
//drawStones(renderer);
|
//drawStones(renderer);
|
||||||
@ -315,6 +323,8 @@ namespace ZL {
|
|||||||
renderer.EnableVertexAttribArray(vPositionName);
|
renderer.EnableVertexAttribArray(vPositionName);
|
||||||
renderer.EnableVertexAttribArray(vColorName);
|
renderer.EnableVertexAttribArray(vColorName);
|
||||||
renderer.EnableVertexAttribArray(vNormalName);
|
renderer.EnableVertexAttribArray(vNormalName);
|
||||||
|
renderer.EnableVertexAttribArray("vTangent");
|
||||||
|
renderer.EnableVertexAttribArray("vBinormal");
|
||||||
renderer.EnableVertexAttribArray(vTexCoordName);
|
renderer.EnableVertexAttribArray(vTexCoordName);
|
||||||
//renderer.EnableVertexAttribArray(vTexCoord3Name);
|
//renderer.EnableVertexAttribArray(vTexCoord3Name);
|
||||||
|
|
||||||
@ -330,12 +340,16 @@ namespace ZL {
|
|||||||
|
|
||||||
renderer.PushMatrix();
|
renderer.PushMatrix();
|
||||||
renderer.LoadIdentity();
|
renderer.LoadIdentity();
|
||||||
renderer.TranslateMatrix({ 0,0, -1.0f * Environment::zoom });
|
//renderer.TranslateMatrix({ 0,0, -1.0f * Environment::zoom });
|
||||||
renderer.RotateMatrix(Environment::inverseShipMatrix);
|
renderer.RotateMatrix(Environment::inverseShipMatrix);
|
||||||
|
|
||||||
|
//renderer.RotateMatrix(QuatToMatrix(QuatFromRotateAroundX(M_PI / 4.0)));
|
||||||
|
//renderer.RotateMatrix(QuatToMatrix(QuatFromRotateAroundY(-M_PI / 4.0)));
|
||||||
|
|
||||||
renderer.TranslateMatrix(-Environment::shipPosition);
|
renderer.TranslateMatrix(-Environment::shipPosition);
|
||||||
|
|
||||||
const Matrix4f viewMatrix = renderer.GetCurrentModelViewMatrix();
|
const Matrix4f viewMatrix = renderer.GetCurrentModelViewMatrix();
|
||||||
|
/*
|
||||||
Vector3f lightDir_World = Vector3f(1.0f, 0.0f, -1.0f).normalized();
|
Vector3f lightDir_World = Vector3f(1.0f, 0.0f, -1.0f).normalized();
|
||||||
// В OpenGL/шейдерах удобнее работать с вектором, указывающим ОТ источника к поверхности.
|
// В OpenGL/шейдерах удобнее работать с вектором, указывающим ОТ источника к поверхности.
|
||||||
Vector3f lightDirection_World = -lightDir_World; // Вектор, направленный от источника
|
Vector3f lightDirection_World = -lightDir_World; // Вектор, направленный от источника
|
||||||
@ -353,31 +367,36 @@ namespace ZL {
|
|||||||
|
|
||||||
renderer.RenderUniform1f("uDistanceToPlanetSurface", dist);
|
renderer.RenderUniform1f("uDistanceToPlanetSurface", dist);
|
||||||
renderer.RenderUniform1f("uCurrentZFar", currentZFar);
|
renderer.RenderUniform1f("uCurrentZFar", currentZFar);
|
||||||
renderer.RenderUniform1f("testShift1", x/500.f);
|
*/
|
||||||
renderer.RenderUniform1f("testShift2", y / 5000.f);
|
|
||||||
|
|
||||||
renderer.RenderUniform1i("Texture", 0);
|
renderer.RenderUniform1i("Texture", 0);
|
||||||
|
|
||||||
renderer.RenderUniform1i("StoneMap", 1);
|
Triangle tr = planetData.getLodLevel(planetData.getCurrentLodIndex()).triangles[0]; // Берем базовый треугольник
|
||||||
glActiveTexture(GL_TEXTURE1);
|
Matrix3f mr = GetRotationForTriangle(tr); // Та же матрица, что и при запекании
|
||||||
|
|
||||||
|
// Позиция камеры (корабля) в мире
|
||||||
|
renderer.RenderUniform3fv("uViewPos", &Environment::shipPosition.v[0]);
|
||||||
|
|
||||||
|
// Передаем матрицу вращения треугольника для перехода в Tangent Space
|
||||||
|
renderer.RenderUniformMatrix3fv("uTangentMatrix", false, &mr.m[0]);
|
||||||
|
|
||||||
|
// Не забудьте масштаб эффекта (глубина камней)
|
||||||
|
//renderer.RenderUniform1f("uHeightScale", 0.08f);
|
||||||
|
//renderer.RenderUniform1f("uHeightScale", -0.01f);
|
||||||
|
renderer.RenderUniform1f("uHeightScale", 0.0f + x / 1000.f);
|
||||||
|
//renderer.RenderUniform1f("uHeightScale", 0.0f);
|
||||||
glBindTexture(GL_TEXTURE_2D, stoneMapFB->getTextureID());
|
glBindTexture(GL_TEXTURE_2D, stoneMapFB->getTextureID());
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, sandTexture->getTexID());
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
renderer.DrawVertexRenderStruct(planetRenderStruct);
|
renderer.DrawVertexRenderStruct(planetRenderStruct);
|
||||||
//glDisable(GL_BLEND);
|
|
||||||
CheckGlError();
|
CheckGlError();
|
||||||
|
|
||||||
|
|
||||||
renderer.PopMatrix();
|
renderer.PopMatrix();
|
||||||
renderer.PopProjectionMatrix();
|
renderer.PopProjectionMatrix();
|
||||||
//renderer.DisableVertexAttribArray(vTexCoord3Name);
|
//renderer.DisableVertexAttribArray(vTexCoord3Name);
|
||||||
renderer.DisableVertexAttribArray(vTexCoord2Name);
|
renderer.DisableVertexAttribArray(vTexCoord2Name);
|
||||||
renderer.DisableVertexAttribArray(vTexCoordName);
|
renderer.DisableVertexAttribArray(vTexCoordName);
|
||||||
renderer.DisableVertexAttribArray(vNormalName);
|
renderer.DisableVertexAttribArray(vNormalName);
|
||||||
|
renderer.DisableVertexAttribArray("vTangent");
|
||||||
|
renderer.DisableVertexAttribArray("vBinormal");
|
||||||
renderer.DisableVertexAttribArray(vColorName);
|
renderer.DisableVertexAttribArray(vColorName);
|
||||||
renderer.DisableVertexAttribArray(vPositionName);
|
renderer.DisableVertexAttribArray(vPositionName);
|
||||||
renderer.shaderManager.PopShader();
|
renderer.shaderManager.PopShader();
|
||||||
@ -444,15 +463,10 @@ namespace ZL {
|
|||||||
|
|
||||||
renderer.RenderUniform3fv("uColor", &color2.v[0]);
|
renderer.RenderUniform3fv("uColor", &color2.v[0]);
|
||||||
|
|
||||||
//glEnable(GL_BLEND);
|
|
||||||
//glBlendFunc(GL_SRC_ALPHA, GL_ONE);// Аддитивное смешивание для эффекта свечения
|
|
||||||
|
|
||||||
if (planetStonesRenderStruct.data.PositionData.size() > 0)
|
if (planetStonesRenderStruct.data.PositionData.size() > 0)
|
||||||
{
|
{
|
||||||
//glBindTexture(GL_TEXTURE_2D, fb->getTextureID());
|
|
||||||
glBindTexture(GL_TEXTURE_2D, stoneTexture->getTexID());
|
glBindTexture(GL_TEXTURE_2D, stoneTexture->getTexID());
|
||||||
renderer.DrawVertexRenderStruct(planetStonesRenderStruct);
|
renderer.DrawVertexRenderStruct(planetStonesRenderStruct);
|
||||||
//glDisable(GL_BLEND);
|
|
||||||
CheckGlError();
|
CheckGlError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -31,6 +31,7 @@ namespace ZL {
|
|||||||
VertexRenderStruct planetRenderYellowStruct;
|
VertexRenderStruct planetRenderYellowStruct;
|
||||||
VertexRenderStruct planetAtmosphereRenderStruct;
|
VertexRenderStruct planetAtmosphereRenderStruct;
|
||||||
VertexRenderStruct planetStonesRenderStruct;
|
VertexRenderStruct planetStonesRenderStruct;
|
||||||
|
VertexRenderStruct planetStonesToBakeRenderStruct;
|
||||||
StoneGroup planetStones;
|
StoneGroup planetStones;
|
||||||
|
|
||||||
std::vector<int> triangleIndicesToDraw;
|
std::vector<int> triangleIndicesToDraw;
|
||||||
|
|||||||
12
Renderer.cpp
12
Renderer.cpp
@ -713,6 +713,18 @@ namespace ZL {
|
|||||||
glDisableVertexAttribArray(shader->attribList[attribName]);
|
glDisableVertexAttribArray(shader->attribList[attribName]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Renderer::RenderUniformMatrix3fv(const std::string& uniformName, bool transpose, const float* value)
|
||||||
|
{
|
||||||
|
auto shader = shaderManager.GetCurrentShader();
|
||||||
|
|
||||||
|
auto uniform = shader->uniformList.find(uniformName);
|
||||||
|
|
||||||
|
if (uniform != shader->uniformList.end())
|
||||||
|
{
|
||||||
|
glUniformMatrix3fv(uniform->second, 1, transpose, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Renderer::RenderUniformMatrix4fv(const std::string& uniformName, bool transpose, const float* value)
|
void Renderer::RenderUniformMatrix4fv(const std::string& uniformName, bool transpose, const float* value)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -124,6 +124,7 @@ namespace ZL {
|
|||||||
void DisableVertexAttribArray(const std::string& attribName);
|
void DisableVertexAttribArray(const std::string& attribName);
|
||||||
|
|
||||||
|
|
||||||
|
void RenderUniformMatrix3fv(const std::string& uniformName, bool transpose, const float* value);
|
||||||
void RenderUniformMatrix4fv(const std::string& uniformName, bool transpose, const float* value);
|
void RenderUniformMatrix4fv(const std::string& uniformName, bool transpose, const float* value);
|
||||||
void RenderUniform1i(const std::string& uniformName, const int value);
|
void RenderUniform1i(const std::string& uniformName, const int value);
|
||||||
void RenderUniform3fv(const std::string& uniformName, const float* value);
|
void RenderUniform3fv(const std::string& uniformName, const float* value);
|
||||||
|
|||||||
@ -38,7 +38,6 @@ namespace ZL {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Икосаэдр (на основе золотого сечения phi)
|
// Икосаэдр (на основе золотого сечения phi)
|
||||||
// Координаты могут быть вычислены заранее для константного икосаэдра.
|
// Координаты могут быть вычислены заранее для константного икосаэдра.
|
||||||
// Здесь только объявление, чтобы показать идею.
|
// Здесь только объявление, чтобы показать идею.
|
||||||
@ -46,12 +45,17 @@ namespace ZL {
|
|||||||
VertexDataStruct CreateBaseConvexPolyhedron(uint64_t seed) {
|
VertexDataStruct CreateBaseConvexPolyhedron(uint64_t seed) {
|
||||||
|
|
||||||
// --- КОНСТАНТЫ ПАРАМЕТРОВ (как вы просили) ---
|
// --- КОНСТАНТЫ ПАРАМЕТРОВ (как вы просили) ---
|
||||||
const float BASE_SCALE = 3.0f; // Îáùèé ðàçìåð êàìíÿ
|
//const float BASE_SCALE = 15.0f; // Îáùèé ðàçìåð êàìíÿ
|
||||||
//const float BASE_SCALE = 100.0f; // Îáùèé ðàçìåð êàìíÿ
|
const float BASE_SCALE = 5000.0f; // Îáùèé ðàçìåð êàìíÿ
|
||||||
const float MIN_AXIS_SCALE = 0.5f; // Ìèíèìàëüíîå ðàñòÿæåíèå/ñæàòèå ïî îñè
|
const float MIN_AXIS_SCALE = 1.0f; // Ìèíèìàëüíîå ðàñòÿæåíèå/ñæàòèå ïî îñè
|
||||||
|
const float MAX_AXIS_SCALE = 1.0f; // Ìàêñèìàëüíîå ðàñòÿæåíèå/ñæàòèå ïî îñè
|
||||||
|
const float MIN_PERTURBATION = 0.0f; // Ìèíèìàëüíîå ðàäèàëüíîå âîçìóùåíèå âåðøèíû
|
||||||
|
const float MAX_PERTURBATION = 0.0f; // Ìàêñèìàëüíîå ðàäèàëüíîå âîçìóùåíèå âåðøèíû
|
||||||
|
/*const float MIN_AXIS_SCALE = 0.5f; // Ìèíèìàëüíîå ðàñòÿæåíèå/ñæàòèå ïî îñè
|
||||||
const float MAX_AXIS_SCALE = 1.5f; // Максимальное растяжение/сжатие по оси
|
const float MAX_AXIS_SCALE = 1.5f; // Максимальное растяжение/сжатие по оси
|
||||||
const float MIN_PERTURBATION = 0.05f; // Минимальное радиальное возмущение вершины
|
const float MIN_PERTURBATION = 0.05f; // Минимальное радиальное возмущение вершины
|
||||||
const float MAX_PERTURBATION = 0.25f; // Максимальное радиальное возмущение вершины
|
const float MAX_PERTURBATION = 0.25f; // Максимальное радиальное возмущение вершины
|
||||||
|
*/
|
||||||
// const size_t SUBDIVISION_LEVEL = 1; // Уровень подразделения (для более круглого камня, пока опустим)
|
// const size_t SUBDIVISION_LEVEL = 1; // Уровень подразделения (для более круглого камня, пока опустим)
|
||||||
|
|
||||||
std::mt19937 engine(static_cast<unsigned int>(seed));
|
std::mt19937 engine(static_cast<unsigned int>(seed));
|
||||||
@ -203,7 +207,7 @@ namespace ZL {
|
|||||||
|
|
||||||
StoneGroup CreateStoneGroupData(uint64_t globalSeed, const LodLevel& planetLodLevel) {
|
StoneGroup CreateStoneGroupData(uint64_t globalSeed, const LodLevel& planetLodLevel) {
|
||||||
StoneGroup group;
|
StoneGroup group;
|
||||||
const int STONES_PER_TRIANGLE = 100;
|
const int STONES_PER_TRIANGLE = 1;
|
||||||
|
|
||||||
// Резервируем место под все треугольники текущего LOD
|
// Резервируем место под все треугольники текущего LOD
|
||||||
group.allInstances.resize(planetLodLevel.triangles.size());
|
group.allInstances.resize(planetLodLevel.triangles.size());
|
||||||
@ -216,8 +220,9 @@ namespace ZL {
|
|||||||
StoneInstance instance;
|
StoneInstance instance;
|
||||||
instance.seed = globalSeed;// + tIdx * 1000 + i; // Уникальный сид для каждого камня
|
instance.seed = globalSeed;// + tIdx * 1000 + i; // Уникальный сид для каждого камня
|
||||||
|
|
||||||
instance.position = GetRandomPointOnTriangle(tri, engine);
|
//instance.position = GetRandomPointOnTriangle(tri, engine);
|
||||||
|
|
||||||
|
instance.position = Vector3f(5000.0f, 5000.0f, 5000.0f);
|
||||||
// Генерируем случайные параметры один раз
|
// Генерируем случайные параметры один раз
|
||||||
instance.scale = {
|
instance.scale = {
|
||||||
getRandomFloat(engine, 0.5f, 1.5f),
|
getRandomFloat(engine, 0.5f, 1.5f),
|
||||||
|
|||||||
34
shaders/defaultColor_bake.vertex
Normal file
34
shaders/defaultColor_bake.vertex
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
// Vertex Shader (Bake Stage)
|
||||||
|
attribute vec3 vPosition;
|
||||||
|
attribute vec2 vTexCoord;
|
||||||
|
attribute vec3 vNormal; // Нормаль самого камня (для освещения при запекании)
|
||||||
|
|
||||||
|
varying vec2 TexCoord;
|
||||||
|
varying float vHeight;
|
||||||
|
varying vec3 vWorldNormal;
|
||||||
|
|
||||||
|
// Данные о плоскости треугольника планеты
|
||||||
|
uniform vec3 uPlanePoint; // Любая вершина треугольника (например, tri.data[0])
|
||||||
|
uniform vec3 uPlaneNormal; // Нормаль треугольника планеты (ось Z из GetRotationForTriangle)
|
||||||
|
uniform float uMaxHeight; // Максимальный размер камня (BASE_SCALE)
|
||||||
|
|
||||||
|
uniform mat4 ProjectionModelViewMatrix;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// 1. Вычисляем вектор от плоскости до текущей вершины камня
|
||||||
|
vec3 vecToVertex = vPosition - uPlanePoint;
|
||||||
|
|
||||||
|
// 2. Проецируем этот вектор на нормаль плоскости (скалярное произведение)
|
||||||
|
// Это и есть кратчайшее расстояние от точки до плоскости
|
||||||
|
float distance = dot(vecToVertex, uPlaneNormal);
|
||||||
|
|
||||||
|
// 3. Нормализуем высоту для записи в текстуру (0.0 - уровень земли, 1.0 - пик)
|
||||||
|
// Clamp гарантирует, что значения не выйдут за пределы, если камень "утоплен"
|
||||||
|
vHeight = clamp(distance / uMaxHeight, 0.0, 1.0);
|
||||||
|
|
||||||
|
TexCoord = vTexCoord;
|
||||||
|
vWorldNormal = vNormal;
|
||||||
|
|
||||||
|
gl_Position = ProjectionModelViewMatrix * vec4(vPosition, 1.0);
|
||||||
|
}
|
||||||
21
shaders/defaultColor_bake_desktop.fragment
Normal file
21
shaders/defaultColor_bake_desktop.fragment
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// Fragment Shader (Bake Stage)
|
||||||
|
varying vec2 TexCoord;
|
||||||
|
varying float vHeight;
|
||||||
|
varying vec3 vWorldNormal;
|
||||||
|
|
||||||
|
uniform sampler2D Texture; // Текстура камня (rock.png)
|
||||||
|
uniform vec3 uLightDir; // Направление света для базового затенения камней при запекании
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 stoneColor = texture2D(Texture, TexCoord);
|
||||||
|
|
||||||
|
// Простое Lambert-освещение, чтобы камни не были "плоскими" в текстуре
|
||||||
|
//float diff = max(dot(normalize(vWorldNormal), normalize(uLightDir)), 0.3);
|
||||||
|
float diff = 1.0;
|
||||||
|
|
||||||
|
// RGB - цвет камня с учетом света, A - нормализованная высота
|
||||||
|
//gl_FragColor = vec4(stoneColor.rgb * diff, vHeight);
|
||||||
|
gl_FragColor = vec4(vHeight, vHeight, vHeight, vHeight);
|
||||||
|
//gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0);
|
||||||
|
}
|
||||||
@ -1,18 +1,26 @@
|
|||||||
// Вершинный шейдер (Vertex Shader)
|
|
||||||
|
|
||||||
attribute vec3 vPosition;
|
attribute vec3 vPosition;
|
||||||
attribute vec2 vTexCoord;
|
attribute vec2 vTexCoord;
|
||||||
|
attribute vec3 vNormal;
|
||||||
|
attribute vec3 vTangent; // Новые атрибуты
|
||||||
|
attribute vec3 vBinormal;
|
||||||
|
|
||||||
varying vec2 TexCoord;
|
varying vec2 TexCoord;
|
||||||
|
varying vec3 vViewDirTangent;
|
||||||
|
|
||||||
uniform mat4 ProjectionModelViewMatrix;
|
uniform mat4 ProjectionModelViewMatrix;
|
||||||
|
uniform vec3 uViewPos;
|
||||||
|
|
||||||
|
void main() {
|
||||||
void main()
|
gl_Position = ProjectionModelViewMatrix * vec4(vPosition, 1.0);
|
||||||
{
|
|
||||||
|
|
||||||
gl_Position = ProjectionModelViewMatrix * vec4(vPosition.xyz, 1.0);
|
|
||||||
|
|
||||||
TexCoord = vTexCoord;
|
TexCoord = vTexCoord;
|
||||||
|
|
||||||
|
vec3 viewDirWorld = normalize(uViewPos - vPosition);
|
||||||
|
|
||||||
|
// Строим матрицу перехода из атрибутов
|
||||||
|
// Так как базис ортонормирован, TBN^-1 == TBN_transpose
|
||||||
|
vViewDirTangent = vec3(
|
||||||
|
dot(viewDirWorld, vTangent),
|
||||||
|
dot(viewDirWorld, vBinormal),
|
||||||
|
dot(viewDirWorld, vNormal)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
@ -1,24 +1,67 @@
|
|||||||
// Fragment Shader
|
|
||||||
varying vec2 TexCoord;
|
varying vec2 TexCoord;
|
||||||
uniform sampler2D Texture; // sandTexture
|
varying vec3 vViewDirTangent;
|
||||||
uniform sampler2D StoneMap; // Наша запеченная текстура
|
|
||||||
uniform float testShift1;
|
|
||||||
uniform float testShift2;
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
vec2 newTexCoord;
|
|
||||||
newTexCoord.x = TexCoord.x;
|
|
||||||
//newTexCoord.y = TexCoord.y - 0.0122;
|
|
||||||
//newTexCoord.y = TexCoord.y * (1.0+testShift) + 0.0122;
|
|
||||||
//newTexCoord.y = (TexCoord.y + 0.0122)*(1.0 +x/500.0);
|
|
||||||
//newTexCoord.y = TexCoord.y * (1.0-6.0/500.0) + 0.0122+ (11.0/500.0) *0.1 -6/5000.0;
|
|
||||||
newTexCoord.y = TexCoord.y;
|
|
||||||
vec4 sandColor = texture2D(Texture, TexCoord);
|
|
||||||
vec4 stoneData = texture2D(StoneMap, newTexCoord);
|
|
||||||
|
|
||||||
//vec3 finalColor = sandColor.rgb*0.5 + stoneData.rgb*0.5;
|
|
||||||
vec3 finalColor = stoneData.rgb;
|
|
||||||
//vec3 finalColor = sandColor.rgb;
|
|
||||||
|
|
||||||
gl_FragColor = vec4(finalColor, 1.0);
|
uniform sampler2D Texture; // Нам нужен только Alpha канал (высота)
|
||||||
}
|
uniform float uHeightScale;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec3 viewDir = normalize(vViewDirTangent);
|
||||||
|
float height = texture2D(Texture, TexCoord).a;
|
||||||
|
|
||||||
|
// Рассчитываем вектор смещения P
|
||||||
|
//vec2 p = viewDir.xy * (height * uHeightScale) / viewDir.z;
|
||||||
|
//vec2 p = vec2(viewDir.y, -viewDir.x) * (height * uHeightScale);
|
||||||
|
//vec2 p = viewDir.xy * (height * uHeightScale);
|
||||||
|
vec2 p = vec2(viewDir.x, -viewDir.y) * (height * uHeightScale);
|
||||||
|
vec2 finalTexCoord = TexCoord + p;
|
||||||
|
|
||||||
|
// 1. Визуализация сетки по смещенным координатам
|
||||||
|
// Если сетка кривая или ломается на стыках — значит T, B, N векторы не сошлись
|
||||||
|
vec2 grid = fract(finalTexCoord * 20.0); // 20 ячеек сетки
|
||||||
|
float line = (step(0.9, grid.x) + step(0.9, grid.y));
|
||||||
|
|
||||||
|
// 2. Визуализация вектора смещения через цвет
|
||||||
|
// Красный = смещение по U, Зеленый = смещение по V
|
||||||
|
vec3 offsetColor = vec3(p * 10.0 + 0.5, 0.0); // Умножаем на 10 для видимости
|
||||||
|
|
||||||
|
vec3 finalColor = mix(offsetColor, vec3(1.0), line); // Накладываем сетку поверх цвета
|
||||||
|
|
||||||
|
// 3. Подмешиваем карту высот, чтобы видеть "объемы"
|
||||||
|
gl_FragColor = vec4(finalColor * height, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
varying vec2 TexCoord;
|
||||||
|
varying vec3 vViewDirTangent;
|
||||||
|
|
||||||
|
uniform sampler2D Texture;
|
||||||
|
uniform float uHeightScale;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec3 viewDir = normalize(vViewDirTangent);
|
||||||
|
|
||||||
|
// Получаем высоту из альфа-канала запеченной текстуры
|
||||||
|
float height = texture2D(Texture, TexCoord).a;
|
||||||
|
|
||||||
|
// Смещение. Знак минус используется, если мы хотим "вдавить" камни
|
||||||
|
// Деление на viewDir.z помогает избежать сильных искажений под углом
|
||||||
|
vec2 p = viewDir.xy * (height * uHeightScale) / viewDir.z;
|
||||||
|
vec2 finalTexCoord = TexCoord + p;
|
||||||
|
|
||||||
|
gl_FragColor = texture2D(Texture, finalTexCoord);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
varying vec2 TexCoord;
|
||||||
|
varying vec3 vViewDirTangent; // Тот самый вектор из VS
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
// 1. Нормализуем входящий вектор
|
||||||
|
vec3 v = normalize(vViewDirTangent);
|
||||||
|
|
||||||
|
// 2. Преобразуем компоненты из [-1, 1] в [0, 1] для визуализации
|
||||||
|
// X -> Red, Y -> Green, Z -> Blue
|
||||||
|
vec3 debugColor = v * 0.5 + 0.5;
|
||||||
|
|
||||||
|
gl_FragColor = vec4(debugColor, 1.0);
|
||||||
|
}*/
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user