Having some problem getting the uvs working right with vulkan raytracing

I’ve been working with ray-tracing for about a month so I’m still getting used it. I’m having some problems getting the uvs to look right. Here’s the shader I’m working with, I think the problem has something to do with v.uv = vec2(d0.x, d1.y); in the unpack function. I’ve been playing around with it for a while but haven’t been having any luck. I’ve also tried making a uv buffer and directly sending the info directly into and working from that, but it only works with one mesh then looks messed up after that.

#version 460
#extension GL_EXT_ray_tracing : require
#extension GL_EXT_nonuniform_qualifier : enable

layout(location = 0) rayPayloadInEXT vec3 hitValue;
layout(location = 2) rayPayloadEXT bool shadowed;
hitAttributeEXT vec2 attribs;

struct VertexData
{
	vec3 Position;
	vec3 Normal;
	vec2 UV;
	vec3 Tangent;
	vec3 BiTangent;
};


struct DirectionalLight
{
	vec3 direction;
    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
};

struct PointLight 
{
    vec3 position;
    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
	float constant;
    float linear;
    float quadratic;
};

struct MaterialInfo
{
	vec3 Ambient;
    vec3 Diffuse;
    vec3 Specular;    
    float Shininess;
    float Reflectivness;

	uint DiffuseMapID;
	uint SpecularMapID;
	uint NormalMapID;
	uint DepthMapID;
	uint AlphaMapID;
	uint EmissionMapID;
};

struct Material
{
	vec3 Ambient;
    vec3 Diffuse;
    vec3 Specular;    
    float Shininess;
    float Reflectivness;

	vec3 DiffuseMap;
	vec3 SpecularMap;
	vec3 NormalMap;
	vec3 DepthMap;
	vec3 AlphaMap;
	vec3 EmissionMap;
};

layout(binding = 0) uniform accelerationStructureEXT topLevelAS;
layout(binding = 2) uniform UBO 
{
	mat4 viewInverse;
	mat4 projInverse;
	mat4 modelInverse;
	DirectionalLight dlight;
	vec3 viewPos;
	PointLight plight;
	int vertexSize;
} ubo;
layout(binding = 3) buffer Vertices { vec4 v[]; } vertices[];
layout(binding = 4) buffer Indices { uint i[]; } indices[];
layout(binding = 5) buffer MaterialInfos { MaterialInfo materialInfo[]; } MaterialList;
layout(binding = 6) uniform sampler2D TextureMap[];

struct Vertex
{
  vec3 pos;
  vec3 normal;
  vec2 uv;
  vec4 tangent;
  vec4 BiTangant;
  vec4 Color;
  vec4 BoneID;
  vec4 BoneWeights;
 };


Vertex unpack(uint index)
{
	const int m = ubo.vertexSize / 16;

	vec4 d0 = vertices[gl_InstanceCustomIndexEXT].v[m * index + 0];
	vec4 d1 = vertices[gl_InstanceCustomIndexEXT].v[m * index + 1];
	vec4 d2 = vertices[gl_InstanceCustomIndexEXT].v[m * index + 2];

	Vertex v;
	v.pos = d0.xyz;
	v.normal = vec3(d0.w, d1.x, d1.y);
	v.Color = vec4(d2.x, d2.y, d2.z, 1.0);
	v.uv = vec2(d0.x, 
				d1.y);
	v.tangent = vec4(d0.w, d1.y, d1.y, 0.0f);

	return v;
}

Material BuildMaterial(vec2 UV)
{
	Material material;
	material.Ambient = MaterialList.materialInfo[gl_InstanceCustomIndexEXT].Ambient;
	material.Diffuse = MaterialList.materialInfo[gl_InstanceCustomIndexEXT].Diffuse;
	material.Specular = MaterialList.materialInfo[gl_InstanceCustomIndexEXT].Specular;
	material.Shininess = MaterialList.materialInfo[gl_InstanceCustomIndexEXT].Shininess;
	material.Reflectivness = MaterialList.materialInfo[gl_InstanceCustomIndexEXT].Reflectivness;
	material.DiffuseMap = vec3(texture(TextureMap[MaterialList.materialInfo[gl_InstanceCustomIndexEXT].DiffuseMapID], UV));
	material.SpecularMap = vec3(texture(TextureMap[MaterialList.materialInfo[gl_InstanceCustomIndexEXT].SpecularMapID], UV));
	material.NormalMap = vec3(texture(TextureMap[MaterialList.materialInfo[gl_InstanceCustomIndexEXT].NormalMapID], UV));
	material.AlphaMap = vec3(texture(TextureMap[MaterialList.materialInfo[gl_InstanceCustomIndexEXT].AlphaMapID], UV));
	material.EmissionMap = vec3(texture(TextureMap[MaterialList.materialInfo[gl_InstanceCustomIndexEXT].EmissionMapID], UV));
	return material;
};

