# Syerjchep

Member

105

213 Neutral

• Rank
Member

• Website
• Role
Programmer
• Interests
DevOps
Production
Programming

## Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

1. ## OpenGL Camera issues combining raymarching and polygonal graphics.

So I have a program that involves rendering a few models and some tessellated terrain, and allowing the user to navigate through it using wasd (R and F for vertical) keys and a mouselook camera. I also have it rendering two triangles at the front of the screen that I am attempting to use as the basis for some post-processing raymarching stuff. I also have a depth framebuffer texture that I render from the player's camera perspective to get a sense of how far each pixel's ray must be cast. For reference, here's the part of my fragment shader that deals with the raymarching: float LinearizeDepth(in vec2 uv) { float zNear = 0.1; // TODO: Replace by the zNear of your perspective projection float zFar = 250.0; // TODO: Replace by the zFar of your perspective projection float depth = texture2D(texture0, uv).x; float z_n = 2.0 * depth - 1.0; float z_e = 2.0 * zNear * zFar / (zFar + zNear - z_n * (zFar - zNear)); return z_e; } float mapSphere(vec3 eyePos) { return length(eyePos) - 1.0; } float doMap(vec3 eyePos) { float total = 999999; for(int x = 0; x<5; x++) { for(int y = 0; y<5; y++) { eyePos += vec3(x*10,y*10,0); total = min(total,mapSphere(eyePos)); eyePos -= vec3(x*10,y*10,0); } } return total; } Above: Some functions to help set things up. Below: The part of main that deals with the two triangles applied to the screen. if(skyDrawingSky == 1) { vec2 uv = (vert.xy + 1.0) * 0.5; //vert is the 2d coords from -1 to 1 of the two triangles rendered to the screen for the raymarching shader float depth = LinearizeDepth(uv); //get the depth of a particular pixel's view from a depth buffer rendered to texture0 vec4 r = normalize(vec4(-vert.x,-vert.y,1.0,0.0)); r = r * camAngleMain; //I thought adding a 3rd dimension and the normalizing would be equivalent to a perspective matrix //At which point I just multiply those 'perspective coordinates' by the inverse of my actual camera view matrix that I use for the polygonal graphics vec3 rayDirection = r.xyz; vec3 rayOrigin = -camPositionMain; float distance = 0; float total = 0; for(int i = 0; i < 64; i++) { vec3 pos = rayOrigin + rayDirection * distance; float value = doMap(pos); distance += value; if(distance >= depth) break; else total += clamp(1-value,0,1); } color = vec4(1,1,1,total); return; } edit: Changing the raymarching camera glsl code to: vec4 r = normalize(vec4(vert.x,vert.y,1.0,0.0)); r = r * camProjectionMain; r = r * camAngleMain; vec3 rayDirection = r.xyz; vec3 rayOrigin = camPositionMain; Doesn't really change anything, but it's easier to read. My main problem is that for some reason vertically panning the camera results in vertical distortion of objects as they approach the top and bottom of the view/screen. If you look at the attached image, the white orbs are part of the raymarching shader, everything else is tesselated/polygonal graphics. In the first two images, the orbs can be clearly seen to be above or below the sand colored heightmap. In the last image, the position of the orbs is a bit off such that they now clip through the terrain. I can't figure out why this is. My camera seems to *almost* work, but not quite. My aspect ratio at the moment is a perfect square, and I multiply my raymarching screen coordinates (2d from -1 to 1) by the inverse of my camera view matrix so I don't really know why this would happen. Is there anything I'm doing wrong with my implementation here?
2. ## Computing normals of tessellated heighmap on the fly.

