TerraForge3D  2.3.1
3D Terrain And Landscape Generator
ShaderTextureNode.cpp
1#include "Shading/ShaderNodes/ShaderTextureNode.h"
2
3#include "Utils/Utils.h"
4#include "Data/ProjectData.h"
5#include "Platform.h"
6
7
8#include <iostream>
9
10static GLSLFunction GetTriplanarBlendFunction()
11{
12 GLSLFunction f("getTriplanarBlend", "vec3 normal", "vec3");
13 f.AddLine(GLSLLine("vec3 blending = abs(normal);", ""));
14 f.AddLine(GLSLLine("blending = normalize(max(blending, 0.000001));", "Force weights to sum to 1.0"));
15 f.AddLine(GLSLLine("float b = (blending.x + blending.y + blending.z);", ""));
16 f.AddLine(GLSLLine("blending /= vec3(b);", ""));
17 f.AddLine(GLSLLine("return blending;", ""));
18 return f;
19}
20
21void ShaderTextureNode::OnEvaluate(GLSLFunction *function, GLSLLine *line)
22{
23 handler->AddFunction(GetTriplanarBlendFunction());
24 function->AddLine(GLSLLine("vec3 " + VAR("tex") + ";", "Variable to store the result"));
25 function->AddLine(GLSLLine("if(" + SDATA(4) + " == 1.0)", "If triplanar mapping is enabled"));
26 function->AddLine(GLSLLine("{", ""));
27 function->AddLine(GLSLLine(""
28 "\tvec3 " + VAR("blending") + " = getTriplanarBlend(Normal);\n"
29 "\t\tvec3 " + VAR("xaxis") + " = texture(_Textures, vec3(FragPos.yz * " + SDATA(0) + " + vec2(" + SDATA(1) + ", " + SDATA(2) + "), " + STR(zCoord) + ")).rgb;\n"
30 "\t\tvec3 " + VAR("yaxis") + " = texture(_Textures, vec3(FragPos.xz * " + SDATA(0) + " + vec2(" + SDATA(1) + ", " + SDATA(2) + "), " + STR(zCoord) + ")).rgb;\n"
31 "\t\tvec3 " + VAR("zaxis") + " = texture(_Textures, vec3(FragPos.xy * " + SDATA(0) + " + vec2(" + SDATA(1) + ", " + SDATA(2) + "), " + STR(zCoord) + ")).rgb;\n"
32 "\t" + VAR("tex") + " = " + VAR("blending") + ".x * " + VAR("xaxis") + " + " + VAR("blending") + ".y * " + VAR("yaxis") + " + " + VAR("blending") + ".z * " + VAR("zaxis") + ";\n"
33 , ""));
34 function->AddLine(GLSLLine("}", ""));
35 function->AddLine(GLSLLine("else", "If texture is not triplanar mapped just sample texture normally"));
36 function->AddLine(GLSLLine("{", ""));
37 function->AddLine(GLSLLine(""
38 "\t" + VAR("tex") + " = texture(_Textures, vec3(TexCoord * " + SDATA(0) + " + vec2(" + SDATA(1) + ", " + SDATA(2) + "), " + STR(zCoord) + ")).rgb;\n"));
39 function->AddLine(GLSLLine("}", ""));
40 line->line = VAR("tex");
41}
42
43void ShaderTextureNode::Load(nlohmann::json data)
44{
45 if(texture != nullptr)
46 {
47 delete texture;
48 texture = nullptr;
49 }
50
51 texture = new Texture2D(ProjectManager::Get()->GetResourcePath() + PATH_SEPARATOR + ProjectManager::Get()->GetAsset(data["texture"]));
52 scale = data["scale"];
53 offsetX = data["offsetX"];
54 offsetY = data["offsetY"];
55 rotation = data["rotation"];
56 isTriplanar = data["isTriplanar"];
57}
58
59nlohmann::json ShaderTextureNode::Save()
60{
61 nlohmann::json data;
62 data["type"] = "ShaderTexture";
63 data["scale"] = scale;
64 data["offsetX"] = offsetX;
65 data["offsetY"] = offsetY;
66 data["rotation"] = rotation;
67 data["isTriplanar"] = isTriplanar;
68 data["texture"] = ProjectManager::Get()->SaveTexture(texture);
69 return data;
70}
71
72void ShaderTextureNode::UpdateShaders()
73{
74 sharedData->d0 = scale;
75 sharedData->d1 = offsetX;
76 sharedData->d2 = offsetY;
77 sharedData->d3 = rotation;
78 sharedData->d4 = isTriplanar ? 1.0f : 0.0f;
79}
80
81void ShaderTextureNode::OnRender()
82{
83 DrawHeader("Texture");
84
85 if(ImGui::ImageButton((ImTextureID)texture->GetRendererID(), ImVec2(150, 150)))
86 {
87 std::string path = ShowOpenFileDialog("*.png\0*.jpg\0");
88
89 if(path.size() > 3)
90 {
91 if(texture)
92 {
93 delete texture;
94 }
95
96 texture = new Texture2D(path);
97 textureManager->UploadToGPU(zCoord);
98 }
99 }
100
101 if(ImGui::BeginDragDropTarget())
102 {
103 if(const ImGuiPayload *payload = ImGui::AcceptDragDropPayload("TerraForge3D_Texture"))
104 {
105 std::string path = std::string((char*)payload->Data);
106 if(path.size() > 3)
107 {
108 if(texture)
109 {
110 delete texture;
111 }
112
113 texture = new Texture2D(path);
114 textureManager->UploadToGPU(zCoord);
115 }
116 }
117
118 ImGui::EndDragDropTarget();
119 }
120
121 ImGui::SameLine();
122 outputPins[0]->Render();
123 ImGui::PushItemWidth(100);
124
125 if(ImGui::DragFloat("Scale", &scale, 0.01f))
126 {
127 sharedData->d0 = scale;
128 }
129
130 if(ImGui::DragFloat("Offset X", &offsetX, 0.01f))
131 {
132 sharedData->d1 = offsetX;
133 }
134
135 if(ImGui::DragFloat("Offset Y", &offsetY, 0.01f))
136 {
137 sharedData->d2 = offsetY;
138 }
139
140 if(ImGui::DragFloat("Rotation", &rotation, 0.01f))
141 {
142 sharedData->d3 = rotation;
143 }
144
145 if(ImGui::Checkbox("Triplanar Mapping", &isTriplanar))
146 {
147 sharedData->d4 = isTriplanar ? 1.0f : 0.0f;
148 }
149
150 ImGui::PopItemWidth();
151}
152
153ShaderTextureNode::ShaderTextureNode(GLSLHandler *handler, ShaderTextureManager *textureManager)
154 :SNENode(handler), textureManager(textureManager)
155{
156 name = "Texture";
157 headerColor = ImColor(SHADER_TEXTURE_NODE_COLOR);
158 outputPins.push_back(new SNEPin(NodeEditorPinType::Output, SNEPinType::SNEPinType_Float3));
159 texture = new Texture2D(GetExecutableDir() + PATH_SEPARATOR "Data" PATH_SEPARATOR "textures" PATH_SEPARATOR "white.png");
160 textureManager->Register(this);
161}
162
163
164ShaderTextureNode::~ShaderTextureNode()
165{
166 textureManager->Unregister(this);
167
168 if(texture != nullptr)
169 {
170 delete texture;
171 texture = nullptr;
172 }
173}
a class to store JSON values
Definition: json.hpp:17860