Recent Questions - Computer Graphics Stack Exchange most recent 30 from computergraphics.stackexchange.com 2021-09-26T01:27:04Z https://computergraphics.stackexchange.com/feeds https://creativecommons.org/licenses/by-sa/4.0/rdf https://computergraphics.stackexchange.com/q/12221 0 Is there a mathematical (as opposed to iterative/SDF) test for ray intersection with a grid of circles? Sniggerfardimungus https://computergraphics.stackexchange.com/users/9779 2021-09-25T08:23:19Z 2021-09-25T08:23:19Z <p>My actual problem is considerably more complex, but can be solved if there is a cheap way to compute the intersection of a ray with a regular grid of circles. If I had a circle centered at every integer (x,y) pair, and a ray in xy space, what's the fastest way to determine where the ray first intersects the surface of a circtle? My ray origin will not be inside one of the circles.</p> <p>The grid will be at least 256x256, so a signed distance function would be far too expensive, as I'd have to allow too many iterations to get the answer I need. I'm hoping that there's a mathematical solution to my problem so I can get this over in a dozen or two floating point operations. If a solution exists, I would assume that it will test against an infinite grid. I can happily cull intersections outside of the finite space in which I am working.</p> <p>Thanks...</p> https://computergraphics.stackexchange.com/q/12220 0 Transfer parameterisation between one mesh to another [closed] Argha Chakraborty https://computergraphics.stackexchange.com/users/10370 2021-09-22T09:54:04Z 2021-09-22T09:54:04Z <p>I have two similar looking meshes which are not geometrically identical but topologically equivalent. I carefully parameterised one in blender and want to reuse my parameterisation on another(or more similar looking meshes).</p> <p>Is there any open source software/tool which does this kind of cross-parameterisation?</p> https://computergraphics.stackexchange.com/q/12217 3 Graphics APIs: read/write the same texture Emil Kabirov https://computergraphics.stackexchange.com/users/10193 2021-09-21T20:27:09Z 2021-09-21T20:27:09Z <p>I know we can't bind the same texture as an input resource to a shader and as a render target within a single draw call, Direct3D just forces unbinding of such a texture SRV, OpenGL says it's undefined behaviour, and I am not sure about Vulkan.</p> <p>We can bypass that via Unordered Access Views in Direct3D or Images in OpenGL though.</p> <p>But the question is: what is the reason of these limitations <strong>in case we know that every fragment shader thread reads and writes the same texel just once from hardware perspective?</strong></p> <p>I can imagine that this won't work due to reads and writes caching if we deal with another case not mentioned above, with some random read/write positions and counts, but what about this specific case I asked about? Shouldn't we safely read values from read cache and write values into write cache and just flush write cache in the end overwriting previous content and do not worry about asynchronous glitches?</p> https://computergraphics.stackexchange.com/q/12215 1 OpenGL transparency - object behind is not rendered Paweł Pomierski https://computergraphics.stackexchange.com/users/17240 2021-09-21T19:03:19Z 2021-09-22T09:21:57Z <p>I'm trying to implement voxel world using OpenGL (Core 3.3). I've come across a problem with transparency. It looks like sometimes GPU decides to not render stuff that would be important. Can you help me diagnose the problem, please? (I thought this problem can be related to sorting (I don't perform any extra sorting at the moment), but I've changed &quot;clear color&quot; to glClearColor(1.0f, 1.0f, 1.0f, 0.01f); and the &quot;gaps&quot; are still noticeable)</p> <p><strong>EDIT:</strong> I've found a resource that claims that it is indeed sorting problem and drawing background triangles at first should solve this issue. However every 'chunk' (16x16 blocks' column) is rendered as a separate batch with single draw call. Is there a way to preserve this batch rendering?</p> <p>Here are some pictures:</p> <p><a href="https://i.stack.imgur.com/QaKhT.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/QaKhT.png" alt="enter image description here" /></a> <a href="https://i.stack.imgur.com/ahFb2.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/ahFb2.png" alt="enter image description here" /></a></p> <p><a href="https://i.stack.imgur.com/JUwqg.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/JUwqg.png" alt="enter image description here" /></a> <a href="https://i.stack.imgur.com/8nOV0.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/8nOV0.png" alt="enter image description here" /></a></p> <p>The Ftagment Shader is very simple:</p> <pre><code>#version 330 core out vec4 FragColor; in vec2 v_TexCoord; uniform sampler2D u_Texture; void main() { vec4 texColor = texture(u_Texture, v_TexCoord); if(texColor.a &lt; 0.2) discard; FragColor = texColor; } </code></pre> <p>Depth test and blending:</p> <pre><code>void Renderer::clear() const { glClearColor(0.53f, 0.8f, 0.92f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } //Before render loop glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_DEPTH_TEST); </code></pre> <p>Do you have any idea how can I fix this problem?</p> https://computergraphics.stackexchange.com/q/12213 2 ACES tonemapping confusion Emil Kabirov https://computergraphics.stackexchange.com/users/10193 2021-09-20T18:11:31Z 2021-09-20T20:50:38Z <p>In different sources I see ACES tonemapping, but I see one of two possible sets of formulas:</p> <ol> <li><a href="https://www.shadertoy.com/view/XsGfWV" rel="nofollow noreferrer">https://www.shadertoy.com/view/XsGfWV</a> this one</li> <li><a href="https://www.shadertoy.com/view/tdffDl" rel="nofollow noreferrer">https://www.shadertoy.com/view/tdffDl</a> or this</li> </ol> <p>I compared them and the first one looks better, it can transform very bright monochromatic light to white.</p> <p>But the question is: why do they both are called ACES and what is the &quot;true&quot; ACES? It seems like number 2 is used alot though number 1 looks better.</p> https://computergraphics.stackexchange.com/q/12212 1 SSR - ray origin and ray direction DirectX_Programmer https://computergraphics.stackexchange.com/users/10129 2021-09-18T17:03:42Z 2021-09-21T19:33:35Z <p><strike>I'm implementing SSR, specifically HZCT (Hi-Z Cone Tracing, based on article in <strong>GPU Pro 5</strong> name &quot;Hi-Z Screen-Space Cone-Traced Reflections&quot;).</p> <p>What I'm trying to do right now is to determine point in screen space and direction in screen space in which I'll be doing Hi-Z trace to find reflected color. <strong>I'm not interested in tracing ray for now. Only determining starting position/direction.</strong></strike></p> <p><strong>Edit:</strong> New approach here. More details and screenshots</p> <p>I've used this approach to start working with SSR - <a href="https://sakibsaikia.github.io/graphics/2016/12/26/Screen-Space-Reflection-in-Killing-Floor-2.html#overview" rel="nofollow noreferrer">https://sakibsaikia.github.io/graphics/2016/12/26/Screen-Space-Reflection-in-Killing-Floor-2.html#overview</a> - up until now, I've used <strong>main()</strong> and <strong>GetReflection()</strong> funtions but my code doesn't seem to be working.</p> <p>What might be a cause that it doesn't work? It seems that part of plane with texture is indeed reflected, but it seems like a sheer luck that vector is directed in that way. My guess is that screen-space vector is incorrect, but I have no idea, what might be a reason behind this?</p> <pre><code>float3 positionWSFromDepthCS(float depthCS, uint2 positionCS) { float4 positionWS = mul(float4(positionCS, depthCS, 1.0f), g_matricesCB.invViewProjMatrix); return positionWS.xyz / positionWS.w; } #define MAX_REFLECTION_RAY_MARCH_STEP 0.02f #define NUM_RAY_MARCH_SAMPLES 16 bool GetReflection( float3 ScreenSpaceReflectionVec, float3 ScreenSpacePos, out float3 ReflectionColor) { // Raymarch in the direction of the ScreenSpaceReflectionVec until you get an intersection with your z buffer for (int RayStepIdx = 0; RayStepIdx &lt; NUM_RAY_MARCH_SAMPLES; RayStepIdx++) { float3 RaySample = (RayStepIdx * MAX_REFLECTION_RAY_MARCH_STEP) * ScreenSpaceReflectionVec + ScreenSpacePos; float ZBufferVal = depthVStoCS(hiZBuffer.Sample(pointSampler, RaySample.xy).r); if (RaySample.z &gt; ZBufferVal) { ReflectionColor = colorBuffer.SampleLevel(pointSampler, RaySample.xy, 0).rgb; return true; } } return false; } float4 SSR(PixelInputType input) : SV_TARGET { float3 normal = normalBuffer.Sample(pointSampler, input.uv).rgb; if (dot(normal, float3(1.0f, 1.0f, 1.0f)) == 0.0f) { return float4(0.0f, 0.0f, 0.0f, 0.0f); } float2 PixelUV = input.uv; float2 NDCPos = float2(2.0f, -2.0f) * PixelUV + float2(-1.0f, 1.0f); // Prerequisites float DeviceZ = depthVStoCS(hiZBuffer.Sample(pointSampler, input.uv).r); float3 WorldPosition = positionWSFromDepthCS(DeviceZ, input.uv); float3 CameraVector = normalize(WorldPosition - g_constantBuffer.cameraPosition.xyz); float4 WorldNormal = float4(normal, 1.0f) * float4(2, 2, 2, 1) - float4(1, 1, 1, 0); // ScreenSpacePos --&gt; (screencoord.xy, device_z) float4 ScreenSpacePos = float4(PixelUV, DeviceZ, 1.f); // Compute world space reflection vector float3 ReflectionVector = reflect(CameraVector, WorldNormal.xyz); // Compute second sreen space point so that we can get the SS reflection vector float4 PointAlongReflectionVec = float4(10.f * ReflectionVector + WorldPosition, 1.f); float4 ScreenSpaceReflectionPoint = mul(g_matricesCB.viewMatrix, PointAlongReflectionVec); ScreenSpaceReflectionPoint /= ScreenSpaceReflectionPoint.w; ScreenSpaceReflectionPoint.xy = ScreenSpaceReflectionPoint.xy * float2(0.5, -0.5) + float2(0.5, 0.5); // Compute the sreen space reflection vector as the difference of the two screen space points float3 ScreenSpaceReflectionVec = normalize(ScreenSpaceReflectionPoint.xyz - ScreenSpacePos.xyz); float3 OutReflectionColor; GetReflection(ScreenSpaceReflectionVec, ScreenSpacePos.xyz, OutReflectionColor); return float4(OutReflectionColor.xyz, 1.0f); } </code></pre> <p>Here is result - SSR color: <a href="https://i.stack.imgur.com/W7Jih.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/W7Jih.png" alt="enter image description here" /></a></p> <p>ScreenSpaceReflectionVec values: <a href="https://i.stack.imgur.com/oi22F.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/oi22F.png" alt="enter image description here" /></a></p> <p>Input - normal buffer: <a href="https://i.stack.imgur.com/O7dE2.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/O7dE2.png" alt="enter image description here" /></a></p> <p>Input - color buffer: <a href="https://i.stack.imgur.com/yQlJ2.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/yQlJ2.png" alt="enter image description here" /></a></p> <p>Input - Hi-Z buffer: <a href="https://i.stack.imgur.com/bUFrj.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/bUFrj.png" alt="enter image description here" /></a></p> <hr /> <p><strong>Edit:</strong> Approach from old post is deleted. They are very similar (practically speaking - the same), but currently linked solution provides actual shader implementation, no only theory.</p> https://computergraphics.stackexchange.com/q/12208 2 Deriving formula for perspective correct texture interpolation Sam https://computergraphics.stackexchange.com/users/17223 2021-09-17T11:52:36Z 2021-09-17T15:26:24Z <p>I am trying to derive the formula for perspective correct texture interpolation on my own while implementing my own software rasterizer (projecting an arbitrarily rotated triangle in camera space on the projection plane and rasterize its texture). Sure, the solution is that one can interpolate the inverse of z in the projection plane (or screen space). However, given the assumption that I do not know that yet, all I came up with so far is the following:</p> <p><a href="https://i.stack.imgur.com/FsW63.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/FsW63.png" alt="enter image description here" /></a></p> <p>My first step was to formulate the problem (maybe my problem statement is the problem?) and visualize it. Then I tried to find some relations between the variables.</p> <p>What I am now looking for is some hint / observation that leads to right direction (not the solution).</p> https://computergraphics.stackexchange.com/q/12203 0 Reorder mesh triangles Matheus Markies https://computergraphics.stackexchange.com/users/15955 2021-09-16T16:26:36Z 2021-09-17T17:08:20Z <p>Good Morning!</p> <p>My problem is: I need to get the vertices of a mesh and send them to a shader.</p> <p>Inside the shader I will reassemble the mesh from its vertices.</p> <p>So far so good, I send the information and the shader tries to mount. But I'm not hitting the algorithm that assembles the new triangles. As seen in these images:</p> <p>Mesh:</p> <p><a href="https://i.stack.imgur.com/QqNEb.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/QqNEb.png" alt="Mesh" /></a></p> <p>Triangles (Made by shader):</p> <p>Each line of equal color; represents a triangle. Some colors end up repeating themselves, but I think you can understand.</p> <p><a href="https://i.stack.imgur.com/WJnVV.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/WJnVV.png" alt="Triangles" /></a></p> <p><a href="https://www.youtube.com/watch?v=aicstuF6Kcc" rel="nofollow noreferrer">https://www.youtube.com/watch?v=aicstuF6Kcc</a></p> <p><a href="https://www.youtube.com/watch?v=gW-Hqu2QEts" rel="nofollow noreferrer">https://www.youtube.com/watch?v=gW-Hqu2QEts</a></p> <p>Basically I build a list already in the order of the triangles and then put together 3 by 3.</p> <pre><code>public void buildObjectList() { int indicesCount = 0; int verticesCount = 0; int[] triangles; Vector3[] vertices; triangles = pto.objectMesh.triangles;//Take a sequence of vertices that form a triangle. vertices = pto.objectMesh.vertices;//Take vertex list pto._pathTracingObject.indicesOffset = indicesCount;//Offset: Where the list of indices belonging to the object starts. | indicesCount: How many indices were added before these. pto._pathTracingObject.indicesCount = triangles.Length;//How many indexes does this object have. foreach (Vector3 vertice in vertices) this.vertices.Add(vertice); for (int i = 0; i &lt; triangles.Length; i++) { this.indices.Add(triangles[i] + verticesCount + 1);//Variable containing all indices of all objects in the scene. | triangles[i] (take an index) +verticesCount(Add to the amount of vetices already added) + 1 /*Example: If the previous object has 270 vertices. The first triangle of the next objects will be connected to the vertices(271, 272, 273) instead of(0,1,2). +1 because vertex 270 belongs to a different object.*/ } indicesCount += triangles.Length;//update index verticesCount += vertices.Length;//update index } </code></pre> <p>In other words, if vertices 1,2 and 3 form a triangle in the list, they will appear in this sequence.</p> <p>So, when I need to form a triangle, I'll get the indices i, i+1 and i+2 from the list.</p> <p>As done here:</p> <pre><code> Vector3 v0 = vertices[indices[pto._pathTracingObject.indicesOffset + i]]; Vector3 v1 = vertices[indices[pto._pathTracingObject.indicesOffset + i + 1]]; Vector3 v2 = vertices[indices[pto._pathTracingObject.indicesOffset + i + 2]]; </code></pre> <p>&quot;pto._pathTracingObject.indicesOffset&quot; It's good for when I have more than one object in the scene, then I skip the vertices of other objects using this offset.</p> <p>For example if I have 2 objects in the scene and the first has 10 vertices, the vertices of the second will be counted after those 10.</p> <p>Like this: 11.12,13...</p> <p>But this algorithm is wrong, as it is connecting vertices that shouldn't be together. &quot;buildObjectList()&quot;</p> <p>For example, unity says my cube has 12 triangles. However, the algorithm returned 716 triangles.</p> <p><a href="https://i.stack.imgur.com/ryyDi.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/ryyDi.png" alt="enter image description here" /></a></p> <p><a href="https://i.stack.imgur.com/3iUbw.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/3iUbw.png" alt="enter image description here" /></a></p> https://computergraphics.stackexchange.com/q/12202 0 Purpose and workflow of wireframe models rustyBucketBay https://computergraphics.stackexchange.com/users/13348 2021-09-16T15:24:06Z 2021-09-17T11:59:26Z <p>I am more less familiarized with the major computer graphics concepts up to certain dregree of &quot;low-levelness&quot;. So I know how models, vertices, polygons etc. and how these works. Also how is the info in these (meaning the models) serialized and interpreted by a software, generally a game or graphics engine, to use this models info, vertices and indices, to get the model itself and handle it accordingly.</p> <p>Thats why I was surprised when I found some <a href="https://en.wikipedia.org/wiki/Wire-frame_model" rel="nofollow noreferrer">wireframe models</a>, because I am not familiar neither with the concept nor the purpose of these.</p> <p>1.- Are these handled (seralized and de-serialized) same as regular vertices models? Back in the beginning of computer graphics guess this was about all a computer could easily do, but is there any other purpose?</p> <p>2.- If there is a wireframe resource provided such as <a href="https://www.spriters-resource.com/pc_computer/starcraft/sheet/59990/" rel="nofollow noreferrer">this</a>, how it would me used/handled. In the case of a 2D isometric view game, I do not know what would I need to do with resources provided in this format. What would be roughly the approach? There are no vertices in this case, the wireframe is provided as a sprite resource, so what is it that needs to be done roughly to make use of it?</p> <p>I am not after an specific algorithm to handle this, this is not a code question. I mean what would be the general concept/workflow for this type of resource.</p> https://computergraphics.stackexchange.com/q/12197 1 Why does a game at 1080p look better on a 1080p display than 1440p display of the same size kmdhrm https://computergraphics.stackexchange.com/users/17208 2021-09-15T09:32:19Z 2021-09-15T10:38:44Z <p>So this is something i recently noticed. I have a 27inch 1440p monitor. And a game in 1080p looks pixelated on that. My friend has a 27 inch 1080p monitor and the same game on 1080p with all same graphics settings doesn't look pixelated on his monitor.</p> <p>What's up with that? Anything happening with upscaling on my monitor thats causing this?</p> https://computergraphics.stackexchange.com/q/12196 0 glsl passing data array from vertex to tessellation control shader Thomas https://computergraphics.stackexchange.com/users/13273 2021-09-15T08:38:03Z 2021-09-15T14:58:27Z <p>I am trying to pass a vec3 array from vertex shader to tessellation shader.</p> <p>passing just one value works fine, but how to pass an array?</p> <p><strong>Vertex shader</strong></p> <pre><code>#version 430 out vec3 data; //working! out vec3 dataArray; void main() { gl_position = vec4(0,0,0,0); data = vec3(1,2,3); dataArray = vec3(1,2,3); dataArray = vec3(4,5,6); } </code></pre> <p><strong>tessellation controll shader</strong></p> <pre><code>#version 430 layout (vertices = 3) out; in vec3 data[]; //working! in vec3 dataArray[]; // how to do this? void main() { ... } </code></pre> <p>The error message is: error C7618: OpenGL/ES does not allow input array declarations with size not equal to gl_MaxPatchVertices</p> <p>I also tried</p> <pre><code>in vec3 dataArray[gl_MaxPatchVertices] </code></pre> <p>But this also doesn't work.</p> https://computergraphics.stackexchange.com/q/12195 0 What's The Math Behind This Cloth Animation? fweth https://computergraphics.stackexchange.com/users/13975 2021-09-14T08:08:37Z 2021-09-14T11:09:53Z <p>I progammed a simple cloth animation. Initially I tried to implement Hooke's law, but it wasn't numerically stable, presumably because I used explicit Euler. Anyway, I came up with <a href="https://codepen.io/fweth/full/wvedBPz" rel="nofollow noreferrer">something</a> (WebGL2 based, won't work in Safari unfortunately) I quite like but don't understand the math at all.</p> <p>Every point has a position <span class="math-container">$p$</span> and velocity <span class="math-container">$v$</span>. The position is given relative to the initial position, where the initial position of point <span class="math-container">$(i,j)$</span> can be thought as <span class="math-container">$(i,j,0,0)$</span> (I rendered the cloth in 4 dimensions to make it more interesting, but that should not make a huge difference). There is a linear gravity term <span class="math-container">$g_v$</span> on the velocity which pulls the point back to its original position and also a friction term <span class="math-container">$f_v$</span> which slows down the velocity, so we have <span class="math-container">$v_{t+1}=f_vv_t+g_vp_t+d$</span> where <span class="math-container">$d$</span> is some external disturbance which is triggered by mouse clicks. But the position doesn't follow just <span class="math-container">$p_{t+1}=p_t+v_{t+1}$</span>, as I added some term to implement clothiness, so the points tend to the center of the four surrounding points. What I came up with is <span class="math-container">$$p_{t+1}=g_pp_t+v_{t+1}+\frac{c}{|c|^{2/3}+1}$$</span> where the center <span class="math-container">$c$</span> is computed as the sum of the positions of the four neighbouring points, <span class="math-container">$g_p&lt;1$</span> is some kind of another gravity term and the <span class="math-container">$2/3$</span> basically just make the last term approximates <span class="math-container">$c$</span> for small <span class="math-container">$|c|$</span> but grows slower for larger values of <span class="math-container">$|c|$</span>.</p> <p>I played around with this and tried to get rid of some terms but couldn't really find a satisfying way to do so. On the other hand, I just can't wrap my head around what I have actually done here. The velocity is not the true velocity anymore, as it doesn't reflect the change in position. Yet the new position feeds back in the velocity via the <span class="math-container">$g_v$</span> term. It's also weird that if you click the cloth once, it more or less just changes position, but on every further click it behaves much more like a cloth.</p> <p>Can someone tell me if this math does make any sense or if there is some underlying principle for this dynamics which I accidentally approximated?</p> https://computergraphics.stackexchange.com/q/12193 0 optional geometry shader Thomas https://computergraphics.stackexchange.com/users/13273 2021-09-13T10:07:56Z 2021-09-13T12:22:45Z <p>I am looking for an easy solution for passing information between shader stages when adding additional shader stages. Right now I am using the &quot;out&quot; keyword to pass data from for example vertex to fragment shader. On the fragment shader of cause I am using &quot;in&quot; to receive the data.</p> <p><strong>The problem I have is the following:</strong> The variable name MUST be the same. So &quot;out vec3 test;&quot; can only be received by variable &quot;in vec3 test;&quot;. When optionally plug in a geometry shader to duplicate triangles, I would like to receive the outputting data from the vertex shader &quot;in vec3 test&quot; and pass it to the fragment shader &quot;out vec3 test&quot;. And here the program crashes... because both variables names are &quot;test&quot;</p> <p><strong>Here the Vertex shader code:</strong></p> <pre><code>#version 430 layout(location = 0) in vec3 vertexPosition; out vec3 test; void main() { gl_Position = vec4(vertexPosition, 1.0f); test = vec3(1.0f, 2.0f, 3.0f); //this is just a test! } </code></pre> <p><strong>The Fragment shader code:</strong></p> <pre><code>#version 430 in vec3 test; out vec4 color; void main() { color = vec4(test, 1.0f); } </code></pre> <p>So the last shader (geometry shader) should be able to plug in if wanted, without changing the vertex or fragment shader.</p> <p><strong>The Geometry shader code:</strong></p> <pre><code>#version 430 core layout (triangles) in; layout (triangle_strip, max_vertices = 30) out; in vec3 test[]; out vec3 test; // this does not work (name already exists) void main() { vec4 position0 = gl_Position; vec4 position1 = gl_Position; vec4 position2 = gl_Position; for(uint i = 0; i &lt; 10; ++i) { gl_Position = position0 + vec4(i,0,0,0); test = test; //this of cause does not work... (I just want to pass this information) EmitVertex(); gl_Position = position1 + vec4(i,0,0,0); test = test; //this of cause does not work... EmitVertex(); gl_Position = position2 + vec4(i,0,0,0); test = test; //this of cause does not work... EmitVertex(); EndPrimitive(); } } </code></pre> <p>This geometry shader should copy the input triangle 10 times and pass the &quot;varying&quot; data from vertex to fragment shader.<br /> So the goal is that the vertex and fragment shader do not need to be changed when adding or leaving out the geometry shader.</p> <p>We would like to do stuff like that for example to enable/disable layered rendering, adding a tessellation shader when wanted. Right now we need to write several shaders for the same thing. For example when having the option of enable/disable layered rendering and enable/disable tessellation there are 2^2 = 4 possibilities. This means we need to write the same shader 4 times. With this approach we only need to write it once and just plug in the shader stages when needed.</p> <p>I am also interested in dynamically read out type and values of passed data. So ask within the geometry shader which variables are passed and then forward them to the next stage. With this approach we would be able to write one geometry shader which can be plugged between several other shaders.</p> <p>What possibilities do we have to generate such a system?</p> https://computergraphics.stackexchange.com/q/12192 0 How to add a second calculation to an already working transform feedback webgl2 code? hhaamm https://computergraphics.stackexchange.com/users/17192 2021-09-12T22:04:41Z 2021-09-12T22:04:41Z <p>I'm doing a project that involves transform feedback and WebGL2. I was able to make a transform feedback work using two buffers, to calculate an update in 3d positions of particles.</p> <p>But now I'd like to add age to the particles. Currently I have something like:</p> <pre><code> function makeTransformFeedback(gl, buffer, idx) { const tf = gl.createTransformFeedback(); gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf); gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, idx, buffer); return tf; } const tf1 = makeTransformFeedback(gl, this.position1Buffer, 0); const tf2 = makeTransformFeedback(gl, this.position2Buffer, 0); </code></pre> <p>And in the drawing part:</p> <pre><code> gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, this.current.tf); gl.beginTransformFeedback(gl.POINTS); gl.drawArrays(gl.POINTS, 0, this.numParticles); gl.endTransformFeedback(); gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null); </code></pre> <p>Which works. But I'm not sure how to add a second parameter. Should I create new &quot;transform feedback&quot; objects? (e.g. calling to makeTransformFeedback again). Also, should I use the same buffers for all the variables involved in the transform feedback or should I use different buffers?</p> <p>Sorry if the question is vague. Basically I'd like to know what would be the simplest approach to add a second variable to an existing code that uses transform feedback to update positions to particles, but that was created to only do that.</p> <p>One difference between particle age and particle position is that the last one is related with the drawing program while the first one would only be related with the &quot;update vertex data&quot; program (the code contains two programs, one for updating data and one for drawing).</p> https://computergraphics.stackexchange.com/q/12187 4 Rendering Hypercentric Perspective Monster196883 https://computergraphics.stackexchange.com/users/17184 2021-09-11T16:58:05Z 2021-09-12T02:23:34Z <p>I came across some Non-Euclidean Games which involve Hyperbolic Spaces, Spherical Spaces, Portals, etc. And, I noticed that they give quite deep feel of what Non-Euclidean Spaces feel like. So, I was thinking whether space rendering was possible for other unconventional perspectives, for example, <strong>Hypercentric Perspective</strong> (Objects that are farther away from the lens produce larger images than objects that are closer to the lens, contrary to the human eye where farther-away objects always appear smaller.) Due to physical restrictions, only a handful of images for Hypercentric Perspective exists on the internet, but these should give some idea:</p> <p><a href="https://i.stack.imgur.com/dxiGG.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/dxiGG.jpg" alt="enter image description here" /></a></p> <p><a href="https://i.stack.imgur.com/TJkxV.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/TJkxV.jpg" alt="enter image description here" /></a></p> <p>Now, my question is how to render Hypercentric Perspective in preferably 3 Dimensional Space?</p> <p>I tried doing this in Unity by varying the physical parameters of the virtual physical camera, but it was no success. What can be the other way of approaching the problem? Preferably, the optimal approach? I'm very new to Computer Graphics so please pardon me if I missed something obvious here.</p> <p>Please help me here.</p> <p>Thank you.</p> https://computergraphics.stackexchange.com/q/12186 1 Stripping unnecessary data from C++ data structures before sending to GPU JHall https://computergraphics.stackexchange.com/users/8704 2021-09-11T15:34:22Z 2021-09-11T23:12:44Z <p>I've recently been working on a particle system in my renderer and I've encountered a situation where my particle class on the C++ side has data I need to maintain my particle on that end, but that I don't need in my shader (velocity, acceleration, life span, start colour, end colour, gravity toggle, etc.).</p> <p>So presently I've created a second class that just contains my necessary rendering data and I have a function that will copy the needed data from my &quot;full&quot; particle to my &quot;rendering&quot; particle.</p> <pre><code>class HParticle { public: vec3 m_pos = vec3(0, 0, 0); float m_life = 0; // Remaining life of the particle. if &lt; 0 : dead and unused. vec4 m_color = vec4(1, 1, 1, 1); // Color float m_texture = -1; float m_scale = 1; vec3 m_orientation; float m_featureValue = 0; float m_featureSelected = 0; float m_emission = 0; float m_scaleRate = 0; vec4 m_startColor = vec4(1, 1, 1, 1); vec4 m_endColor = vec4(1, 1, 1, 1); vec3 m_velocity = vec3(0, 0, 0); vec3 m_acceleration = vec3(0, 0, 0); float m_featureValueRateOfChange = 0; float m_totalLife = 0; float m_colorLife = 0; } struct HStrippedParticle { mat4 m_transform; vec4 m_color = vec4(1, 1, 1, 1); // Color float m_texture = -1; float m_featureValue = 0; float m_featureSelected = 0; float m_emission = 0; }; </code></pre> <p>I know I'm speaking specifically to particles here but I've encountered this situation a couple of times before and I'm wondering if there's a better general approach than maintaining two lists. One for C++ and one for my shader. And having to update the shader one every time I go to render (I know I could be cleverer and avoid updating data that hasn't changed but still). Maybe something fancy with C++ memory to copy desired chunks from the full class to the stripped class?</p> <p>Thanks in advance</p> https://computergraphics.stackexchange.com/q/12184 0 Efficient algorithm for mesh scale adjustment based on the scale of another mesh Michael IV https://computergraphics.stackexchange.com/users/213 2021-09-10T16:23:10Z 2021-09-10T17:32:04Z <p>I have a mesh (Mesh-A) with a bounding box of some arbitrary size defined by X,Y,Z scale. In runtime I import another mesh (Mesh-B),which has an overall topology similar to the Mesh-A, but it can have a different default scale. I am looking for an efficient algorithm to rescale the Mesh-B to have the new scale equal to the Mesh-A,which basically means - their bounding boxes are of similar sizes. The naive approach would be to run for... loop, scaling the Mesh-B transform,till its BB has an approximate size equal to that of the Mesh-B's BB. I would like to learn other approaches.</p> https://computergraphics.stackexchange.com/q/12182 1 Mesh-Shader and layered rendering Thomas https://computergraphics.stackexchange.com/users/13273 2021-09-10T10:27:55Z 2021-09-10T16:16:14Z <p>In the usual pipeline (vertex, tessellation, geometry and fragment shaders) the geometry can be deformed and in the geometry shader it is possible to copy the generated and deformed geometry in order to transfer it from several positions into several layers of a texture to render. Also known as &quot;layered rendering&quot;. Does the new mesh shading pipeline (task shader, mesh shader and fragment shader) also have the option of generating / deforming the mesh and then copying it into different layers? So that you can render the same scenario multiple times within one drawcall?</p> <p>I am asking for Vulkan, OpenGL and DirectX 12</p> https://computergraphics.stackexchange.com/q/12179 0 Which geometry file format is the most similar to our geometry file format? Kutadgubilig https://computergraphics.stackexchange.com/users/17173 2021-09-08T19:48:10Z 2021-09-09T16:46:40Z <p>To represent a 3D geometry in our software we use this format below: Material-1 Material-2 P1(X1,Y1,Z1) P2(X2,Y2,Z2) P3(X3,Y3,Z3)</p> <p>This 11 point gives us a triangle with the description of what is behind and front of the triangle. Depicted below:</p> <p><a href="https://i.stack.imgur.com/z1N10.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/z1N10.png" alt="enter image description here" /></a></p> <p>By applying the right-hand rule (P1 to P2 and then P3, like for electromagnetic force), we know what is Material-1 and Material-2 these are the properties on both sides of the triangular plane.</p> <p>Using these triangles we can construct the complete surface of our geometries. Since it is hard to create complex 3D surfaces and volumes (enclosed space by these triangles) manually, we want to use CAD software like Blender, SolidWorks, etc. What is the easiest data format (e.g. .STP, .STL, ...) that we can use to convert and represent the 3D geometries with our 5 parameters (actually 11 parameters) geometry format.</p> <p>Thanks!</p> https://computergraphics.stackexchange.com/q/12158 0 OpenGL state management Thomas https://computergraphics.stackexchange.com/users/13273 2021-08-28T14:10:28Z 2021-09-16T08:21:00Z <p>I am working on a software with lots of different shaders, which require different states in OpenGL. My problem is the following: The different models with different shaders are not rendered in the same order, so there is a switch form shader1 to shader23 to shader2 and so on. In the next frame this order can change (depending on the scenario). When I am adding a new kind of object (with new shader and so on) and I think it is working, I need to check every order of object-rendering to see, if bugs appear. With bugs I mean OpenGL states which are set to a specific value and later not changed back. How do you handle this?</p> <p>I have the idea, to create a OpenGL state class where you can define each parameter. When running an render method, the current state will be compared with the OpenGL state and each setting which is different should be set to the state will is required for this rendering.</p> <p>This seems to me more than a few lines of code... The most hardest part is to figure out which states are saved in which OpenGL table (with table I mean VAO, FBO, Texture, ...). Where can I find a table very good described where each OpenGL state will be saved?</p> <p>I mean: when binding Shader1 and setting uniform &quot;test&quot; to value &quot;123&quot; and then binding Shader2, the uniform there also named &quot;test&quot; will not have the value &quot;123&quot;... so the uniform values are somehow stored on shader level?? Same with attributepointer and VAO...</p> <p>On the other hand: PointSize is not stored on shader level... so each time I am rendering Points, I need to check which size they have and change it to the required size.</p> <p>Can someone give me some URL to a table of OpenGL states?</p> <p>Does someone has a better idea to handle this problem? BTW: I am not the only one who is working on this software... so saying &quot;every time when changing a state, change it back at the end of the method&quot; will not work.</p> https://computergraphics.stackexchange.com/q/12151 3 Cubic Splines - Do Parametric and Explicit representation give different curves? gallickgunner https://computergraphics.stackexchange.com/users/6046 2021-08-24T05:30:38Z 2021-09-22T04:33:14Z <p>I asked a similar question here before but since the previous post original question was different, I think it was confusing people. So I've voted to close that and asking the new question here. I'm doing a volume rendering project and made a cubic spline editor for transfer function. I used <a href="http://graphicsrunner.blogspot.com/2008/05/camera-animation-part-ii.html" rel="nofollow noreferrer">this</a> as a source which basically uses Wolfram as the main source. Now Wolfram defines a parametric representation. After I made it, I tried to compare it online but the curves are different. The only difference I found is that the online version is using a non-parametric representation.</p> <p>Here's mine. <a href="https://i.stack.imgur.com/Yo4am.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Yo4am.png" alt="enter image description here" /></a></p> <p>And here's the online version <a href="https://i.stack.imgur.com/fEXlf.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/fEXlf.png" alt="enter image description here" /></a></p> <p>In order to clarify a bit more on what I'm trying to do. I have 2 variables.</p> <p><span class="math-container">$X = [0, 255]$</span></p> <p><span class="math-container">$Y = [0, 1]$</span></p> <p>For every given <span class="math-container">$X$</span> value I need the interpolated <span class="math-container">$Y$</span> value. At first glance it seems that the explicit form of cubic spline is what I want. But I have another case where <span class="math-container">$Y$</span> values are RGB triplets <span class="math-container">$(r,g,b)$</span>. Since the parametric representation doesn't have to deal with dimensions and since the code was already online I'm using the parametric form. The parametric form uses the parameter <span class="math-container">$t \in [0,1]$</span> for every segment.</p> <p>Now things get a little trickier. Technichally my graph is of <span class="math-container">$(t, Y(t))$</span> but as you can see in the first picture the X-axis isn't <span class="math-container">$t$</span> but the previously defined <span class="math-container">$X$</span> which is in range <span class="math-container">$[0-255]$</span>. I'm simply rescaling between <span class="math-container">$X$</span> and <span class="math-container">$t$</span>. So if I get <span class="math-container">$t = 0.5$</span> for the first segment as an example, I'd take the two bounding control points which resolve to <span class="math-container">$(0,0)$</span> and <span class="math-container">$(141, 0.759)$</span> in the first picture. Then do simple rescaling like</p> <p><span class="math-container">$0 + (141 - 0) * t$</span></p> <p>to get my iso-value and plot the graph. Here's how I'm actually drawing the graph</p> <pre><code>float t_step = 1/255.0f; for(int i = 0; i &lt; knots.size() - 1; i++) { for (int i_step = 1; i_step &lt;= num_line_segments; i_step++) { glm::vec2 coord; coord.x = knots[i].iso_value + (t_step * i_step * (knots[i+1].iso_value - knots[i].iso_value)); coord.y = glm::clamp(alpha_spline.getPointOnSpline(t_step * i_step, i).w, v_min.y, v_max.y); win-&gt;DrawList-&gt;_Path.push_back(getAbsMousePositionFromPoint(coord) ); } } getAbsMousePositionFromPoint(glm::vec2 v) { glm::vec2 v_min(0,0), v_max(255, 1.0) glm::vec2 t = (v - v_min) / (v_max - v_min); return glm::mix(graph_bot_left, graph_top_right, t); // both &quot;graph_bot_left&quot; and &quot;graph_top_right&quot; are absolute coordinates of the drawing region } </code></pre> <p>Basically I need absolute coordinates for drawing anything on the screen. Each segment of the spline is basically drawn as a polyline. Just to be on the safe side I have currently set the number of line segments per curve of the spline to be <code>255</code>. This means per segment of the spline I need to draw 255 line segments. I step along <code>t</code> then transform it to the proper X-value by doing the transformation step as I told above then find absolute coordinates from that X-value and draw the segment there.</p> <p><em><strong>Now all I wanna know is, do parametric and explicit forms give different curves? If not, then is there something wrong with the rescaling step I'm doing above or something else?</strong></em></p> <p>P.S :- I've checked the formulation and the boundary conditions of the <a href="https://timodenk.com/blog/cubic-spline-interpolation/" rel="nofollow noreferrer">online</a> one and all are similar to the Wolfram one. Both mine and the online one are natural cubic splines. I've also double checked my code, even derived the whole parametric form on paper and checked the code with the one derived on paper and it matches perfectly so I'm pretty sure the code isn't wrong. Still <a href="https://github.com/gallickgunner/Volume-Renderer/blob/master/src/CubicSpline.cpp" rel="nofollow noreferrer">here's</a> my spline source as a reference if anybody here knows programming</p> <p>UPDATE:- So I just found another guy using the same logic as well <a href="https://github.com/jose-villegas/VolumeRendering/blob/3de0008cbd6c1771dc25d0e382b47240220ee7cc/VolumeRendering/TransferFunction.cpp#L96" rel="nofollow noreferrer">here</a>. I guess the math is all right then. Don't see where's the problem then.</p> https://computergraphics.stackexchange.com/q/10824 2 Environment map importance sampling (beginner) Kc Able https://computergraphics.stackexchange.com/users/16193 2021-04-15T09:55:49Z 2021-09-12T11:07:30Z <p>beginner here.</p> <p>I am implementing importance sampling for environment maps in Scotty3D, a CMU CS project (but I am not a student).</p> <p>The task can be found <a href="https://cmu-graphics.github.io/Scotty3D/pathtracer/environment_lighting" rel="nofollow noreferrer">here</a></p> <p>I have a problem with the sample's pdf, it is unusually small and that results in the object being rendered white even if its albedo is not white.</p> <p>Here is how I construct the CDF:</p> <pre><code>// Calculate Lsintheta across the image. Accumulate to normalize the pdf to 1 later. for (size_t j = 0; j &lt; h; j++) { for (size_t i = 0; i &lt; w; i++) { // 0.5f at the pixel center. Else we never sample top and bottom rows float Lsintheta = image.at(i, j).luma() * sin(PI_F*(j + 0.5f)/h); total += Lsintheta; cdf.push_back(total); // Joint Cdf. P(theta, phi) } } </code></pre> <p>So <code>total</code> would have all the pixels' luminosities. <code>cdf</code> would actually be the cumulative luminosity.</p> <p>Next is the sampling and calculating the actual pdf.</p> <pre><code>float Xi = RNG::unit(); // [0, 1] auto lower = std::lower_bound(cdf.begin(), cdf.end(), Xi*total); // cdf is not normalized yet. Scale the RV auto index = std::distance(cdf.begin(), lower); out_pdf = *lower; if (index &gt; 0) out_pdf -= cdf[index - 1]; // pdf[index] = cdf[index] - cdf[index - 1] out_pdf /= total; </code></pre> <p><code>Xi</code> is a uniformly sampled real number from 0 to 1. Then it is multiplied by the <code>total</code> luminosity in the image to get the sampled accumulated luminosity. Use <code>std::lower_bound</code> to get the nearest accumulated luminosity greater than or equal to it. Find the index of this nearest accumulated luminosity using <code>std::distance</code>. Then minus with the previous accumulated luminosity to get the actual luminosity in this pixel. Divide by <code>total</code> to get the <code>pdf</code>.</p> <p>This doesn't work, but if I just do <code>out_pdf = lower/total</code> it can at least show the right color. What am I doing/understanding wrong?</p> https://computergraphics.stackexchange.com/q/10154 1 Optimizing compute shader with thread group shared memory François Guthmann https://computergraphics.stackexchange.com/users/11388 2020-08-28T14:17:42Z 2021-09-19T19:01:40Z <p>I'm currently learning compute shaders and I'm trying to write an optimized <a href="https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life" rel="nofollow noreferrer">Game Of Life</a>. I have a first version working that uses a Shader Storage Buffer Object. I dispatch a thread per cell I want to update and that thread samples the SSBO 8 times to gather the cell's neighbors. This works fine.</p> <p>I'm now trying to optimize this by using shared memory. Every thread in a work group will now load a single cell in shared memory wait for the memory and execution barrier to resolve and then sample the shared memory 8 times to compute its cell's state. Of course some threads need to load more than 1 cell to shared memory because if they're on the 'border' of a workgroup no thread will load the data for some of its neighbors. ( See picture )</p> <p><a href="https://i.stack.imgur.com/3SQIn.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/3SQIn.png" alt="enter image description here" /></a></p> <p>I got this working as well. However, it is less performant than the brute force version. ( On an RTX 2070 and GTX 660M ) I'm very surprised. I'm using Vulkan and gpu queries to estimate how long the compute pass takes. Here is for example the numbers for a 4096x4096 grid. I dispatch 256x256 thread groups of size 16x16. On my old GTX 660M compute takes ~12ms in brute force mode but it takes ~17ms with TGSM. I can't test on the RTX right now but the TGSM version was less performant as well.</p> <p>I was definitely expecting to see some improvement with TGSM. I need to look into it more with tools like Nvidia Nsight but I would assume this shader is limited by memory and definitely not ALU. I guess my questions are:</p> <ul> <li>Am I correct in assuming the TGSM version should run faster somehow? Search for Neighborhood Processing <a href="https://gpuopen.com/learn/optimizing-gpu-occupancy-resource-usage-large-thread-groups/" rel="nofollow noreferrer">here</a></li> <li>If my assumption is correct, what went wrong?</li> </ul> <p>Here is the brute force shader:</p> <pre><code>#version 450 layout (constant_id = 0) const uint CELLS_COUNT = 4096; layout (constant_id = 1) const uint GRID_SIZE = 64; layout (constant_id = 2) const uint THREADS_PER_GROUP_X = 8; layout (constant_id = 3) const uint THREADS_PER_GROUP_Y = 8; layout (constant_id = 4) const uint THREADS_PER_GROUP = 64; layout(local_size_x_id = 2, local_size_y_id = 3) in; layout(std430, set = 0, binding = 0) buffer SrcGrid { uint state[CELLS_COUNT]; } srcGrid; layout(std430, set = 0, binding = 1) buffer DstGrid { uint state[CELLS_COUNT]; } dstGrid; const ivec2 sampleXYOffsets[] = { ivec2(-1, -1), ivec2(0, -1), ivec2(1, -1), ivec2(-1, 0), ivec2(1, 0), ivec2(-1, 1), ivec2(0, 1), ivec2(1, 1), }; void main() { const uint maxIdX = gl_WorkGroupSize.x * gl_NumWorkGroups.x; const uint maxIdY = gl_WorkGroupSize.y * gl_NumWorkGroups.y; uint aliveNeighbors = 0; // Convert dispatch IDs into storage buffer id const uint currentCellIndex = gl_GlobalInvocationID.y * maxIdX + gl_GlobalInvocationID.x; // Convert storage buffer id into grid coordinates (x, y) const uvec2 currentCoords = uvec2( currentCellIndex % GRID_SIZE, currentCellIndex / GRID_SIZE); for( uint i = 0; i &lt; 8; i++ ){ uvec2 coords = currentCoords; // Bring everything above 0 to be able to use the modulo operator coords = (coords + sampleXYOffsets[i] + GRID_SIZE) % GRID_SIZE; // Convert grid coordinates (x, y) into storage buffer id uint neighborIndex = coords.x + coords.y * GRID_SIZE; aliveNeighbors += srcGrid.state[neighborIndex]; } uint currentCellState = srcGrid.state[currentCellIndex]; if( currentCellState &lt; 1.0 &amp;&amp; aliveNeighbors == 3 ) { // Dead cell comes back to life dstGrid.state[currentCellIndex] = 1; return; } // Alive cell dies if( aliveNeighbors &lt; 2.0 || aliveNeighbors &gt; 3.0) { dstGrid.state[currentCellIndex] = 0; return; } dstGrid.state[currentCellIndex] = currentCellState; } </code></pre> <p>And the one using TGSM:</p> <pre><code>#version 450 layout (constant_id = 0) const uint CELLS_COUNT = 4096; layout (constant_id = 1) const uint GRID_SIZE = 64; layout (constant_id = 2) const uint THREADS_PER_GROUP_X = 8; layout (constant_id = 3) const uint THREADS_PER_GROUP_Y = 8; layout (constant_id = 4) const uint THREADS_PER_GROUP = 64; layout(local_size_x_id = 2, local_size_y_id = 3) in; layout(std430, set = 0, binding = 0) buffer SrcGrid { uint state[CELLS_COUNT]; } srcGrid; layout(std430, set = 0, binding = 1) buffer DstGrid { uint state[CELLS_COUNT]; } dstGrid; uint getSSBODataFromWorldGridCoords( uint worldGridX, uint worldGridY ) { uvec2 worldGridCoords = uvec2( worldGridX, worldGridY ); worldGridCoords = (worldGridCoords + GRID_SIZE) % GRID_SIZE; return srcGrid.state[ worldGridCoords.x + worldGridCoords.y * GRID_SIZE ]; } shared uint sharedData[ THREADS_PER_GROUP_X + 2 ][ THREADS_PER_GROUP_Y + 2 ]; void main() { const uvec2 workGroupSize = uvec2( THREADS_PER_GROUP_X, THREADS_PER_GROUP_Y ); // Grid coords within a thead group const uvec2 localGridCoords = gl_LocalInvocationID.xy; // Coordinates of each thread group tile const uvec2 worldGridOffset = gl_WorkGroupID.xy * workGroupSize.xy; // Grid coords within the whole game const uvec2 worldGridCoords = worldGridOffset + localGridCoords; // Early out if not in the grid if( worldGridCoords.x &gt;= GRID_SIZE || worldGridCoords.y &gt;= GRID_SIZE ) { return; } // Load data into TGSM const uvec2 tgsmCoords = localGridCoords + uvec2( 1, 1 ); // Top left corner if( localGridCoords.x == 0 &amp;&amp; localGridCoords.y == 0 ) { // Top sharedData[ tgsmCoords.x ][ tgsmCoords.y - 1 ] = getSSBODataFromWorldGridCoords( worldGridCoords.x, worldGridCoords.y - 1 ); // Top Left sharedData[ tgsmCoords.x - 1 ][ tgsmCoords.y - 1 ] = getSSBODataFromWorldGridCoords( worldGridCoords.x - 1, worldGridCoords.y - 1 ); // Left sharedData[ tgsmCoords.x - 1 ][ tgsmCoords.y ] = getSSBODataFromWorldGridCoords( worldGridCoords.x - 1, worldGridCoords.y ); } // Top right corner else if( localGridCoords.x == workGroupSize.x - 1 &amp;&amp; localGridCoords.y == 0 ) { // Top sharedData[ tgsmCoords.x ][ tgsmCoords.y - 1 ] = getSSBODataFromWorldGridCoords( worldGridCoords.x, worldGridCoords.y - 1 ); // Top Right sharedData[ tgsmCoords.x + 1 ][ tgsmCoords.y - 1 ] = getSSBODataFromWorldGridCoords( worldGridCoords.x + 1, worldGridCoords.y - 1 ); // Right sharedData[ tgsmCoords.x + 1 ][ tgsmCoords.y ] = getSSBODataFromWorldGridCoords( worldGridCoords.x + 1, worldGridCoords.y ); } // Bottom left corner else if( localGridCoords.x == 0 &amp;&amp; localGridCoords.y == workGroupSize.y - 1 ) { // Bottom sharedData[ tgsmCoords.x ][ tgsmCoords.y + 1 ] = getSSBODataFromWorldGridCoords( worldGridCoords.x, worldGridCoords.y + 1 ); // Bottom Left sharedData[ tgsmCoords.x - 1 ][ tgsmCoords.y + 1 ] = getSSBODataFromWorldGridCoords( worldGridCoords.x - 1, worldGridCoords.y + 1 ); // Left sharedData[ tgsmCoords.x - 1 ][ tgsmCoords.y ] = getSSBODataFromWorldGridCoords( worldGridCoords.x - 1, worldGridCoords.y ); } // Bottom right corner else if( localGridCoords.x == workGroupSize.x - 1 &amp;&amp; localGridCoords.y == workGroupSize.y - 1 ) { // Bottom sharedData[ tgsmCoords.x ][ tgsmCoords.y + 1 ] = getSSBODataFromWorldGridCoords( worldGridCoords.x, worldGridCoords.y + 1 ); // Bottom Right sharedData[ tgsmCoords.x + 1 ][ tgsmCoords.y + 1 ] = getSSBODataFromWorldGridCoords( worldGridCoords.x + 1, worldGridCoords.y + 1 ); // Right sharedData[ tgsmCoords.x + 1 ][ tgsmCoords.y ] = getSSBODataFromWorldGridCoords( worldGridCoords.x + 1, worldGridCoords.y ); } // Left Edge else if( localGridCoords.x == 0 ) { sharedData[ tgsmCoords.x - 1 ][ tgsmCoords.y ] = getSSBODataFromWorldGridCoords( worldGridCoords.x - 1, worldGridCoords.y ); } // Right Edge else if( localGridCoords.x == workGroupSize.x - 1 ) { sharedData[ tgsmCoords.x + 1 ][ tgsmCoords.y ] = getSSBODataFromWorldGridCoords( worldGridCoords.x + 1, worldGridCoords.y ); } // Top Edge else if( localGridCoords.y == 0 ) { sharedData[ tgsmCoords.x ][ tgsmCoords.y - 1 ] = getSSBODataFromWorldGridCoords( worldGridCoords.x, worldGridCoords.y - 1 ); } // Bottom Edge else if( localGridCoords.y == workGroupSize.y - 1 ) { sharedData[ tgsmCoords.x ][ tgsmCoords.y + 1 ] = getSSBODataFromWorldGridCoords( worldGridCoords.x, worldGridCoords.y + 1 ); } // SSBO index for this thread const uint ssboIndex = worldGridCoords.x + worldGridCoords.y * GRID_SIZE; uint currentCellState = getSSBODataFromWorldGridCoords( worldGridCoords.x, worldGridCoords.y ); // Load current cell into TGSM. sharedData[ tgsmCoords.x ][ tgsmCoords.y ] = currentCellState; // Barrier memoryBarrierShared(); barrier(); // Count alive neighbors from TGSM uint aliveNeighbors = 0; const uvec2 sharedMemoryGridCoordinates = uvec2( localGridCoords.x + 1, localGridCoords.y + 1 ); aliveNeighbors += sharedData[ sharedMemoryGridCoordinates.x - 1 ][ sharedMemoryGridCoordinates.y - 1 ]; aliveNeighbors += sharedData[ sharedMemoryGridCoordinates.x ][ sharedMemoryGridCoordinates.y - 1 ]; aliveNeighbors += sharedData[ sharedMemoryGridCoordinates.x + 1 ][ sharedMemoryGridCoordinates.y - 1 ]; aliveNeighbors += sharedData[ sharedMemoryGridCoordinates.x - 1 ][ sharedMemoryGridCoordinates.y ]; aliveNeighbors += sharedData[ sharedMemoryGridCoordinates.x + 1 ][ sharedMemoryGridCoordinates.y ]; aliveNeighbors += sharedData[ sharedMemoryGridCoordinates.x - 1 ][ sharedMemoryGridCoordinates.y + 1 ]; aliveNeighbors += sharedData[ sharedMemoryGridCoordinates.x ][ sharedMemoryGridCoordinates.y + 1 ]; aliveNeighbors += sharedData[ sharedMemoryGridCoordinates.x + 1 ][ sharedMemoryGridCoordinates.y + 1 ]; if( currentCellState &lt; 1.0 &amp;&amp; aliveNeighbors == 3 ) { // Dead cell comes back to life dstGrid.state[ssboIndex] = 1; return; } // Alive cell dies if( aliveNeighbors &lt; 2.0 || aliveNeighbors &gt; 3.0) { dstGrid.state[ssboIndex] = 0; return; } dstGrid.state[ssboIndex] = currentCellState; } </code></pre> <p>Any pointers towards articles or tools that could help me figure this out would be greatly appreciated :).</p> https://computergraphics.stackexchange.com/q/9614 1 constant pixel width for any scale Anvaka https://computergraphics.stackexchange.com/users/7512 2020-02-26T19:50:06Z 2021-09-24T22:06:05Z <p>I have a standard 3d camera/projection/model setup that renders rectangles with a WebGL shader. </p> <p>Users can zoom out and fly anywhere. </p> <p>I want to make sure that regardless of the scale, width of the rendered rectangles is a constant value (e.g. 2 pixels). </p> <p>What is the most efficient way to do so?</p> <p>This is very similar to SVG's non-scaling-stroke vector effect: <a href="https://www.w3.org/TR/SVGTiny12/painting.html#NonScalingStroke" rel="nofollow noreferrer">https://www.w3.org/TR/SVGTiny12/painting.html#NonScalingStroke</a></p> https://computergraphics.stackexchange.com/q/9364 5 Visualize the interpolated unit quaternion on the surface of the unit sphere Ali https://computergraphics.stackexchange.com/users/11492 2019-11-20T02:16:08Z 2021-09-15T23:03:05Z <p>My major is mechanical, please forgive me for asking questions that may seem trivial to you. </p> <p>First, I'm reading the following paper:</p> <blockquote> <p>Dam, Erik B., Martin Koch, and Martin Lillholm. <a href="https://archive.org/details/Erik_B_Dam_Martin_Koch_and_Martin_Lillholm___Quaternions_Interpolation_and_Animation" rel="nofollow noreferrer">Quaternions, interpolation and animation</a>. Vol. 2. Copenhagen: Datalogisk Institut, Københavns Universitet, 1998.</p> </blockquote> <p>On page 35, it says:</p> <blockquote> <p>Since quaternion space is four-dimensional, we cannot visualise the interpolated curves directly. We will always interpolate between unit quaternions, and the interpolated quaternions will always (with a few exceptions in chapter 6 on page 38 and 69) be unit quaternions. This means that we only need three dimensions to visualize the interpolation curves, <strong>because they lie on the surface of the unit sphere.</strong> </p> </blockquote> <p>I don't quite get the last sentence: why only three dimensions are needed to visualize the unit quaternion or why unit quaternion lies on the surface of the unit sphere? I thought they lie on the unit hyper-sphere. Does the author assume that we are viewing the quaternions from the south pole of the hyper-sphere?</p> <p>Second, I was also following this paper:</p> <blockquote> <p>Ramamoorthi, R., &amp; Barr, A. H. (1997). Fast construction of accurate quaternion splines.</p> </blockquote> <p>I found they are also treating (plotting) a unit quaternion as a point on a unit sphere <span class="math-container">$\mathbb{S}^{2}$</span>. I wonder if you could recommend some resources in why we can view a unit quaternion <span class="math-container">$q = (a+b\mathbf{i}+c\mathbf{j}+d\mathbf{k})$</span> as a point on a unit sphere <span class="math-container">$\mathbb{S}^{2}$</span>? </p> <p>Any help is appreciated. Thank you. </p> https://computergraphics.stackexchange.com/q/9116 2 Estimating the position of vertexes in a 3D model Mike Zadeh https://computergraphics.stackexchange.com/users/11138 2019-09-05T06:39:32Z 2021-09-25T10:02:25Z <p><strong>Introduction to my project:</strong></p> <p>We are machine learning scientists and working on a biomedical system for tracking tongue for speech pathology using a technology called EMA (Electromagnetic articulography). In EMA a coil is attached to tongue surface using a glue and its 3D pos and orientation (roll and pitch) are read by EMA measurement system. So, you can track the coil and thus a point on the surface of tongue while speech is made. Also let's assume we have a low density 3D model of tongue for the patient is obtained by 3D MRI and we know exactly that which vertex in 3D model corresponds to the point that coil is attached.</p> <p>It would be very valuable for our research if we can visualize the tongue for the patient. But the issue is that we just track 1 or 2 points on the tongue but our 3D model has more than 100 vertices which are not tracked. Now, we think it might be possible to estimate the position of those point given these two points.</p> <p><strong>Here are some of the facts that we think it should be possible:</strong></p> <ol> <li>Although tongue is not a solid object, it has a degree of rigidity thus the position of these 100 vertexes are correlated by physics For example how much they can be stretched or bent (Something like spring and mass model in physics). </li> <li>by looking at a training set of 3D models for tongue during production of different sounds, we might say that the position of vertexes are not pure random and there is a distribution for them which might be estimated using the training dataset (sequence of MRI 3D models). </li> <li>we might assume that in our presentation the tongue can have just a bent toward the palate to simplify the modeling problem. or a 2D profile of tongue (like the line at the center) is enough for modeling. or any simplification that we can make. </li> </ol> <p><strong>Now my question:</strong> </p> <p>What do you know in computer graphics literature which resembles to our problem (any model, method, tool, software, library,....)? What is your suggestion for us to do this task in more efficient way?</p> <p>Thanks,</p> <p>Mike</p> https://computergraphics.stackexchange.com/q/8431 1 Export Model Textures Per Face KatoFett https://computergraphics.stackexchange.com/users/9922 2018-12-28T05:26:55Z 2021-09-15T03:05:50Z <p>(Note that as far as attempts go, I can't find anything that helps me)</p> <p>I have a 3D polygon, and for simplicity's sake it's going to be the one below:</p> <p><a href="https://i.stack.imgur.com/KQ8Ct.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/KQ8Ct.png" alt="Basic Textured Polygon"></a></p> <p>It is textured using the UV map below:</p> <p><a href="https://i.stack.imgur.com/UaFcs.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/UaFcs.jpg" alt="Basic Texture UV"></a></p> <p><em>Side Note: I just found the texture on Google. It is not being used in any manner other than solely to demonstrate my question.</em></p> <p>I plan on 3D printing the polygon. Since I suck at painting, I want to print the textures for each face so I can glue/decal them onto the correct faces.</p> <p>My question is: How can I go from a UV texture map to individual polygon faces (and 1 texture per face) that is correctly scaled to fit the face. I want something like below:</p> <p><a href="https://i.stack.imgur.com/s8hCn.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/s8hCn.png" alt="Desired Outcome"></a></p> <p>Is there <strong>any</strong> way to do this? I don't care about width * height as I can manage that on my own, but I need the textures to be distorted just like how they are on the corresponding face of the polygon.</p> https://computergraphics.stackexchange.com/q/8291 0 Translate an arcball camera upwards or left-right Marcel Hansemann https://computergraphics.stackexchange.com/users/9727 2018-11-18T19:23:52Z 2021-09-16T03:08:10Z <p>This problem is giving me a really hard time.</p> <p>I'm always looking at the origin and have a camera that moves around it in an arcball mode. </p> <p>That part works beautifully:</p> <p><a href="https://i.stack.imgur.com/4cEd5.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/4cEd5.png" alt="enter image description here"></a></p> <p>I'm calculating the camera position as follows:</p> <pre><code>camera.pos.x = origin.x + distance (arrow) * cos(angleX) camera.pos.z = origin.z + distance * sin(angleX) camera.pos.y : Float = origin.y + distance * sin(angleY) </code></pre> <p>But now I also want to be able to shift the position of the camera laterally, i.e. on (or parallel to) the tangent plane to the sphere between the origin and the camera position. (That tangent plane being the screen plane.)</p> <p>I.e. I want to shift the view matrix to the left/right and upwards/downwards, so that the camera is shifted laterally. (I need this for features such as moving the view on a touchscreen [two-finger gesture] or texture projection).</p> <p>How should I go about this?</p> https://computergraphics.stackexchange.com/q/8136 5 Ray tracing implicit surfaces using Sturm's theorem user9485 https://computergraphics.stackexchange.com/users/0 2018-10-10T15:49:56Z 2021-09-21T19:35:01Z <p>I am trying to render implicit surfaces given by a polynomial equation <span class="math-container">$F(x,y,z) = 0$</span> using <a href="https://en.wikipedia.org/wiki/Sturm%27s_theorem" rel="nofollow noreferrer">Sturm's theorem</a>.</p> <p>Plugging the parametric ray equation <span class="math-container">$r(t) = o + td$</span>, where <span class="math-container">$o\in\mathbb{R}^3$</span> is the ray origin and <span class="math-container">$d\in\mathbb{R}^3\backslash\{0\}$</span> is the ray direction, into <span class="math-container">$F$</span> yields a polynomial equation <span class="math-container">$p(t) = 0$</span> for the intersections of the ray with the surface. I noticed that the straightforward implementation of calculating a Sturm sequence as</p> <p><span class="math-container">$$p_0 = p, \\ p_1 = p', \\ p_{i} = -\text{rem}(p_{i-2},p_{i-1}) \quad\forall i\ge2$$</span></p> <p>is numerically unstable. When rendering a torus for example, the equation for one particular ray in my program was</p> <p><span class="math-container">$$p(t) := t^4 + 0.00329589844t^2 - 660.766052t + 9627.17676 = 0.$$</span></p> <p>In single precision, the associated Sturm sequence is computed as</p> <p><span class="math-container">$$p_0(t) = t^4 + 0.00329589844t^2 - 660.766052t + 9627.17676,\\ p_1(t) = 4t^3+0.00659179688t-660.766052,\\ p_2(t) = -0.001647949220t^2+495.5745390t-9627.17676,\\ p_3(t) = -3.617114498\cdot 10^{11}t+7.027166964\cdot 10^{12},\\ p_4(t) = 0,$$</span></p> <p>which indicates that (up to multiplicity) <span class="math-container">$p$</span> has exactly one real root. But in fact <span class="math-container">$p$</span> has no real roots, which can easily be verified with a computer algebra system. If the same computation is done with higher precision, it turns out that <span class="math-container">$p_4(t)\approx 0.000039&gt;0$</span>. In this case the correct number of roots is calculated.</p> <p>Is there anything that can be done to avoid this problem when calculating a Sturm sequence?</p> https://computergraphics.stackexchange.com/q/1793 13 How many polygons in a scene can modern hardware reach while maintaining realtime, and how to get there? [closed] Llamageddon https://computergraphics.stackexchange.com/users/2111 2015-12-09T17:40:28Z 2021-09-17T12:52:23Z <p>A fairly basic, in some ways, question, but one that many people, myself included, don't really know the answer to. GPU manufacturers often cite extremely high numbers, and the spread between polygon counts that various game engines claim to support often spans multiple orders of magnitude, and then still depends heavily on a lot of variables.</p> <p>I'm aware that this is a broad, pretty much open-ended question, and I apologize for that, I just thought that it would be a valuable question to have on here nonetheless.</p>