So I have a heightmap for my terrain. The heighmap is a texture, and I have tessellation control and evaulation shaders in glsl (using OpenGL 4.0 atm) that tessellate them into smaller squares. I've tried to write code that looks at differences in neighboring pixels in the heightmap to determine the normals at a given point. The result of this is the attached image. It looks like it more or less works, but there's undesirable artifacts. I've drawn a black circle around one such artifact in the close up screenshot to the right. Here's my tessellation evaluation shader that computes vertex positions and normals: #version 400 core uniform sampler2D texture0; uniform sampler2D texture1; uniform mat4 cameraProjectionMatrix; uniform mat4 cameraMatrix; uniform vec3 cameraPosition; uniform vec3 cameraRight; uniform vec3 cameraUp; uniform vec3 cameraDirection; layout(quads, equal_spacing, ccw) in; in vec3 ES_Position[]; out vec2 UV; out vec3 FS_Position; out vec3 lightingNormal; vec3 getNormal(float cellSize,float totalPixels,vec2 uvCoords) { float heightL = texture(texture0,uvCoords - vec2(1.0/totalPixels,0)).r*10.0; float heightR = texture(texture0,uvCoords + vec2(1.0/totalPixels,0)).r*10.0; float heightD = texture(texture0,uvCoords - vec2(0,1.0/totalPixels)).r*10.0; float heightU = texture(texture0,uvCoords + vec2(0,1.0/totalPixels)).r*10.0; vec3 tangent = normalize(vec3(cellSize,heightL - heightR,0)); vec3 bitangent = normalize(vec3(0,heightD - heightU,cellSize)); return normalize(cross(tangent,bitangent)) * vec3(1,-1,1); } void main() { float totalMapSize = 400.0; float totalPixels = 2048.0; float cellSize = totalMapSize/totalPixels; vec3 highXPos = mix(ES_Position[3],ES_Position[2],gl_TessCoord.y); vec3 lowXPos = mix(ES_Position[0],ES_Position[1],gl_TessCoord.y); FS_Position = mix(lowXPos,highXPos,gl_TessCoord.x); vec2 uvCoords = FS_Position.xz/totalMapSize; float actualHeight = texture(texture0,uvCoords).r*10.0; FS_Position.y = actualHeight; gl_Position = cameraProjectionMatrix * cameraMatrix * vec4(FS_Position,1.0); UV = gl_TessCoord.xy * vec2(0.33,1); vec3 norm = getNormal(cellSize,totalPixels,uvCoords); //vec3 normL = getNormal(cellSize,totalPixels,uvCoords - vec2(1.0/totalPixels,0)); //vec3 normR = getNormal(cellSize,totalPixels,uvCoords + vec2(1.0/totalPixels,0)); //vec3 normD = getNormal(cellSize,totalPixels,uvCoords - vec2(0,1.0/totalPixels)); //vec3 normU = getNormal(cellSize,totalPixels,uvCoords + vec2(0,1.0/totalPixels)); //vec3 normX = mix(normL,normR,0.5); //vec3 normY = mix(normD,normU,0.5); //vec3 normAround = mix(normX,normY,0.5); //lightingNormal = mix(norm,normAround,0.5); lightingNormal = norm; } Trying to approximate what pixel it is on and finding the supposedly neighboring pixels using floating point math seems hacky, I feel like there's a better way to do this that will eliminate those artifacts and make it look a lot more smooth.
3. ## Quickly finding location in an array that is similar to a smaller array.

I actually considered doing 4 bit sequences. For now they're just unsigned chars though. That would save RAM, but would it save CPU? RAM isn't the issue at all. As for doing it on the GPU, that'd be great, though I imagine that's a bit above my head. I understand the basics of parallel computing though.
4. ## Quickly finding location in an array that is similar to a smaller array.

I've got like thousands of enzymes to compare to thousands of ligands each frame. I guess it just boils down to doing what ya'll said and finding ways to preemptively determine a failed match and weed out any unnecessary comparison.
5. ## Quickly finding location in an array that is similar to a smaller array.

