Advertisement Jump to content
  • Advertisement
    1. Past hour
    2. If your scene has 100 objects, your original code will raycast against those 100 objects, looking for hits, copy the results of up to twenty objects that hit the ray, and then you check if those 20 objects are ground objects. By using layermasking, we first filter out the 100 objects for ground objects. (Of which there might be only one!) Then we do a ray test on those objects. So even if there is no GC difference, there should be a order of magnitude difference, especially as object count and complexity goes up. That and we eliminate the tag check as well. I don't recall if the single hit method returns the closest or not, it would be pretty garbage if it didn't, but I wouldn't be surprised if it didn't, or if it generated more GC that the non-alloc. Though I wonder how much it of a difference there is if compiling to their il2cpp code.
    3. That's why I emphasized that ECS can actually be very simple and minimal while still providing a huge advantage. I think we are thinking and saying mostly the same. I just recommend to give it a try and build the whole gameplay logic in the ECS pattern, since I have made very good experiences with that. At least with my small, simple games where I never had to care about performance or other things where my ultra-low-tech ECS approach might get in the way. P.S.: Dankeschön
    4. Like I stated at the top, some of these are unoptimized examples using local variables. I reuse non-local arrays to keep from generating excess garbage in production code. I started out using normal raycasts(w/o layermasks of course), it's also important to mention that there's really nothing to mask out in most of my use cases. As the ground object is the only thing that can be collided with. Profiling got me to my present methodologies. I shall now venture to test if layermasking reduces the GC as well. As it stands I don't have any GC of measure. I'm also curious if a single result raycast would guarantee the closest hit as my more resource intensive casts are not straight up and down and often return multiple ground hits that are never in a predictable order... More tests, perhaps the topic of my next blog.
    5. I mean that you no longer need to check for multiple hits, therefore don't need to use the Physics.Raycast that returns multiple hits, which should theoretically invoke much less garbage collection than yours,since no array is required.
    6. You can likely find some experienced/proven freelancers on this site if you post an entry in the classifieds. Given the phrasing of the question, I'm assuming you have the capital to finance such outsourcing. https://www.gamedev.net/forums/forum/29-hobby-project-classifieds/ Insofar as partnering with a publisher, or development house, we're talking some serious muscle, or capital, and/or the right prototypes/ideas (which you may have, don't know). In such a case I wouldn't be of much help
    7. Today
    8. Yes you are right (copy-paste mistake). For some reason I cant edit the original post so I'm going to post the code here: Fragment Shader #version 330 core out vec4 Color; in vec2 TexCoord; uniform sampler2D diffuse; void main() { Color = texture(diffuse, TexCoord); }
    9. Hello guys, It was always my dream to create a little game engine (or rather a graphics engine) for fun. I know it's a huge load of work, but that's the challenge. It would be great, if anyone wants to join me in this quest. Programming language doesn't really matter (except for python and javascript.), I prefer C++. I am currently finishing my bachelors degree and have done graphics stuff in the past.
    10. Babaliaris, the fragment shader u posted looks like the vertex shader u posted :-)
    11. If you mean about the vertex specification, you can check it at the constructor of the Renderer class . I don't think I have any vertex data wrong in there. Also I would like to mention that A LOT of people who run Nvidia run my code and everything was rendering fine. But on my computer (AMD GPU) does this. Someone in an older post told me that "Some OpneGL Implementations are more forgiven that others and 99% when a glitch like this appears it's your fault, not the driver's." As much as I want to believe him, I cant' find what else I might be doing wrong.
    12. Vincent Chase

      Deferred shadowmapping

      I was right as it comes to world space position. It was wrong because of this line: float2 cpos = (pixelCoord + 0.5f) * aspectRatio; First of all pixelCoord is already in [0,1] range so adding 0.5 to it made no sense. After changing it to: float2 cpos = pixelCoord; world position is fine. The shadow map still looks broken though. Do you have any further hints on this? I don't like this self shadowing thing:
    13. I really need an experienced game development company to help me with my project that is getting a bit too long to make. Please tell me which companies were the easiest for you to work with 🙃
    14. How many code, it seems to me somewhere there is a problem in the creation of an object - values are incorrectly transmitted. Well, thank you, I openly say that I do not understand, why put a minus?
    15. Sharik

      Weird depth buffer values

      Show your result, curious!
    16. I just signed up and, you know, after seeing this game, I was not disappointed, it is funny!;)
    17. Hello Everyone, http://www.youtube.com/watch?v=V4BEluerj0c Clan N is a beatemup game which combines the classic arcades gameplay with today's modern brawlers. With an ancient far east theme, you'll get challenged across 7 different levels with many different enemies, mid/end level bosses and casual mini games integrated into main gameplay. Features A fast paced beatemup which combines the classic arcades gameplay with today's modern brawlers. A main story with 7 levels divided into more than 50 sections. Levels contain casual minigames which are tightly integrated into the main story and can be played separately as well. Can be played as local or online coop with up to 4 players. A slick and clean pixel based graphics with accompanying far east inspired music and sfx. ScreenShots More information WebSite : http://www.clanngame.com/ Reveal Trailer : http://www.youtube.com/V4BEluerj0c Steam : https://store.steampowered.com/app/982670/Clan_N/ Let me know any questions you may have and happy gaming!
    18. No, even that would be better then camera->move(false, false, false, true); Because even with intellisense it communicates nothing when skimming the code.
    19. jakovo

      Weird depth buffer values

      Ah, I see... yeah, you're right... I had 0.1 / 40000. I don't know why it was set to that, but yeah... changed it and it worked properly too. Thanks!
    20. LoL. Usually when I use enums I'm doing it old style (a bunch of #define statements, not the c++ enum type) bet you would scream more seeing that 😂
    21. I don't have time to look over that huge code dump, but in your main.cpp, the HandleInput... That camera->move() function made me scream then sob. Please, for the love of all that is programming use an enum! enum class movement_direction: unit8_t { forward, back, left, right }; type deal. I'll try and come back later today to look the rest of your code over and see if I can spot anything.
    22. Hi all, I am currently playing around with making a 2D underwater survival game (pet project, not too serious) but I need someone I can sit with for like an hour or so, to help me flesh out some reasonable mechanics for the behavior of liquids and gases in relation to gravity, pressure, etc. (Sorry guys I totally failed science class and have no intention of studying it now). There obviously has to be a balance between what I'm willing to code for and realism and then assistance with understanding some mechanics and how their formulas, etc would work. Some additional info, I am making the game in javascript (web browser) and dont plan on using any physics related engines or libraries. Also my first interests (as a starting point) for development lie in managing water vs oxygen vs immobile material in terms of gravity, weight, flow and pressure, both individually and against each other. The game will naturally use a basic 2D block/grid system similar to what you would see in a game like oxygen not included. If a voice chat not going to be so practical, then here are some of my starting questions: Water has weight and is therefore pulled down by gravity, I know this. I have also heard that water does not compress well, so I probably don't have to worry about deeper water having a higher density due to large amounts of water weight above it. So assuming some constant or formula for gravity and water weight, if you have one tile filled with water, and nothing underneath it, it all falls straight down (not caring much about atmospheric interference). But if you have solid mass underneath, then the water should probably fill tiles to the sides instead. Im guessing a good way of doing this will be to multiply your chosen flow rate by the difference between the fuller tile and the more empty tile or something like that in order to calculate change over time? There should probably also be something else at play here, as the liquid tile falling straight down would be very fast surely vs the 'flowing' into a neighboring tile or am I wrong? Another consideration is how do you handle the concept whereby I believe the water would flow downwards (gravity) first before attempting to flow to neighboring tiles (or am I just being naive here)? Also does gas or high pressure gas have any noticeable effect on any of the 'flow rates'?
    23. Thank you both for your answers! Indeed, as Rutin understood it, there is no need to have both cameras active at once, only one of them. (Although that would be another cool option to consider...!) The point is to have not only a main character but also a second one that plays a parallel role in the story --and some of their actions affect the story in different ways. This particular relationship is a mix of game mechanics and story, and it was difficult imagining one without the other, so I wanted to make sure I had some freedom. Anyway, thank you again. That was my first post, hopefully I'll see you again around here. 🙂
    24. Caused me to laugh at first, now I it's more closer to tears This is where I parse the matrix and after this I do the above calculate_inverse_bind_transform method. std::string matrix_data = el->FirstChildElement("matrix")->GetText();; std::vector<float> f = split_string(matrix_data); float tmp_data[16]; for(int i = 0; i < f.size(); i++) { tmp_data[i] = f.at(i); } glm::mat4 matrix = glm::make_mat4x4(tmp_data); glm::mat4 matrix_transposed = glm::transpose(matrix); if(is_root) { // correct matrix blender use Z as up-axis we use Y glm::mat4 up_axis_correcion = glm::mat4(1.0f); up_axis_correcion = glm::rotate(up_axis_correcion, glm::radians(-90.0f), glm::vec3(1,0,0)); matrix_transposed = matrix_transposed * up_axis_correcion; } I then send it to the shader like this: glm::mat4 projection_view_matrix = projection * view; shader_use(entities[i].shader_id); shader_setMat4(entities[i].shader_id, "projection_view_matrix", projection_view_matrix); for(int j = 0; j < 16; j++) { std::string name = "joint_transforms[" + std::to_string(j) + "]"; shader_setMat4(entities[i].shader_id, name, entities[i].model.meshes[0].local_transforms[j]); } void shader_setMat4(unsigned int shader_id, const std::string &name, const glm::mat4 &mat) { glUniformMatrix4fv(glGetUniformLocation(shader_id, name.c_str()), 1, GL_FALSE, &mat[0][0]); } I tried to make all matrices the identity matrix and send those to the shader, it then renders correctly, not sure if that proves that it has to be the matrices or that the weights or bones can still be wrong?
    25. I got hung up by it for longer than I should have when I first started using multiple cameras, just didn't click right away that I was multiplying the rendering load...
    26. I assumed the OP is just swapping from one character to the next, not rendering multiple camera views at once, maybe I misunderstood the post. If the OP is wanting more than one camera view to render out then some form of optimization might be required depending on the target specs, and what is being outputted. There will be no performance issue if you're just changing cameras from one area to another but maintaining a single 'active' camera view. Thanks for pointing that out!
    27. So, I'm trying to solve this problem for months. I have already opened relative threads for this but now that I learned a lot of stuff I still seek your help for this one. What I learned so far when dealing with texture Uploading and Pixel Reads: 1) Make sure how many channels the source image file has in order to configure the glTexImage2D() to read the data correctly. 2) Make sure that the width * num_OfChannels of the image is multiple of 4, so you won't have problems with the alignment. (OpenGL Common Mistakes, Texture Upload And Pixel Reads) 3) Forcing any kind of texture (R, RG, RGB) to have exactly 4 channels ALWAYS works (But you waste a lot of memory)!!! Below, I'm going to show you step by step what I tried and what glitches are occurring, NOTICE that even if I'm creating more than one textures I ONLY render the first one a.jpg: First check out my texture code. As you can see I'm configuring glTexImage2D() to read pixel data based on how many channels they have (I'm only using textures with 3 and 4 channels) and I already made sure that the width * channels for each image is multiple of 4. #include "texture.h" #include "stb_image/stb_image.h" #include "glcall.h" #include "engine_error.h" #include <math.h> Texture::Texture(std::string path, bool trans, int unit) { //Reverse the pixels. stbi_set_flip_vertically_on_load(1); //Try to load the image. unsigned char *data = stbi_load(path.c_str(), &m_width, &m_height, &m_channels, 0); //Debug. float check = (m_width * m_channels) / 4.0f; printf("file: %20s \tchannels: %d, Divisible by 4: %s, width: %d, height: %d, widthXheight: %d\n", path.c_str(), m_channels, check == ceilf(check) ? "yes" : "no", m_width, m_height, m_width * m_height); /* //The length of the pixes row is multiple of 4. if ( check == ceilf(check) ) { GLCall(glPixelStorei(GL_UNPACK_ALIGNMENT, 4)); } //It's NOT!!!! else { GLCall(glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); } */ //Image loaded successfully. if (data) { //Generate the texture and bind it. GLCall(glGenTextures(1, &m_id)); GLCall(glBindTexture(GL_TEXTURE_2D, m_id)); //Not Transparent texture. if (m_channels == 3) { GLCall(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_width, m_height, 0, GL_RGB, GL_UNSIGNED_BYTE, data)); } //Transparent texture. else if (m_channels == 4) { GLCall(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data)); } else { throw EngineError("Unsupported Channels!!!"); } //Texture Filters. GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)); GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)); GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST)); GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); //Generate mipmaps. GLCall(glGenerateMipmap(GL_TEXTURE_2D)); } //Loading Failed. else throw EngineError("The was an error loading image: " + path); //Unbind the texture. GLCall(glBindTexture(GL_TEXTURE_2D, 0)); //Free the image data. stbi_image_free(data); } Texture::~Texture() { GLCall(glDeleteTextures(1, &m_id)); } void Texture::Bind(int unit) { GLCall(glActiveTexture(GL_TEXTURE0 + unit)); GLCall(glBindTexture(GL_TEXTURE_2D, m_id)); } Now Check out the Main.cpp File #include "Renderer.h" #include "camera.h" Camera *camera; //Handle Key Input. void HandleInput(GLFWwindow *window) { //Exit the application with ESCAPE KEY. if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) glfwSetWindowShouldClose(window, 1); //Move Forward. if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) camera->Move(true); //Move Backward. if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) camera->Move(false, true); //Move left. if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) camera->Move(false, false, true); //Move right. if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) camera->Move(false, false, false, true); } //Mouse Input. void MouseInput(GLFWwindow *window, double x, double y) { camera->UpdateRotation(x, y); } //Mouse Zoom input. void MouseZoom(GLFWwindow *window, double x, double y) { camera->UpdateZoom(x, y); } int main(void) { GLFWwindow* window; /* Initialize the library */ if (!glfwInit()) return -1; //Use openGL version 3.3 Core Profile. glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); /* Create a windowed mode window and its OpenGL context */ window = glfwCreateWindow(800, 600, "Hello World", NULL, NULL); if (!window) { glfwTerminate(); return -1; } /* Make the window's context current */ glfwMakeContextCurrent(window); //Initialize GLEW. if (glewInit() != GLEW_OK) { glfwTerminate(); return -1; } //Set Callback functions. glfwSetCursorPosCallback(window, MouseInput); glfwSetScrollCallback(window, MouseZoom); //Disable the cursor. glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); //Enable Depth Test. GLCall(glEnable(GL_DEPTH_TEST)); //Get the max texture size. GLint size; GLCall(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &size)); std::cout << "Texture Max Size: "<< size << std::endl; camera = new Camera(glm::vec3(0.0f, 0.0f, 3.0f)); Renderer *renderer = new Renderer(); Shader *shader = new Shader("Shaders/basic_vertex.glsl", "Shaders/basic_fragment.glsl"); Texture *texture1 = new Texture("Resources/a.jpg", false); Texture *texture2 = new Texture("Resources/container.jpg", false); Texture *texture3 = new Texture("Resources/brick2.jpg", false); Texture *texture4 = new Texture("Resources/brick3.jpg", false); //Forget this texture. //Texture *texture5 = new Texture("Resources/brick4.jpg", false); Texture *texture6 = new Texture("Resources/container2.png", true); /* Loop until the user closes the window */ while (!glfwWindowShouldClose(window)) { //Handle input. HandleInput(window); //Clear the screen. renderer->ClearScreen(0.0f, 0.0f, 0.0f); //Render the cube. renderer->Render(texture1, shader, camera); //Update. renderer->Update(window); } //-------------Clean Up-------------// delete camera; delete renderer; delete shader; //forget about textures for now. //-------------Clean Up-------------// glfwTerminate(); return 0; } I will put the code of the rest classes and the glsl shaders at the end if you want to check them out, but i assure you that they work just fine. Now if i run the code below I'm getting this: Now lets see what happens if I'm loading the textures one by one starting from the first one which is the only one i render. Attempt 1: Texture *texture1 = new Texture("Resources/a.jpg", false); //Texture *texture2 = new Texture("Resources/container.jpg", false); //Texture *texture3 = new Texture("Resources/brick2.jpg", false); //Texture *texture4 = new Texture("Resources/brick3.jpg", false); //Forget this texture. //Texture *texture5 = new Texture("Resources/brick4.jpg", false); //Texture *texture6 = new Texture("Resources/container2.png", true); Attempt 2: Texture *texture1 = new Texture("Resources/a.jpg", false); Texture *texture2 = new Texture("Resources/container.jpg", false); //Texture *texture3 = new Texture("Resources/brick2.jpg", false); //Texture *texture4 = new Texture("Resources/brick3.jpg", false); //Forget this texture. //Texture *texture5 = new Texture("Resources/brick4.jpg", false); //Texture *texture6 = new Texture("Resources/container2.png", true); Attempt 3: Texture *texture1 = new Texture("Resources/a.jpg", false); Texture *texture2 = new Texture("Resources/container.jpg", false); Texture *texture3 = new Texture("Resources/brick2.jpg", false); //Texture *texture4 = new Texture("Resources/brick3.jpg", false); //Forget this texture. //Texture *texture5 = new Texture("Resources/brick4.jpg", false); //Texture *texture6 = new Texture("Resources/container2.png", true); Attempt 4 (Orange Glitch Appears) Texture *texture1 = new Texture("Resources/a.jpg", false); Texture *texture2 = new Texture("Resources/container.jpg", false); Texture *texture3 = new Texture("Resources/brick2.jpg", false); Texture *texture4 = new Texture("Resources/brick3.jpg", false); //Forget this texture. //Texture *texture5 = new Texture("Resources/brick4.jpg", false); //Texture *texture6 = new Texture("Resources/container2.png", true); Attempt 5 (Grey Glitch Appears) Texture *texture1 = new Texture("Resources/a.jpg", false); Texture *texture2 = new Texture("Resources/container.jpg", false); Texture *texture3 = new Texture("Resources/brick2.jpg", false); Texture *texture4 = new Texture("Resources/brick3.jpg", false); //Forget this texture. //Texture *texture5 = new Texture("Resources/brick4.jpg", false); Texture *texture6 = new Texture("Resources/container2.png", true); If you see it, they only texture which I'm rendering is the first one, so how can the loading of the rest textures affect the rendering, since I'm not using them? (I'm binding the first texture before every draw call, you can check it out in the renderer class). This is so weird I literally can't think anything that causes the problem. Now check this out. I'm going to run Attempt 5 again but with these changes in the Texture class (I'm going to Force 4 channels no matter what the source file's channels😞 #include "texture.h" #include "stb_image/stb_image.h" #include "glcall.h" #include "engine_error.h" #include <math.h> Texture::Texture(std::string path, bool trans, int unit) { //Reverse the pixels. stbi_set_flip_vertically_on_load(1); //Try to load the image. unsigned char *data = stbi_load(path.c_str(), &m_width, &m_height, &m_channels, 4); //FORCE 4 CHANNELS. //Debug. float check = (m_width * m_channels) / 4.0f; printf("file: %20s \tchannels: %d, Divisible by 4: %s, width: %d, height: %d, widthXheight: %d\n", path.c_str(), m_channels, check == ceilf(check) ? "yes" : "no", m_width, m_height, m_width * m_height); /* //The length of the pixes row is multiple of 4. if ( check == ceilf(check) ) { GLCall(glPixelStorei(GL_UNPACK_ALIGNMENT, 4)); } //It's NOT!!!! else { GLCall(glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); } */ //Image loaded successfully. if (data) { //Generate the texture and bind it. GLCall(glGenTextures(1, &m_id)); GLCall(glBindTexture(GL_TEXTURE_2D, m_id)); /* //Not Transparent texture. if (m_channels == 3) { GLCall(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_width, m_height, 0, GL_RGB, GL_UNSIGNED_BYTE, data)); } //Transparent texture. else if (m_channels == 4) { GLCall(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data)); } else { throw EngineError("Unsupported Channels!!!"); } */ GLCall(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data)); //Texture Filters. GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)); GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)); GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST)); GLCall(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); //Generate mipmaps. GLCall(glGenerateMipmap(GL_TEXTURE_2D)); } //Loading Failed. else throw EngineError("The was an error loading image: " + path); //Unbind the texture. GLCall(glBindTexture(GL_TEXTURE_2D, 0)); //Free the image data. stbi_image_free(data); } Texture::~Texture() { GLCall(glDeleteTextures(1, &m_id)); } void Texture::Bind(int unit) { GLCall(glActiveTexture(GL_TEXTURE0 + unit)); GLCall(glBindTexture(GL_TEXTURE_2D, m_id)); } Rendering is what I expected! But I still can't understand why this fixes it. In the first version of my texture class, which I don't force 4 channels but instead I'm using the default channels, I'm configuring glTexImage2D the right way based on the source files channels and also I'm SURE that the width * channels of each image file is multiple of 4.But again in the second version of my texture class, which solve's the problem my mind is thinking again that this might be an alignment problem but it's not, I made sure of that. So what else can cause such a problem? Does anybody knows the answer? Below you will find the rest of the code: Vertex Shader: #version 330 core layout(location = 0) in vec3 aPos; layout(location = 1) in vec3 aNormal; layout(location = 2) in vec2 aTexCoord; uniform mat4 model; uniform mat4 view; uniform mat4 proj; out vec2 TexCoord; void main() { gl_Position = proj * view * model * vec4(aPos, 1.0); TexCoord = aTexCoord; } Fragment Shader: #version 330 core layout(location = 0) in vec3 aPos; layout(location = 1) in vec3 aNormal; layout(location = 2) in vec2 aTexCoord; uniform mat4 model; uniform mat4 view; uniform mat4 proj; out vec2 TexCoord; void main() { gl_Position = proj * view * model * vec4(aPos, 1.0); TexCoord = aTexCoord; } Renderer Class: #include "Renderer.h" Renderer::Renderer() { //Vertex Data. float vertices[] = { // positions // normals // texture coords -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f, 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f }; //Generate a VAO and a VBO. GLCall(glGenVertexArrays(1, &m_VAO)); GLCall(glGenBuffers(1, &m_VBO)); //Bind VAO and VBO. GLCall(glBindVertexArray(m_VAO)); GLCall(glBindBuffer(GL_ARRAY_BUFFER, m_VBO)); //Transfer The Data. GLCall(glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW)); //Positions. GLCall(glEnableVertexAttribArray(0)); GLCall(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 8, (void *)0)); //Normals. GLCall(glEnableVertexAttribArray(1)); GLCall(glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 8, (void *) 12)); //Texture Coordinates. GLCall(glEnableVertexAttribArray(2)); GLCall(glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 8, (void *) 24)); //Unbind The Buffers. GLCall(glBindVertexArray(0)); GLCall(glBindBuffer(GL_ARRAY_BUFFER, 0)); } Renderer::~Renderer() { } void Renderer::ClearScreen(float r, float g, float b) { GLCall(glClearColor(r, g, b, 1.0f)); GLCall(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); } void Renderer::Update(GLFWwindow * window) { glfwSwapBuffers(window); glfwPollEvents(); } void Renderer::Render(Texture *texture, Shader *program, Camera *camera) { //Bind VAO. GLCall(glBindVertexArray(m_VAO)); //Bind The Program. program->Bind(); //Set the unit to be used on the shader. program->SetUniform1i("diffuse", 0); //Bind the texture at unit zero. texture->Bind(0); glm::mat4 model = glm::mat4(1.0f); glm::mat4 view = glm::mat4(1.0f); glm::mat4 proj = glm::mat4(1.0f); //Get The View Matrix. view = camera->GetView(); //Create The Perspective Projection. proj = glm::perspective(glm::radians(camera->m_fov), 800.0f / 600, 0.1f, 100.0f); //Set the transformation uniforms. program->SetUniformMat4f("model", model); program->SetUniformMat4f("view", view); program->SetUniformMat4f("proj", proj); //Draw Call. GLCall(glDrawArrays(GL_TRIANGLES, 0, 36)); } Shader Class: #include "shader.h" #include "glcall.h" #include "engine_error.h" #include <fstream> #include <string> #include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/type_ptr.hpp> struct ShaderSource { std::string vertex_src; std::string fragment_src; }; static void ReadSources(std::string filename, bool is_vertex, struct ShaderSource *src) { //Create a file object. std::ifstream file; //Open the file. file.open(filename, std::ios::in); //If the file opened successfully read it. if (file.is_open()) { //Size of the file. file.seekg(0, std::ios::end); std::streampos size = file.tellg(); file.seekg(0, std::ios::beg); //Allocate memory to store the data. char *data = (char *)malloc(sizeof(char) * (size + (std::streampos)1) ); //Read the data from the file. file.read(data, size); //Close the string. data[file.gcount()] = '\0'; //Close the file. file.close(); //This was the vertex file. if (is_vertex) src->vertex_src = (const char *)data; //This was the fragment file. else src->fragment_src = (const char *)data; //Release the memory for the data since I coppied them into the ShaderSource structure. free(data); } //Problem opening the file. else throw EngineError("There was a problem opening the file: " + filename); } static unsigned int CompileShader(std::string source, GLenum type) { //__________Local Variables__________// int length, success; //__________Local Variables__________// //Create the shader object. GLCall(unsigned int shader = glCreateShader(type)); //std::string to const c string. const char *src = source.c_str(); //Copy the source code into the shader object. GLCall(glShaderSource(shader, 1, &src, NULL)); //Compile the shader. GLCall(glCompileShader(shader)); //Get the shader info length. GLCall(glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length)); //Get the shader compilations status. GLCall(glGetShaderiv(shader, GL_COMPILE_STATUS, &success)); //Compilation Failed. if (!success) { //Error string. std::string error; //Allocate memory for the info log. char *info = (char *)malloc(sizeof(char) * (length+1) ); //Get the info. GLCall(glGetShaderInfoLog(shader, length, NULL, info)); //Terminate the string. info[length] = '\0'; //Initialize the error message as vertex compilation error. if (type == GL_VERTEX_SHADER) error = "Vertex Shader compilations error: "; //Initialize the error message as fragment compilation error. else error = "Fragment Shader compilation error: "; //Add the info log to the message. error += info; //Free info. free(info); //Throw a message error. throw EngineError(error); } return shader; } static unsigned int CreateProgram(ShaderSource &src) { //__________Local Variables__________// int length, success; //__________Local Variables__________// unsigned int program = glCreateProgram(); unsigned int vertex_shader = CompileShader(src.vertex_src, GL_VERTEX_SHADER); unsigned int fragment_shader = CompileShader(src.fragment_src, GL_FRAGMENT_SHADER); GLCall(glAttachShader(program, vertex_shader)); GLCall(glAttachShader(program, fragment_shader)); GLCall(glLinkProgram(program)); GLCall(glValidateProgram(program)); //Get the shader info length. GLCall(glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length)); //Get the shader compilations status. GLCall(glGetProgramiv(program, GL_LINK_STATUS, &success)); //Linking Failed. if (!success) { //Error string. std::string error = "Linking Error: "; //Allocate memory for the info log. char *info = (char *)malloc(sizeof(char) * (length + 1)); //Get the info. GLCall(glGetProgramInfoLog(program, length, NULL, info)); //Terminate the string. info[length] = '\0'; //Add the info log to the message. error += info; //Free info. free(info); //Throw a message error. throw EngineError(error); } return program; } Shader::Shader(std::string vertex_filename, std::string fragment_filename) { //Create a ShaderSource object. ShaderSource source; //Read the sources. ReadSources(vertex_filename, true, &source); ReadSources(fragment_filename, false, &source); //Create the program. m_id = CreateProgram(source); //And start using it. this->Bind(); } Shader::~Shader() { } void Shader::Bind() { GLCall(glUseProgram(m_id)); } void Shader::SetUniform1i(std::string name, int value) { //Bind the shader. this->Bind(); //Get uniform location. GLCall(int location = glGetUniformLocation(m_id, name.c_str())); //Set the value. GLCall(glUniform1i(location, value)); } void Shader::SetUniformMat4f(std::string name, glm::mat4 mat) { //Bind the shader. this->Bind(); //Get uniform location. GLCall(int location = glGetUniformLocation(m_id, name.c_str())); //Set the mat4. GLCall(glUniformMatrix4fv(location, 1, GL_FALSE, glm::value_ptr(mat))); } void Shader::SetUniformVec3(std::string name, glm::vec3 vec3) { //Bind the shader. this->Bind(); //Get uniform location. GLCall(int location = glGetUniformLocation(m_id, name.c_str())); //Set the Uniform. GLCall(glUniform3f(location, vec3.x, vec3.y, vec3.z)); } void Shader::SetUniform1f(std::string name, float value) { //Bind the shader. this->Bind(); //Get uniform location. GLCall(int location = glGetUniformLocation(m_id, name.c_str())); GLCall(glUniform1f(location, value)); } Camera Class: #include "camera.h" #include <glm/gtc/matrix_transform.hpp> #include <iostream> Camera::Camera(glm::vec3 cam_pos) : m_cameraPos(cam_pos), m_pitch(0), m_yaw(-90), m_FirstTime(true), m_sensitivity(0.1), m_fov(45.0) { //Calculate last x and y. m_lastx = 800 / 2.0f; m_lasty = 600 / 2.0f; } Camera::~Camera() { } void Camera::Move(bool forward, bool backward, bool left, bool right) { //Move Forward. if (forward) m_cameraPos += m_cameraFront * m_speed; //Move Backwards. else if (backward) m_cameraPos -= m_cameraFront * m_speed; //Move Left. if (left) m_cameraPos += glm::normalize(glm::cross(m_cameraUp, m_cameraFront)) * m_speed; //Move Right. else if (right) m_cameraPos -= glm::normalize(glm::cross(m_cameraUp, m_cameraFront)) * m_speed; } glm::mat4 Camera::GetView() { return glm::lookAt(m_cameraPos, m_cameraPos + m_cameraFront, m_cameraUp); } void Camera::UpdateRotation(double xpos, double ypos) { //First time, don't do anything. if (m_FirstTime) { m_lastx = xpos; m_lasty = ypos; m_FirstTime = false; } //Get the offset for pitch and yaw. float xoffset = (xpos - m_lastx) * m_sensitivity; float yoffset = (m_lasty - ypos) * m_sensitivity; //Update lastX and lastY. m_lastx = xpos; m_lasty = ypos; //Add them to pitch and yaw. m_pitch += yoffset; m_yaw += xoffset; //Limits for pitch. if (m_pitch > 89.0f) m_pitch = 89.0f; if (m_pitch < -89.0f) m_pitch = -89.0f; //Calculate the new vector. glm::vec3 front = glm::vec3(1.0f); front.x = cos(glm::radians(m_pitch)) * cos(glm::radians(m_yaw)); front.y = sin(glm::radians(m_pitch)); front.z = cos(glm::radians(m_pitch)) * sin(glm::radians(m_yaw)); //Create the direction camera front vector. m_cameraFront = front; } void Camera::UpdateZoom(double x, double y) { m_fov -= y; if (m_fov <= 25) m_fov = 25; else if (m_fov > 45) m_fov = 45; std::cout << m_fov << std::endl; }
    28. Yes. There are file searchers that can search by name thru literally all files (over 500k of them for me) on a disk or few/all disks (I have an OS 256 GB SDD and a 1TB HDD) in a couple of milliseconds like that (I never perceived a delay in one I use). I also use http://www.voidtools.com/support/everything/ I didn't list that one since a file searcher doesn't help with finding out what kind, size and amount of files are in the folder as conveniently as WinDirStat or similar does. WinDirStat is old and also doesn't use NTFS MFT but it's fast enough for me (a minute or two at most) and I prefer it over some tool that has an ad or banner asking me to buy/donate. It's development seems dead but it's FOSS so if needed I could compile or extend it myself even (but it's written in C++ with MFC). Reading raw disk is also very easy via WinAPI but you need admin rights and to seek/read by sector size and have right flags (and know NTFS structure from somewhere): https://support.microsoft.com/en-us/help/100027/info-direct-drive-access-under-win32 This C program prints sizes of all NTFS partitions taken from their NTFS headers: https://gist.github.com/FRex/5ee5d6efd4910ad90b24a84a429dfe9b I've no idea if there is a special purpose API for NTFS MFT in WinAPI or COM. There might be. I googled but couldn't find it. If you ever want to play with NTFS structure then make a 1 GB ram disk, format it as NTFS, copy some files onto it and saving that ramdisk to a file. It will let you open it easier in a hex editor or a normal non-admin ran program. I use Imdisk for my ram disk needs: http://www.ltr-data.se/opencode.html/#ImDisk 7zip also supports opening an NTFS image (and few other FS formats and many archive formats): https://www.7-zip.org/ NTFS MFT also keeps names of deleted files (I'm not sure how long) in MFT so if you ever delete your very_evil_plans.txt you're not in the clear just yet (even when it's gone from trash bin). Yes. That and not hiding extensions are two very useful things to programmers and most people. It's silly they are off by default.
    29. On the MSDN page about implicit state transitions, GENERIC_READ is not in the table of supported implicit transitions: https://docs.microsoft.com/en-us/windows/desktop/direct3d12/using-resource-barriers-to-synchronize-resource-states-in-direct3d-12#implicit-state-transitions which is a bit confusing. But it mentions that: "All buffer resources as well as textures with the D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS flag set are implicitly promoted from D3D12_RESOURCE_STATE_COMMON to the relevant state on first GPU access, including GENERIC_READ to cover any read scenario. Any resource in the COMMON state can be accessed as through it were in a single state with 1 WRITE flag, or 1 or more READ flags" My take on this is that it is safe to assume that from COMMON state, the resource will be implicitly promoted to first PIXEL_SHADER_RESOURCE then NON_PIXEL_SHADER_RESOURCE in your case because multiple read flags can be combined. In my experience it is safe to rely on this, so for read only textures (eg. assets), vertex buffers, etc. you don't ever need to care about transitioning explicitly. Maybe when you first copy data into them, their state will be left as COPY_DEST, but unless you do that on your main rendering command list (you probably shouldn't), then by the time you bind it to a shader, they are decayed into COMMON already. This way I never saw any problems with it, but maybe a more experienced person can correct me.
    30. I played it. Have you played it to the finish? Seems each enemy you encounter will deal damage, I noticed there is an ability to use health-potions. But alas I didn't find one before I died. I did stack up gold bars though.
    31. I bet if you posted this as a question in the math and physics forum, mentioned the language/engine, you would end up with all the answers you need in no time. These cats are smart. Plus I think it's a relatively easy effect to fake from my miscellaneous readings here and there.. You can begin to simulate buoyancy by simply adding an upwards force to the object to negate the effect of gravity, if you make the force proportional to the mass or "composition" of the object then you can make it more realistic. It might be helpful to lock or to selective lock the rotation of one or multiple axes if you aren't interested in doing a FULL physics simulation to control the object rotation and etc... But I assume those would be under player control somewhat anyhow. Another method might be to not use gravity at all and do it like a space simulation, only you would dampen the movement to represent the fluid friction and/or add forces to represent current flow. Good Luck! https://www.gamedev.net/forums/forum/7-math-and-physics/
    32. Splash Damage, developers of Dirty Bomb, have released the game design document, art book, and soundtrack for Dirty Bomb. According to their blog post: The Game Design document includes hundreds of pages of designs, sketches, notes, concept art, biro drawings, user stories and more. It can be downloaded here: link The Art Book looks at many of the original concepts for Dirty Bomb; from maps and characters to weapons and vehicles. It can be downloaded here: link The original soundtrack can be downloaded here: link
    33. Splash Damage, developers of Dirty Bomb, have released the game design document, art book, and soundtrack for Dirty Bomb. According to their blog post: The Game Design document includes hundreds of pages of designs, sketches, notes, concept art, biro drawings, user stories and more. It can be downloaded here: link The Art Book looks at many of the original concepts for Dirty Bomb; from maps and characters to weapons and vehicles. It can be downloaded here: link The original soundtrack can be downloaded here: link View full story
    34. Keep in mind that using multiple cameras can quickly hinder performance if care isn't taken to make sure only one is rendering at full speed/resolution at a time. This is mostly important if you want to maintain some kind of view of the other character. Of course this is somewhat dependent on hardware and etc,etc,etc.. Sounds like a fun project!
    35. SergFD

      {Rev-Share} Looking for C# Unity Devs

      Hi I'am interested. c# developer
    36. Hi all, I am currently playing around with making a 2D underwater survival game (pet project, not too serious) but I need someone I can sit with for like an hour or so, to help me flesh out some reasonable mechanics for the behavior of liquids and gases in relation to gravity, pressure, etc. (Sorry guys I totally failed science class and have no intention of studying it now). There obviously has to be a balance between what I'm willing to code for and realism and then assistance with understanding some mechanics and how their formulas, etc would work. Again, I'm not trying to recruit anyone here, just looking for someone knowledgeable to have a friendly chat with for a little while.
    37. Hi, I'm looking into how to manage state transitions of read only resources. Lets say I have the following scenario with buffer A: Draw Call #1 - Reads from buffer A in PS. Draw Call #2 - Reads from buffer A in VS. So the state will be: Initial - Common Draw Call #1 - Implicit transition to NON_PIXEL_SHADER_RESOURCE Draw Call #2 - Transition from NON_PIXEL_SHADER_RESOURCE to PIXEL_SHADER_RESOURCE. End of command list - Implicit decay to D3D12_RESOURCE_STATE_COMMON. Is this the optimal way to do it? Or should I do a single transition to NON_PIXEL_SHADER_RESOURCE | PIXEL_SHADER_RESOURCE at the beginning of every frame? Would it be more expensive to simply explicitly transition to GENERIC_READ at the beginning of every frame? This would make a lot easier to manage read only resources... Thanks!
    38. nsmadsen

      Radio recordings in public domain

      You have to be really careful when it comes to music because 50's/60's songs are "young" enough to still have copyright applied. Even songs that are older could still be under copyright if the estate chooses to extend out the copyright. Dialog could be something completely different. Having said that, sometimes older documentary style films can be copyright free. Sometimes. You really have to do your research. You could also just look up radio sound effects from royalty free libraries. Sites like https://www.soundrangers.com/ or https://www.sounddogs.com/ could help. Something like this *might* work too but you should still do your research first: https://archive.org/search.php?query=radio Hope that helps! Nate
    39. It's not hard to do by any means. You would just swap the target mesh which responds to your controls, and swap cameras. Then load in the skill bar, inventory, ect... for the relevant character. The Neverwinter games do this, among others. There shouldn't be any issue with performance from doing so.
    40. Hi all, I am designing a small RPG game where you have the possiblity of switching between characters as one of the core mechanics. The thing is, I would like to implement it so that there can be two characters on different rooms on different screens, and whenever you press the switch button, the other screen is displayed and you can manage the other character independently. So, you don't just change the shape of your character and acquire different abilities, you also are in a different area. Eventually, there would be the possiblity for the characters to encounter whenever they both reach the same room, so they should be independent objects. I don't have much experience, as you can tell, so I had to ask. Is implementing this feature viable? Will there be huge performance issues? I am thinking that I could restrict the feature so that the player cannot use it at their will, but only at some specific moments --if there was no alternative. I will be using the Unity engine, but I could try something else if I had to. The thing is, I want to make sure the concept is somehow valid before starting to work on it. Most of the games I have seen allow to switch characters in a 'change shape and abilities' style, so I don't have a good reference. Thank you,
    41. nicfaust

      What's is the best story game you've played?

      I love the God of War game and the plot in general. It is so interesting and exciting. I think there are a lot of fans of this game just because of its story. https://goo.gl/b7GTEb
    42. RoKabium Games

      SAMA

      Images & screenshots from "Something Ate My Alien" game by RoKabium Games.
    43. Although Wurstbrot (guter Name!) is correct that ECS is, in general, an excellent approach to game architecture, I would say in this particular case since it is for a fairly simple text based adventure, full ECS is overkill and I wouldn't bother with the 'S' part and instead treat the behaviours (components) as full objects with the logic as well as the data encapsulated.
    44. TheLiamEnterprise

      DORU an idea i'm brewing up just need opiniouns

      kinda new here how do i edit my post lol
    45. SnW_Charlie

      Is limbo game 3d or 2d

      That was a ' great presentation on the rendering of INSIDE' cheers
    46. Either create a list that contains obj1 collided with obj2 and use it or store another pointer list for a troll that stores all other collided object so you can eaisly clear upon desturction ~trol() { fir (int i=0; i < listcount; i++) if (object!=0) object->colidedeith = 0; Something like that linked kist are helpful
    47. Geonamic

      DORU an idea i'm brewing up just need opiniouns

      If you are going to say the British are invading, that's not racist because that actually happened in history. Same thing if you were thinking about African Americans being enslaved by Caucasians during that time because that also happened. Many AAA games out there are perfectly acceptable with representing the gross reality of history because they were based on true events. Yes, keep the surprise a secret, and you should edit those mentions out, like I'll be editing my mention of it out after this post. You don't have to be super historically accurate. Some resemblance is enough to get people into the mindset that this is happening during so-and-so time period. EDIT: I was going to edit the mention of said surprise out of my first post in this thread, but it seems like I can't without hiding the whole thing... Welp.
    48. SnW_Charlie

      Props for my upcoming game

      Thjose look really good, what sort of poly count are they?
    49. nicolacarrera42

      I want to make a game.

      gl, bae!!
    50. Hi everyone, it's been a long time coming but we've finally released on Itch.io and Steam. We are in Early Access at the moment but we've just added update#3 and are well on shedule to release fully in March. We're a small team, there's just the two of us, myself and a programmer called Dazza. This really has been a labour of love, especially as this is pretty much the fourth year of development (Not full time though) and we're really happy to have got this far. What is it? I hear you ask, well, Smith and Winston is a voxel-based twin stick shooter with a focus on exploration. With fully destructable hand crafted levels and fun puzzles. Along with engaging combat with a variaty of enemies and bosses and an assortment of items and achievments to collect. We think its a lot of fun and from feed back with players, they agree. Smith and Winston can be found here on Itch.io You take on the role of Smith or Winston (or both as we have local co-op planned), two hapless adventurers, as you explore a shattered ring world and uncover its secrets, fight invading aliens and prevent the impending doom of the star system. Only you can save the world from the evil that's approaching and perhaps ultimately the galaxy itself... or not. Smith and Winston can be found here on Itch.io Also head over to our tigsource devblog if you would like to see how the game has developed over the years. Also if you have any questions please ask away
    51. dietrich

      shadow mapping using directional light

      You can definitely cull parts of your scene for directional shadow mapping, and as TomKQT mentions, the problem is to find the correct view frustum (which in this case will just be a box due to the orthographic projection) to cull against. One option is indeed to render the entire scene, in which case the view volume will be a light-space oriented bounding box of the scene. While not very optimal, I've found this to be a good starting point to check if everything is working as expected. Another is to actually compute a tight bounding box around objects required for shadow rendering. Basically, the view volume should enclose only the part of the scene, that is currently visible (i.e. whatever is inside the main camera's view frustum), plus whatever objects can cast a shadow into it. With this approach you compute a light-space bounding box around main camera's view frustum, but shift its near plane all the way back to the scene bound, repeating the process every frame to account for the main view changes. A few more pointers: cascaded shadow mapping mentioned above uses that approach, but you don't actually need to implement the cascades - or you can view it as single-cascade CSM. Anyway, it should be easy enough to extend to cascades form that point, if the need arises. the volume produced by this technique is conservative - there may be optimizations to further reduce the rendered object count, that I don't know of. the fact, that the light view volume is now shifting whenever the main view moves or rotates, and that there's no 1:1 correlation between the screen pixels and shadowmap texels, causes artifacts with shadow stability. You overcome those by making sure that your shadow map is translation and rotation invariant. It's a fairly big topic, again covered by many CSM descriptions. same artifacts are produced whenever the shadow casting light moves (think dynamic day-night cycle). I believe this one is more complicated (if possible) to solve. I saw several games move the sun/moon in short bursts, to limit the time when the effect is visible, but don't recall any other ways to improve this, apart from increasing shadow resolution.
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!