Following on from this post from yesterday. The situation is the same as in the original post: I'm implementing my own Graphics pipeline, odd issue with transforms. However, I now believe that the issue isn't with the perspective projection and is a larger issue than just that.
Right now the pipeline only has three stages, the first transforms individual vertices using the model and projection matrices. The next assembles these into the primitives, which are finally rendered by the rasteriser. This is the output from a test run:
This is the vertex data:
Vertex1: 0 , 0, -1, 1
Vertex2: 0.5, 1, -1, 1
Vertex3: 1 , 0, -1, 1
When no transforms take place (that is to say model matrix is identity matrix):
Model Matrix
1.000000 0.000000 0.000000 0.000000
0.000000 1.000000 0.000000 0.000000
0.000000 0.000000 1.000000 0.000000
0.000000 0.000000 0.000000 1.000000
New vert x: 0.000000 y: 0.000000 z: -1.000000 w: 1.000000
New vert x: 0.500000 y: 1.000000 z: -1.000000 w: 1.000000
New vert x: 1.000000 y: 0.000000 z: -1.000000 w: 1.000000
Projection Matrix
1.931371 0.000000 0.000000 0.000000
0.000000 2.414213 0.000000 0.000000
0.000000 0.000000 1.002002 -0.200200
0.000000 0.000000 -1.000000 0.000000
New vert x: 0.000000 y: 0.000000 z: -1.202202 w: 1.000000
New vert x: 0.965685 y: 2.414213 z: -1.202202 w: 1.000000
New vert x: 1.931371 y: 0.000000 z: -1.202202 w: 1.000000
Divide by W
New vert x: 0.000000 y: 0.000000 z: -1.202202 w: 1.000000
New vert x: 0.965685 y: 2.414213 z: -1.202202 w: 1.000000
New vert x: 1.931371 y: 0.000000 z: -1.202202 w: 1.000000
Screenspace Matrix
400.000000 0.000000 0.000000 400.000000
0.000000 320.000000 0.000000 320.000000
0.000000 0.000000 1.000000 0.000000
0.000000 0.000000 0.000000 1.000000
New vert x: 400.000000 y: 320.000000 z: -1.202202 w: 1.000000
New vert x: 786.274170 y: 1092.548340 z: -1.202202 w: 1.000000
New vert x: 1172.548340 y: 320.000000 z: -1.202202 w: 1.000000
The result of this looks like:
Which looks reasonable to me, the 0,0,0 vertex appears to be centered on the origin with the other points being out of the screen which at -1 away from the camera is what I would expect.
When I adjust the model matrix so that:
Model matrix
1.000000 0.000000 0.000000 -4.799998
0.000000 1.000000 0.000000 -3.999998
0.000000 0.000000 1.000000 -2.300000
0.000000 0.000000 0.000000 1.000000
New vert x: -4.799998 y: -3.999998 z: -3.300000 w: 1.000000
New vert x: -4.299998 y: -2.999998 z: -3.300000 w: 1.000000
New vert x: -3.799998 y: -3.999998 z: -3.300000 w: 1.000000
Projection Matrix
1.931371 0.000000 0.000000 0.000000
0.000000 2.414213 0.000000 0.000000
0.000000 0.000000 1.002002 -0.200200
0.000000 0.000000 -1.000000 0.000000
New vert x: -9.270576 y: -9.656849 z: -3.506807 w: 1.000000
New vert x: -8.304890 y: -7.242636 z: -3.506807 w: 1.000000
New vert x: -7.339205 y: -9.656849 z: -3.506807 w: 1.000000
Divide by W
New vert x: -2.809265 y: -2.926318 z: -1.062669 w: 3.300000
New vert x: -2.516633 y: -2.194738 z: -1.062669 w: 3.300000
New vert x: -2.224001 y: -2.926318 z: -1.062669 w: 3.300000
Screenspace Matrix
400.000000 0.000000 0.000000 400.000000
0.000000 320.000000 0.000000 320.000000
0.000000 0.000000 1.000000 0.000000
0.000000 0.000000 0.000000 1.000000
New vert x: 196.293823 y: 119.578247 z: -1.062669 w: 3.300000
New vert x: 313.346680 y: 353.683777 z: -1.062669 w: 3.300000
New vert x: 430.399414 y: 119.578247 z: -1.062669 w: 3.300000
The output from this data is:
This doesn't look right to me but I can't see where in the matrix stack my problem is. From the above can anyone else see any problem with the matrix stack?
As in the original post:
"So I came back to this project after quite some break and I realised that my projection divide (aka /w) was only dividing the xyz coords. So when I applied the screenspace matrix the translate column was being multiplied by the 'greater than one' W value causing the triangle to move to the upper right as Z decreases."
Related
I've created a simple unit-sized plane in blender and exported it into .obj file which contents is this
# Blender v2.93.3 OBJ File: ''
# www.blender.org
mtllib plane.mtl
o Plane
v 1.000000 -1.000000 0.000000
v -1.000000 -1.000000 0.000000
v 1.000000 1.000000 0.000000
v -1.000000 1.000000 0.000000
vt 0.000000 0.000000
vt 1.000000 0.000000
vt 1.000000 1.000000
vt 0.000000 1.000000
vn 0.0000 0.0000 -1.0000
usemtl None
s off
f 1/1/1 2/2/1 4/3/1 3/4/1
When I import it with assimp
unsigned flags = aiProcess_Triangulate | aiProcess_OptimizeMeshes |
aiProcess_JoinIdenticalVertices | aiProcess_SortByPType |
aiProcess_CalcTangentSpace /*|aiProcess_FlipWindingOrder*/;
const aiScene * scene = importer.ReadFile(path, flags);
for (int i = 0; i < scene->mNumMeshes; ++i)
{
const aiMesh * mesh = scene->mMeshes[i];
for (int j = 0; j < mesh->mNumVertices; ++j)
{
const aiVector3D & vertex = mesh->mVertices[j];
model->vertices.emplace_back(vertex.x, vertex.y, vertex.z);
// ...
it gives me weird results
x = {double} -0.007812501848093234
y = {double} -0.0078125
z = {double} 1.5873523201947252E-314
x = {double} 0.0078125055733835325
y = {double} 0.0078125
z = {double} 5.2635442471208903E-315
x = {double} 2.1053526862322168E-314
y = {double} -3.0421935264696467E-310
z = {double} 0
x = {double} 0
y = {double} 0
z = {double} 0
I expected values from 1 to -1 like they're in the .obj file
I also tried to pass 0 instead of flags, the results are the same
The issue was because i defined ASSIMP_DOUBLE_PRECISION and it was the cause
I'm trying to render a cube with a wood texture (all faces of the cube with the same texture), but the texture is not being rendered as it should (looks like the texture is trasparent at some parts):
But if look inside the cube, it seems to be rendering properly:
:
Here is the .obj file that I'm reading from (with the texture coords and vertices):
mtllib crate.mtl
o Cube_Cube.002
v -1.000000 -1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v 1.000000 -1.000000 -1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 1.000000 1.000000
v -1.000000 1.000000 -1.000000
v 1.000000 1.000000 -1.000000
v 1.000000 1.000000 1.000000
vt 1.000000 0.000000
vt 0.000000 1.000000
vt 0.000000 0.000000
vt 1.000000 0.000000
vt 0.000000 1.000000
vt 0.000000 0.000000
vt 1.000000 0.000000
vt 0.000000 1.000000
vt 0.000000 0.000000
vt 1.000000 0.000000
vt 0.000000 1.000000
vt 0.000000 0.000000
vt 1.000000 0.000000
vt 0.000000 0.000000
vt 0.000000 1.000000
vt 1.000000 1.000000
vt 1.000000 1.000000
vt 1.000000 1.000000
vt 1.000000 1.000000
vt 1.000000 1.000000
vn -1.0000 0.0000 0.0000
vn 0.0000 0.0000 -1.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 0.0000 1.0000
vn 0.0000 -1.0000 0.0000
vn 0.0000 1.0000 0.0000
usemtl Material
s off
f 6/1/1 1/2/1 5/3/1
f 7/4/2 2/5/2 6/6/2
f 8/7/3 3/8/3 7/9/3
f 5/10/4 4/11/4 8/12/4
f 2/13/5 4/11/5 1/14/5
f 7/4/6 5/15/6 8/12/6
f 6/1/1 2/16/1 1/2/1
f 7/4/2 3/17/2 2/5/2
f 8/7/3 4/18/3 3/8/3
f 5/10/4 1/19/4 4/11/4
f 2/13/5 3/17/5 4/11/5
f 7/4/6 6/20/6 5/15/6
Here is the way I'm loading the texture to OpenGL:
unsigned char* localBuffer = stbi_load(filepath.c_str(), &this->width, &this->height, &this->bitsPerPixel, 4);
glGenTextures(1, &this->id);
glActiveTexture(GL_TEXTURE0 + this->slot);
glBindTexture(GL_TEXTURE_2D, this->id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, this->width, this->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, localBuffer);
glBindTexture(GL_TEXTURE_2D, 0);
Here is the the vertex shader:
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 textureCoords;
out vec2 vTextureCoords;
uniform mat4 Mvp;
void main()
{
vTextureCoords = textureCoords;
gl_Position = Mvp * vec4(aPos, 1.0);
}
Here is the fragment shader:
out vec4 FragColor;
in vec2 vTextureCoords;
uniform sampler2D textureSlot;
void main()
{
FragColor = texture(textureSlot, vTextureCoords);
}
Can someone tell me what I'm doing wrong here?
Thanks to #Sync it I find out that the solution was to enable depth testing.
glEnable(GL_DEPTH_TEST);
I've had a very similar issue, however I'm using DirectX. The reason was that I didn't have the depth-stencil buffer set and I so the pixel depth values were being overridden by whatever order they were drawn in first. Check to make sure you have some equivalent of this enabled in OpenGl.
I have a problem with my sampler in Vulkan: it doesn't matter if I create the sampler with VK_FILTER_NEAREST or VK_FILTER_LINEAR for both magnification or minification filter, my texture will be sampled as if I created it with VK_FILTER_LINEAR;
This is the method where I create my sampler:
void Gui::Texture_2D::createVkSampler(const VkFilter & _magFilter,
const VkFilter & _minFilter,
const VkSamplerMipmapMode & _mipMapFilter,
const unsigned char & _maxAnisotropy) {
VkSamplerCreateInfo samplerInfo = {};
samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
samplerInfo.magFilter = _magFilter; // VK_FILTER_NEAREST
samplerInfo.minFilter = _minFilter; // VK_FILTER_NEAREST
samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
samplerInfo.anisotropyEnable = _maxAnisotropy == 0 ? VK_FALSE : VK_TRUE; // 0
samplerInfo.maxAnisotropy = _maxAnisotropy; // 0
samplerInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
samplerInfo.unnormalizedCoordinates = VK_FALSE;
samplerInfo.compareEnable = VK_FALSE;
samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS;
samplerInfo.mipmapMode = _mipMapFilter; // VK_SAMPLER_MIPMAP_MODE_NEAREST
samplerInfo.mipLodBias = 0.0f;
samplerInfo.minLod = 0.0f;
samplerInfo.maxLod = static_cast<float>(image.getMipLevels());
if (vkCreateSampler(logicalDevice, &samplerInfo, nullptr, &sampler) != VK_SUCCESS)
throw std::runtime_error("Texture sampler creation failed!");
}
...but the texture is rendered as if I passed VK_FILTER_LINEAR and VK_SAMPLER_MIPMAP_MODE_LINEAR, and I really don't know what's wrong.
Does someone have an idea? Thanks.
More Info:
This is the image texture (a simple 8x8 .png with every 4x4 corner of a different color):
This is the result using VK_FILTER_NEAREST and VK_SAMPLER_MIPMAP_MODE_NEAREST:
This is the .obj file of the cube, with Normals and Texture Coordinates:
# Blender v2.79 (sub 0) OBJ File: ''
# www.blender.org
mtllib untitled.mtl
o Cube
v 1.000000 -1.000000 -1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 -1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v 1.000000 1.000000 -1.000000
v 1.000000 1.000000 1.000000
v -1.000000 1.000000 1.000000
v -1.000000 1.000000 -1.000000
vt 0.000000 0.000000
vt 1.000000 0.000000
vt 1.000000 1.000000
vt 0.000000 1.000000
vt 0.000000 0.000000
vt 1.000000 0.000000
vt 1.000000 1.000000
vt 0.000000 1.000000
vt 1.000000 0.000000
vt 1.000000 1.000000
vt 0.000000 1.000000
vt 0.000000 0.000000
vt 1.000000 0.000000
vt 0.000000 1.000000
vt 0.000000 0.000000
vt 1.000000 0.000000
vt 1.000000 1.000000
vt 1.000000 0.000000
vt 1.000000 1.000000
vt 0.000000 1.000000
vn 0.0000 -1.0000 0.0000
vn 0.0000 1.0000 0.0000
vn 1.0000 0.0000 0.0000
vn -0.0000 -0.0000 1.0000
vn -1.0000 -0.0000 -0.0000
vn 0.0000 0.0000 -1.0000
usemtl Material
s off
f 1/1/1 2/2/1 3/3/1 4/4/1
f 5/5/2 8/6/2 7/7/2 6/8/2
f 1/1/3 5/9/3 6/10/3 2/11/3
f 2/12/4 6/13/4 7/7/4 3/14/4
f 3/15/5 7/16/5 8/17/5 4/4/5
f 5/5/6 1/18/6 4/19/6 8/20/6
I would expect a Minecraft-like behaviour, but I get this blurry style that I should obtain with VK_FILTER_LINEAR.
Thanks.
Update
I ran the program on another pc and the texture is sampled correctly, I suppose there's a bug/glitch/problem with my GPU, I'll try to update my drivers.
Update 2
I updated my GPU drivers and I'm now using the latest Vulkan SDK version (1.1.101.0), still nothing; RenderDoc analysis of the sampler reports no problem, I'm using the right filter; Removing/Not using mipmaps doesn't help; Not a single Validation layer error.
I'm starting to think my GPU still doesn't support Vulkan very well (Intel HD Graphics 620) so I guess I'll have to accept it and go on, knowing that at least it'll work on other PCs.
Update 3
I updated my GPU drivers and I'm now using the latest Vulkan SDK version (1.1.114.0), still nothing; RenderDoc analysis of the sampler reports no problem, I'm using the right filter; Removing/Not using mipmaps doesn't help; Not a single Validation layer error.
I'm starting to think my GPU still doesn't support Vulkan very well (Intel HD Graphics 620) so I guess I'll have to accept it and go on, knowing that at least it'll work on other PCs.
I had the exact same issue and decided to mess around with VkSamplerCreateInfo and found out that setting anisotropyEnabled to VK_FALSE fixes the problem, but I don't know why.
I am implementing clipping algorithm for a mesh where clipping region is a rectangle in normalized space [-1 , 1].
So my algorithm is as follows:
Create bounding box of a region to be used for a clipping, these coordinates will be in normalized space.
Create bounding box of a mesh in local space. transform them to clip coordinate space using MVP matrix. Divide by w to transform them into normalized space.
vec4 transformed_coords = MVP * vec4(vertex,1.0);
transformed_coords.xyz /= transformed_coords.w;
Check whether the two rectangles overlap or not. Use only x-y coordinates.
With this algorithm I am getting incorrect output.
model matrix
1.000000 0.000000 0.000000 0.000000
0.000000 0.000000 -1.000000 0.000000
0.000000 1.000000 0.000000 0.000000
0.000000 0.000000 0.000000 1.000000
view * projection
0.920664 -0.285565 -0.266194 -0.266141
0.039495 0.746434 -0.664418 -0.664286
-0.388354 -0.601072 -0.698633 -0.698493
-0.063192 -1.194295 0.894055 1.093857
MVP matrix
0.920664 -0.285565 -0.266194 -0.266141
0.388354 0.601072 0.698633 0.698493
0.039495 0.746434 -0.664418 -0.664286
-0.063192 -1.194295 0.894055 1.093857
bounding box in object space
-23.376505 -23.376505 -0.023644
23.376505 -23.376505 -0.023644
-23.376505 23.376505 -0.023644
23.376505 23.376505 -0.023644
-23.376505 -23.376505 1.430214
23.376505 -23.376505 1.430214
-23.376505 23.376505 1.430214
23.376505 23.376505 1.430214
after transformation with MVP
-30.664371 -8.587399 -9.199142 -8.997323
12.379420 -21.938423 -21.644522 -21.440216
-12.507672 19.514534 23.464052 23.659344
30.536121 6.163512 11.018670 11.216449
-30.606953 -7.502190 -10.165111 -9.963099
12.436841 -20.853212 -22.610493 -22.405994
-12.450252 20.599745 22.498081 22.693565
30.593540 7.248722 10.052701 10.250672
the bounding box after MinMax NDC min -0.577393 0.549507 1.000000 max 3.408166 1.023237 1.000000
after NDC
3.408166 0.954439 1.022431 1.000000
-0.577393 1.023237 1.009529 1.000000
-0.528657 0.824813 0.991746 1.000000
2.722441 0.549507 0.982367 1.000000
3.072031 0.752998 1.020276 1.000000
-0.555068 0.930698 1.009127 1.000000
-0.548625 0.907735 0.991386 1.000000
2.984540 0.707146 0.980687 1.000000
.min -0.577393 0.549507 max 3.408166 1.023237
Whereas min and max corner for region is min: -0.53, -0.53 max: 0.53, 0.53.
What could be going wrong here?
i need to be able to draw on a model, so i used of course the picking technique, and i used gluunproject in order to do this. now, when i get the point from the gluunproject, it it always multiplied by some permanent number, and i dont know why it happens.
my model is:
***# XSI Wavefront OBJ Export v3.0
# File Created: Mon Oct 29 00:15:19 2007
# XSI Version: 6.02.2007.0613
mtllib cube.mtl
o cube
# Hierarchy (from self to top father)
g cube
#begin 8 vertices
v -8.000000 -8.000000 -8.000000
v 8.000000 -8.000000 -8.000000
v -8.000000 8.000000 -8.000000
v 8.000000 8.000000 -8.000000
v -8.000000 -8.000000 8.000000
v 8.000000 -8.000000 8.000000
v -8.000000 8.000000 8.000000
v 8.000000 8.000000 8.000000
#end 8 vertices
#begin 24 normals
vn 0.000000 -0.000000 -1.000000
vn 0.000000 -0.000000 -1.000000
vn 0.000000 -0.000000 -1.000000
vn 0.000000 -0.000000 -1.000000
vn -0.000000 -1.000000 0.000000
vn -0.000000 -1.000000 0.000000
vn -0.000000 -1.000000 0.000000
vn -0.000000 -1.000000 0.000000
vn -1.000000 0.000000 -0.000000
vn -1.000000 0.000000 -0.000000
vn -1.000000 0.000000 -0.000000
vn -1.000000 0.000000 -0.000000
vn 1.000000 0.000000 0.000000
vn 1.000000 0.000000 0.000000
vn 1.000000 0.000000 0.000000
vn 1.000000 0.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
#end 24 vertex normals
#begin 24 texture vertices
vt 0.000000 0.000000 0.000000
vt 0.000000 1.000000 0.000000
vt 1.000000 1.000000 0.000000
vt 1.000000 0.000000 0.000000
vt 0.000000 0.000000 0.000000
vt 1.000000 0.000000 0.000000
vt 1.000000 1.000000 0.000000
vt 0.000000 1.000000 0.000000
vt 0.000000 0.000000 0.000000
vt 1.000000 0.000000 0.000000
vt 1.000000 1.000000 0.000000
vt 0.000000 1.000000 0.000000
vt 1.000000 0.000000 0.000000
vt 1.000000 1.000000 0.000000
vt 0.000000 1.000000 0.000000
vt 0.000000 0.000000 0.000000
vt 0.000000 1.000000 0.000000
vt 0.000000 0.000000 0.000000
vt 1.000000 0.000000 0.000000
vt 1.000000 1.000000 0.000000
vt 0.000000 0.000000 0.000000
vt 1.000000 0.000000 0.000000
vt 1.000000 1.000000 0.000000
vt 0.000000 1.000000 0.000000
#end 24 texture vertices
#begin 6 faces
usemtl material
f 1/1/1 3/2/2 4/3/3 2/4/4
usemtl material
f 1/5/5 2/6/6 6/7/7 5/8/8
usemtl material
f 1/9/9 5/10/10 7/11/11 3/12/12
usemtl material
f 2/13/13 4/14/14 8/15/15 6/16/16
usemtl material
f 3/17/17 7/18/18 8/19/19 4/20/20
usemtl material
f 5/21/21 6/22/22 8/23/23 7/24/24
#end 6 faces***
as you can see, it jusr a regular cube, now for example, when i click of one of its edges, i get the point of (4,4,4) instead of (8,8,8). why does it happen ?