问题描述
我已经使用光线追踪大约一个月了,所以我仍在使用它。我在让紫外线看起来正确时遇到了一些问题。这是我正在使用的着色器,我认为问题与 v.uv = vec2(d0.x,d1.y);在解包功能中。我已经玩了一段时间了,但一直没有运气。我也试过制作一个 uv 缓冲区并直接将信息发送到其中并从中工作,但它只适用于一个网格,然后看起来一团糟。
#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,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,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,lightDir2,2);
if (shadowed) {
hitValue *= 0.3f;
}
else
{
vec3 halfwayDir2 = normalize(ubo.plight.position + ubo.viewPos);
spec = pow(max(dot(normal,halfwayDir2),material.Shininess);
vec3 specular2 = ubo.plight.specular * spec * material.specular;
//specular2 *= attenuation;
hitValue += specular2;
}
// }
}
解决方法
v.uv = vec2(d0.x,d1.y);
肯定看起来是错误的,因为 d0.x
包含顶点位置的 x
分量,而不是纹理坐标的 u
分量。错误地取自法线的 v
组件的 w
组件也是如此。由于您没有在主机端发布顶点布局,我只能猜测,但是如果您的主机顶点布局是这样的:
glm::vec3 pos;
glm::vec3 normal;
glm::vec2 uv;
然后你解压成多个 vec4,你会得到这个:
vec4 0: pos.x|pos.y|pos.z|normal.x
vec4 1: normal.y|normal.z|uv.u|uv.v
这意味着您需要像这样获取数据:
v.pos = d0.xyz;
v.normal = vec3(d0.w,d1.x,d1.y);
v.uv = d1.zw;