So I've got some very large (a few thousand elements long) arrays of numbers. Each element in the array is a number from 1 to 6. I then have a lot of smaller arrays (maybe 20 or 30 elements long) which also consist of the numbers 1 to 6. For each of these smaller arrays I have to find the location on the larger array that is similar enough to pass my test if there is one. The similarity for any one of the smaller arrays is found as follows: 1. Tally up the differences between each pair of numbers: one from the smaller array, and one from the larger, going for the whole length of the smaller array. 2. Sum the total difference between all pairs together. 3. Raise it to a high power because I need the results to follow a curve. (e.g. 40/40 has a similarity of 1, but 39/40 is only 0.81 similar, and 35/40 is 0.21 similar) 4. Advance the offset of the larger array by one. Starting over a 1, but this time the first element of the smaller array is compared to the second element of the larger array, and so on. Unfortunately this means that for each smaller array I have to do an exponentiation operation for each element of the larger array. (e.g. to compare a smaller array to an array with 1000 characters, I have to call the 'pow' method over 1000 times) I also have find the difference between an amount of pairs of numbers equal to the number of elements in the smaller array multiplied by the number of elements in the larger array for each of the smaller arrays. (e.g. I have to find out if a 20 element smaller array matches elements 0-19 of the larger array, then elements 1-20 of the larger array, then elements 2-21 ... until the end of the larger array) Can anyone suggest some optimizations I can do here? Here's a snippet of code as an example: void activator::calculateFree() { if(attachSize < 1) return; //attach size is the size of the binding domain of the activator //e.g. the size of the 'smaller array' calculateLigand(); if(!boundLigand) { //parent->mainDNA->size is the size of the 'larger array' //a is the offset as we work our way through the larger array for(unsigned int a = 0; a<=parent->mainDNA->size-attachSize; a++) { float totalDifference = 0; float actualDifference = 0; bool inhibited = false; for(unsigned int b = 0; b<attachSize; b++) { totalDifference += 6; //parent->mainDNA->code is the larger array //attachBinding is the smaller array actualDifference += abs(parent->mainDNA->code[a+b]-attachBinding[b]); if(parent->mainDNA->inhibitedCode[a+b]) { inhibited = true; break; } } if(inhibited) continue; //here (totalDifference-actualDifference)/totalDifference is the raw similarity between the two arrays geneAffinity = (totalDifference-actualDifference)/totalDifference; //try and avoid doing a pow if we don't have to if(geneAffinity > 0.61324) { geneAffinity = pow(geneAffinity,8); //For example, if we have a smaller array length of 20 //And at a particular offset 19 of its elements are equal to the larger arrays elements //and the last element is only 1 different from the corresponding larger array element //that grants a similarity of 119/120 //(totalDifference-actualDifference)/totalDifference in this case would be 0.99166 //raised to the 8th power, that's 0.935 //here we do a check to see if the similarity is close enough to do something with float bindingAffinity = 1-geneAffinity; //geneAffinity > 0.02 if(bindingAffinity < 0.98) { unsigned int randMax = 1+(bindingAffinity*1000); if(rand() % randMax == 0) { boundDNA = parent->mainDNA; boundPosition = a; for(unsigned int b = 0; b<parent->unboundActivators.size(); b++) { if(parent->unboundActivators[b] == this) { parent->unboundActivators.erase(parent->unboundActivators.begin() + b); break; } } boundDNA->activators.push_back(this); break; } } } } } }
6. ## GUI library for OpenGL using SDL2?

Hey there, this may seem like a dumb question, but I feel it can't hurt to ask? There's a lot of graphics libraries out there build in c++ that use opengl and usually GLFW as well. But for my program I'm using a combination of OpenGL 3 with shaders along side SDL to handle events processing and context creation. So my question is, does this mean I'm out of luck for using any of myriad of premade GUI libraries out there?
7. ## Is there a way to get time marker data from Assimp's animations?

Hey there, I just realized you also responded to the last topic I made in september about glew.h not compiling. That's funny. Anyway, just like there I manged to find a work around. In this case I just have anyone who supplies a model specify the start and end frames for each animation manually. Only issue is I can't find a way to play multiple animations simultaneously.
8. ## Is there a way to get time marker data from Assimp's animations?

Pretty straight forward question. I'm using the asset importer library to help me import collada files exported from blender (using an improved exporter add-on). These models have animations. I've written code that's able to use assimp to load these files and animate them reasonably well. The only problem is I have time markers in my models that will say, mark frame 17/250 as "reload:start" and frame 29/250 as "reload:end" and in order to know which frames to play to "reload" I need to be able to access this data in my program. Yet none of the documentation on assimp seems to hint at where this data is loaded to if at all.
9. ## Can not include glew.h in multiple files within the same project.

I believe I solved this problem. I got the newest version of GLEW and included the glew.c file directly in my project rather than trying to link to it.
10. ## Can not include glew.h in multiple files within the same project.

Not a graphics question per se, but I'm having a hell of a time just getting glew to work. See, I had a project using glew.h as well as other files like SDL_Opengl and glm all contained within main.cpp which I compiled and ran just fine. But now I want to split my project up into more files. The problem is if I include glew.h in one of my header files as well as in my main.cpp I get "multiple definition" errors. If I only include it in one or the other, then I get "function undefined" errors. I have tried including GLEW_STATIC and it seems to have done nothing. I also tried putting all my OpenGL header includes in a separate header file with it's own header locks and #pragma once calls and it still didn't work.

New video:
12. ## I've made an evolution simulator using Box2d.

Not a wholly new concept, of course, but some of the ways I'm handling the back end aren't common. I first made a non-physics based evolution simulator back in October of 2016: It was pretty decent in some ways, but quite underwhelming. Two days ago I started a new evolution simulator using opengl graphics and the box2d physics library: Over the weekend I actually got it to work: Now that evolution works, I have to add another feature or two (fighting, gene combination), then I'll post videos of evolutionary progress. Once I add a spiffy interface I'll probably release it as well. For an additional resource, here's a google doc with a sloppy code specification: https://docs.google.com/document/d/1Uc6dLB3cb9oWFAWl6t2GGwI-ImPnVJV3KmlVcmFlFlE/edit?usp=sharing I'm going to tidy that up, and maybe even make a video on how the code itself works.
13. ## Pressure simulation for a game.

So I've recently gotten Box2d to work with C++ and am having fun with it, but I wanted to add heat and pressure to my game. Here's a decent example of the kind of pressure system I'm thinking of: http://dan-ball.jp/en/javagame/dust/ That said, is there any page that summarizes the math required for this? I've searched "air pressure simulation" and "wind simulation" and haven't really come up with much in the way of guides and tutorials.
14. ## Join US / For anyone who want to build the biggest open-world 3D game

You sure do like using emoticons in your reply. Anyway, if you or your teammates have previous work, post links to it here.
15. ## Started work on a behavioral evolution simulator.

Here's a little preview video I made for a different forum: I've only really been working on this a few days but basically the program simulations a map with many different cells on them. Each cell has its own script that tells it what to do each frame. The 'scripting language' is specific for this program and is stored as a string of bytes that are susceptible to mutation. Most of the preferences and such are still hard coded and I only started making an actual interface for the program yesterday. Once I can work on it a bit more I might release a really early version for people to try.