diff --git a/PlanetCreator/cw 6/shaders/shader_pbr_instanced.frag b/PlanetCreator/cw 6/shaders/shader_pbr_instanced.frag new file mode 100644 index 0000000..9f2a55b --- /dev/null +++ b/PlanetCreator/cw 6/shaders/shader_pbr_instanced.frag @@ -0,0 +1,72 @@ +#version 430 core +#define PI 3.14159265359 + +float AMBIENT = 0.1; + +uniform vec3 albedo; +uniform float metallic; +uniform float roughness; +uniform vec3 color; +uniform vec3 lightPos; +uniform vec3 viewPos; +uniform vec3 ambientColor; +uniform sampler2D colorTexture; + +in vec3 fragNormal; +in vec3 fragPosition; +in vec2 texCoords; + +out vec4 outColor; + +float specularD(float NdotH, float roughness) +{ + float alpha = roughness * roughness; + float alpha2 = alpha * alpha; + float cos2ThetaH = NdotH * NdotH; + + float expTerm = (cos2ThetaH - 1.0) / (alpha2 * cos2ThetaH); + return exp(expTerm) / (PI * alpha2 * pow(cos2ThetaH + alpha2 - 1.0, 2.0)); +} + +vec3 specularF(float LdotH, vec3 F0) +{ + return F0 + (vec3(1.0) - F0) * pow(1.0 - LdotH, 5.0); +} + +float specularG(float NdotL, float NdotV, float roughness) +{ + float k = (roughness + 1.0) * (roughness + 1.0) / 8.0; + + float GL = NdotL / (NdotL * (1.0 - k) + k); + float GV = NdotV / (NdotV * (1.0 - k) + k); + + return GL * GV; +} + +void main() +{ + vec3 normal = normalize(fragNormal); + vec3 viewDir = normalize(viewPos - fragPosition); + vec3 lightDir = normalize(lightPos - fragPosition); + + vec3 F0 = vec3(0.04); + F0 = mix(F0, albedo, metallic); + + float NdotL = max(dot(normal, lightDir), 0.0); + float NdotV = max(dot(normal, viewDir), 0.0); + + vec3 H = normalize(lightDir + viewDir); + float NdotH = max(dot(normal, H), 0.0); + float LdotH = max(dot(lightDir, H), 0.0); + vec3 albedo = texture(colorTexture, texCoords).rgb; + albedo *= 2.0; + vec3 specular = F0 * (specularD(NdotH, roughness) * specularF(LdotH, F0) * specularG(NdotL, NdotV, roughness)) / (4.0 * NdotL * NdotV); + + vec3 diffuse = (1.0 - F0) * albedo / PI; + + vec3 ambient = ambientColor * AMBIENT; + + vec3 finalColor = ambient + (diffuse + specular) * NdotL; + + outColor = vec4(finalColor, 1.0); +} diff --git a/PlanetCreator/cw 6/shaders/shader_pbr_instanced.vert b/PlanetCreator/cw 6/shaders/shader_pbr_instanced.vert new file mode 100644 index 0000000..5449af3 --- /dev/null +++ b/PlanetCreator/cw 6/shaders/shader_pbr_instanced.vert @@ -0,0 +1,20 @@ +#version 430 core + +layout(location = 0) in vec3 inPosition; +layout(location = 1) in vec3 inNormal; +layout(location = 2) in vec2 inTexCoord; +uniform mat4 modelMatrix[500]; + + +out vec2 texCoords; +out vec3 fragNormal; +out vec3 fragPosition; +uniform sampler2D colorTexture; +void main() +{ + mat4 modelMat = modelMatrix[gl_InstanceID]; + gl_Position = modelMat * vec4(inPosition, 1.0); + fragPosition = (modelMat* vec4(inPosition,1)).xyz; + texCoords = inTexCoord; + fragNormal = (modelMat* vec4(inNormal,0)).xyz; +} diff --git a/PlanetCreator/cw 6/src/Render_Utils.cpp b/PlanetCreator/cw 6/src/Render_Utils.cpp index 3e895eb..c8c249d 100644 --- a/PlanetCreator/cw 6/src/Render_Utils.cpp +++ b/PlanetCreator/cw 6/src/Render_Utils.cpp @@ -205,3 +205,35 @@ void Core::DrawContext(Core::RenderContext& context) glBindVertexArray(0); } + + + + + + + + + +void Core::DrawContextInstanced(Core::RenderContext& context,std::vector matrices,int numberOfInstances, GLuint program) +{ + + GLuint vbo; + glGenBuffers(1, &vbo); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, matrices.size() * sizeof(glm::mat4), matrices.data(), GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + GLint modelMatrixLocation = glGetAttribLocation(program, "modelMatrix"); + glEnableVertexAttribArray(modelMatrixLocation); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glVertexAttribPointer(modelMatrixLocation, 3, GL_FLOAT, GL_FALSE,sizeof(glm::mat4), (void*)0); + glVertexAttribDivisor(modelMatrixLocation, 1); + glBindVertexArray(context.vertexArray); + glDrawElementsInstanced( + GL_TRIANGLES, // mode + context.size, // count + GL_UNSIGNED_INT, // type + 0, numberOfInstances // element array buffer offset + ); + + glBindVertexArray(0); +} \ No newline at end of file diff --git a/PlanetCreator/cw 6/src/Render_Utils.h b/PlanetCreator/cw 6/src/Render_Utils.h index 0438a68..29e8a58 100644 --- a/PlanetCreator/cw 6/src/Render_Utils.h +++ b/PlanetCreator/cw 6/src/Render_Utils.h @@ -70,4 +70,6 @@ namespace Core void DrawVertexArray(const VertexData & data); void DrawContext(RenderContext& context); + void DrawContextInstanced(RenderContext& context, std::vector matrices ,int count,GLuint program); + } \ No newline at end of file diff --git a/PlanetCreator/cw 6/src/ex_6_1.hpp b/PlanetCreator/cw 6/src/ex_6_1.hpp index da001ff..e4e5358 100644 --- a/PlanetCreator/cw 6/src/ex_6_1.hpp +++ b/PlanetCreator/cw 6/src/ex_6_1.hpp @@ -140,7 +140,7 @@ struct PlanetParams { float humidity = 0.0f; // Начальное значение для влажности float temperature = 0.0f; // Начальное значение для осадков - std::vector < std::tuple> Plant_info; + std::vector < std::tuple> Plant_info; // ID , position }; std::vector planets; // Список всех планет @@ -229,6 +229,7 @@ GLuint programSun; GLuint programTex; GLuint program_pbr; GLuint plantProgram; +GLuint program_pbr_instanced; Core::Shader_Loader shaderLoader; GLuint programBiomes; @@ -406,23 +407,59 @@ void drawObjectTexture_plant(Core::RenderContext& context, glm::mat4 modelMatrix Core::DrawContext(context); glUseProgram(0); } +void drawObjectTexture_plantInstanced(Core::RenderContext& context, std::vector modelMatrices, Material& material, GLuint program,int count) { + glUseProgram(program); + Core::SetActiveTexture(material.textureID, "colorTexture", program, 0); + glm::mat4 viewProjectionMatrix = createPerspectiveMatrix() * createCameraMatrix(); + std::vector transformations; + for (const auto& matrix : modelMatrices) + { + glm::mat4 transformation = viewProjectionMatrix* matrix; + transformations.push_back(transformation); + } -void placeObjectOnPlanet(Core::RenderContext& objectContext, glm::mat4 objectMatrix,float scale,glm::vec3 placePoint, PlanetParams planetParams) { + glUniform3f(glGetUniformLocation(program, "lightPos"), 0, 0, 0); + + //Material + glUniform1f(glGetUniformLocation(program, "shininess"), material.Ns); + glUniform3f(glGetUniformLocation(program, "ambientColor"), material.Ka.r, material.Ka.g, material.Ka.b); + glUniform3f(glGetUniformLocation(program, "specularColor"), material.Ks.r, material.Ks.g, material.Ks.b); + glUniform3f(glGetUniformLocation(program, "emissiveColor"), material.Ke.r, material.Ke.g, material.Ke.b); + glUniform1f(glGetUniformLocation(program, "opticalDensity"), material.Ni); + //glUniform1f(glGetUniformLocation(program, "dissolve"), material.d); + glUniform1i(glGetUniformLocation(program, "illuminationModel"), material.illum); + glUniform1f(glGetUniformLocation(program, "metallic"), 0.05); + glUniform1f(glGetUniformLocation(program, "roughness"), 0.2); + Core::DrawContextInstanced(context, transformations,count,program); + glUseProgram(0); +} +void placeObjectOnPlanet(Core::RenderContext& objectContext, glm::mat4 objectMatrix,float scale,std::vectorplacePoints, PlanetParams planetParams,int count) { float planetScale = planetParams.size; - placePoint = glm::normalize(placePoint); - objectMatrix; + glm::mat4 savedobjectMatrix=objectMatrix; objectMatrix = glm::scale(objectMatrix, glm::vec3(scale)); float diameter = 24.4 * planetScale; glm::vec3 base = glm::vec3(0.f, 1.f, 0.f); glm::vec3 axis; float angle; - axis = glm::cross(placePoint, base); - angle = dot(base,placePoint); - angle = acos(angle); - objectMatrix = objectMatrix * glm::rotate(objectMatrix, angle, axis) * glm::translate(base * diameter); - objectMatrix = objectMatrix * glm::translate(planetParams.position*(1/scale)); - drawObjectTexture_plant(objectContext, objectMatrix, plant3Material, program_pbr); + glm::vec3 normalized_placePoint; + std::vector matrices; + matrices.clear(); + for (const auto& placePoint : placePoints) + { + objectMatrix = savedobjectMatrix; + normalized_placePoint = glm::normalize(placePoint); + axis = glm::cross(normalized_placePoint, base); + angle = dot(base, normalized_placePoint); + angle = acos(angle); + objectMatrix = objectMatrix * glm::rotate(objectMatrix, angle, axis) * glm::translate(base * diameter); + objectMatrix = objectMatrix * glm::translate(planetParams.position * (1 / scale)); + matrices.push_back(objectMatrix); + } + + + + drawObjectTexture_plantInstanced(objectContext, matrices, plant3Material, program_pbr_instanced,count); @@ -488,7 +525,7 @@ void animateGrowingTree(float& elapsedTime, float deltaTime, float firstTreeDura void renderScene(GLFWwindow* window) { glClearColor(0.0f, 0.3f, 0.3f, 1.0f); - //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glm::mat4 transformation; float time = glfwGetTime(); @@ -525,11 +562,23 @@ void renderScene(GLFWwindow* window) drawObjectTexture(sphereContext, modelMatrix, planet.texture, program); std::vector>plants = planet.Plant_info; + int plant_type_count = plants.size(); + int types_count = 1; + std::vector current_type_plant_positions; - for (const auto& plant : plants) + for (int i = 0; i < types_count; i++) + { + for (const auto& plant : plants) + { + current_type_plant_positions.push_back(std::get<1>(plant)); + } + //placeObjectOnPlanet(plant_specimens[std::get<0>(plant)].modelContext, glm::mat4(), 0.2, std::get<1>(plant), planet, plant_type_count); + placeObjectOnPlanet(plant_specimens[0].modelContext, glm::mat4(), 0.2, current_type_plant_positions, planet, plant_type_count); + + } + //for (const auto& plant : plants) //TODO: REMOVE PLACEHOLDER - placeObjectOnPlanet(plant_specimens[std::get<0>(plant)].modelContext, glm::mat4(), 0.2, std::get<1>(plant), planet); //animateGrowingTree(elapsedTime, deltaTime, firstTreeDuration, secondTreeDuration, thirdTreeDuration, plant.pos, scaleFactor, plant_2_1_small_Context, plant_2_1_med_Context, plant_2_1Context, plantModelMatrix, plant2_1Material, program_pbr); } @@ -541,7 +590,7 @@ void renderScene(GLFWwindow* window) //drawObjectColor(plant2Context, plantModelMatrix, glm::vec3(1,1,1), program); // drawObjectColor(plant3Context,glm::translate(glm::vec3(1.0f, 0.5f, 3.0f)) *glm::scale(glm::vec3(0.03f)) *glm::rotate(glm::mat4(1.0f), glm::radians(-90.0f), glm::vec3(1.0f, 0.0f, 0.0f)),glm::vec3(1, 1, 1), program); //drawObjectTexture_plant(plant_1_1_small_Context, plantModelMatrix, plant3Material, program_pbr); - //drawObjectTexture_plant(plant_2_1_small_Context, plantModelMatrix, plant2_1Material, program_pbr); + drawObjectTexture_plant(plant_2_1_small_Context, plantModelMatrix, plant2_1Material, program_pbr); //drawObjectColor(plant2Context, plantModelMatrix, glm::vec3(1, 1, 1), program); @@ -594,6 +643,7 @@ void init(GLFWwindow* window) //programSun = shaderLoader.CreateProgram("shaders/shader_5_sun.vert", "shaders/shader_5_sun.frag"); programBiomes = shaderLoader.CreateProgram("shaders/shader_biomes.vert", "shaders/shader_biomes.frag"); program_pbr = shaderLoader.CreateProgram("shaders/shader_pbr.vert", "shaders/shader_pbr.frag"); + program_pbr_instanced= shaderLoader.CreateProgram("shaders/shader_pbr_instanced.vert", "shaders/shader_pbr_instanced.frag"); loadModelToContext2("./models/plants/polygon.obj", plantContext); loadModelToContext("./models/sphere.obj", sphereContext);