void main()
{
    const ivec3 index = ivec3(indices[gl_InstanceCustomIndexEXT].i[3 * gl_PrimitiveID], 
						      indices[gl_InstanceCustomIndexEXT].i[3 * gl_PrimitiveID + 1], 
						      indices[gl_InstanceCustomIndexEXT].i[3 * gl_PrimitiveID + 2]);

	const Vertex v0 = unpack(index.x);
	const Vertex v1 = unpack(index.y);
	const Vertex v2 = unpack(index.z);

	const vec2 uv0 = getTexCoord(index.x);
	const vec2 uv1 = getTexCoord(index.y);
	const vec2 uv2 = getTexCoord(index.z);

	// Interpolate normal
	const vec3 barycentricCoords = vec3(1.0f - attribs.x - attribs.y, attribs.x, attribs.y);
	vec3 normal = normalize(v0.normal * barycentricCoords.x + v1.normal * barycentricCoords.y + v2.normal * barycentricCoords.z);
	vec2 UV = v0.uv * barycentricCoords.x + v1.uv * barycentricCoords.y + v2.uv * barycentricCoords.z;
	 vec3 worldPos = v0.pos * barycentricCoords.x + v1.pos * barycentricCoords.y + v2.pos * barycentricCoords.z;

	 	const Material material = BuildMaterial(UV);

	vec3 lightDir = normalize(-ubo.dlight.direction);
	float diff = max(dot(ubo.dlight.direction, lightDir), 0.0);

	vec3 ambient = ubo.dlight.ambient *  material.DiffuseMap;
    vec3 diffuse = ubo.dlight.diffuse * diff *  material.DiffuseMap;
 
	 hitValue = ambient + diffuse;


		vec3 lightDir2 = normalize(ubo.plight.position - worldPos);
	float diff2 = max(dot(ubo.plight.position, lightDir2), 0.0);
	 float distance = length(ubo.plight.position - worldPos);
    float attenuation = 1.0 / (ubo.plight.constant + ubo.plight.linear * distance + ubo.plight.quadratic * (distance * distance));    
    
	vec3 ambient2 = ubo.plight.ambient * material.DiffuseMap;
    vec3 diffuse2 = ubo.plight.diffuse * diff * material.DiffuseMap;
//	ambient2 *= attenuation;
  //  diffuse2 *= attenuation;

	 hitValue += ambient2 + diffuse2;















	float spec = 0.0f;
//  if(dot(normal, L) > 0)
//  {
	// Shadow casting
	float tmin = 0.001;
	float tmax = 10000.0;
	vec3 origin = gl_WorldRayOriginEXT + gl_WorldRayDirectionEXT * gl_HitTEXT;
	shadowed = true;  
	// Trace shadow ray and offset indices to match shadow hit/miss shader group indices
	traceRayEXT(topLevelAS, gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT | gl_RayFlagsSkipClosestHitShaderEXT, 0xFF, 1, 0, 1, origin, tmin, lightDir, tmax, 2);
	if (shadowed) {
		hitValue *= 0.3f;
	}
	else
	{
		vec3 halfwayDir = normalize(ubo.dlight.direction + ubo.viewPos);  
         spec = pow(max(dot(normal, halfwayDir), 0.0), material.Shininess);
		vec3 specular = ubo.dlight.specular * spec * material.Specular;
		hitValue += specular;
	}

	traceRayEXT(topLevelAS, gl_RayFlagsTerminateOnFirstHitEXT | gl_RayFlagsOpaqueEXT | gl_RayFlagsSkipClosestHitShaderEXT, 0xFF, 1, 0, 1, origin, tmin, lightDir2, tmax, 2);
	if (shadowed) {
		hitValue *= 0.3f;
	}
	else
	{
		vec3 halfwayDir2 = normalize(ubo.plight.position + ubo.viewPos);  
        spec = pow(max(dot(normal, halfwayDir2), 0.0), material.Shininess);
		vec3 specular2 = ubo.plight.specular * spec * material.Specular;
		//specular2 *= attenuation;
		hitValue += specular2;
	}
		
 //  }

}

See my answer at https://stackoverflow.com/questions/65975157/having-some-problem-getting-the-uvs-working-right-with-vulkan-raytracing.

If I’m not mistaken I already hinted at that on the Discord.

Thanks, it works now.
So this works more like a byte offset to the Vertex struct?

||vec4 d0 = vertices[gl_InstanceCustomIndexEXT].v[m * index + 0];|
||vec4 d1 = vertices[gl_InstanceCustomIndexEXT].v[m * index + 1];|
||vec4 d2 = vertices[gl_InstanceCustomIndexEXT].v[m * index + 2];|

d0.x = 0 bytes in the vertex struct,
d0.y = 4 bytes in the vertex struct,
d0.z = 8 bytes in the vertex struct,
d0.w = 12 bytes in the vertex struct,
d1.x = 16 bytes in the vertex struct,
d1.y = 20 bytes in the vertex struct,
d1.z = 24 bytes in the vertex struct,
d1.w = 28 bytes in the vertex struct,
d2.x = 32 bytes in the vertex struct,
d2.y = 36 bytes in the vertex struct,
d2.z = 40 bytes in the vertex struct,
d2.w = 44 bytes in the vertex struct

Then to extend it for the BiTangant, and Color data would it be something like this?

||vec4 d3 = vertices[gl_InstanceCustomIndexEXT].v[m * index + 3];|
||vec4 d4 = vertices[gl_InstanceCustomIndexEXT].v[m * index + 4];|

v.BiTangant = vec4(d3.x, d3.y, d3.z, d3.w);
v.Color = vec4(d4.x, d4.y, d4.z, d4.z);

Kind of yes. I used this way of unpacking vertex data so I could easily mix vectors of different sizes on the host side without having to pack for the default GLSL layout.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.