Sample 코드의 다음 단계
17280 단어 hello_worldKHRVulkanC++
ray tracking의 Hello World(hello triangle) 코드는 공식khronos에서 공개한 Sample 코드를 참고하면 될 것 같습니다.
https://github.com/KhronosGroup/Vulkan-Samples/tree/master/samples/extensions/raytracing_basic
레이 트랙의 차이점.
전제는 어느 정도 블랑칸에 적응했지만 순조롭게 구축되면 삼각형이 나타난다.놀랍게도, shader의 출력 결과는 완전히 다르다.일반적인vert/frag의 음영으로 출력되기를 기대하는 것은 각 정점의 벡터이지만raytraacing에서raygen shader가 계산한 결과는image로 출력됩니다.그림% 1개의 캡션을 편집했습니다.
다음 단계
Sample code는 2차원 삼각형만 출력하기 때문에 실제 쓰기 효과가 없습니다.다음 단계로 다음 사이트를 참고하게 해 주세요.
https://nvpro-samples.github.io/vk_raytracing_tutorial_KHR/#accelerationstructure/bottom-levelaccelerationstructure
여기에 입방체의 출력과raygen/miss/rchiit의 각종shader의 응용을 기술하였다.
아까 Sample code를 참고할 때 필요한 변경점은 다음과 같습니다.
bottom level acceleration structure 변경 사항
primitive count
Sample 코드는 삼각형만 출력하기 때문에 Geometry 정보는 직접 입력합니다.이곳을 수정하다.uint32_t primitiveCount = indicesCount / 3;
//build range info
VkAccelerationStructureBuildRangeInfoKHR mRangeInfo = {};
mRangeInfo.primitiveCount = primitiveCount;
mRangeInfo.primitiveOffset = 0;
mRangeInfo.firstVertex = 0;
mRangeInfo.transformOffset = 0;
update flag
Sample 코드에서transform 행렬의 변경을 통해 화면을 업데이트하는 것을 고려하지 않았습니다.먼저 AS(Acceleration Structure)의 정보는 처음 빌드할 때와 마찬가지로 빌드 명령으로 업데이트됩니다.pfnCmdBuildAccelerationStructuresKHR(
commandBuffer, 1, &mBuildCommandGeometryInfo, rangeInfos.data());
pfn은 기능 지침이다.vulkan에서 extension에서 제공하는 함수를 사용하면 프로그램에 함수를 바늘로 전달해야 합니다.pfnCmdBuildAccelerationStructuresKHR =
reinterpret_cast<PFN_vkCmdBuildAccelerationStructuresKHR>(
vkGetDeviceProcAddr(device,"vkCmdBuildAccelerationStructuresKHR"));
AS의 정보를 업데이트한 후 다시 이 함수를 사용하여 AS를 업데이트하지만 AS를 구축할 때 미리 로고를 설정해야 한다.//build geometry info
mBuildCommandGeometryInfo = {};
mBuildCommandGeometryInfo.sType =
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR;
mBuildCommandGeometryInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
mBuildCommandGeometryInfo.flags =
VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR |
VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR;
mBuildCommandGeometryInfo.mode = VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR;
mBuildCommandGeometryInfo.dstAccelerationStructure = mAS;
mBuildCommandGeometryInfo.geometryCount = 1;
mBuildCommandGeometryInfo.pGeometries = &mGeometry;
mBuildCommandGeometryInfo.scratchData.deviceAddress =
scratchBufferDeviceAddress.deviceAddress;
gflags의 멤버 VKBUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR를 미리 설정하지 않으면 업데이트 후 프로그램이 다운돼 PC 자체로 작동할 수 없기 때문에 주의가 필요하다.
push constants
light의 위치와 같은 정보는 모든shader에서 같은 데이터를 처리하기 때문에push constants에서 제공됩니다.VkPushConstantRange pushConstant{};
pushConstant.stageFlags = VK_SHADER_STAGE_RAYGEN_BIT_KHR |
VK_SHADER_STAGE_MISS_BIT_KHR |
VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;
pushConstant.offset = 0;
pushConstant.size = size;/*constantsのサイズ*/
std::vector<VkPushConstantRange> pushConstants = {pushConstant};
//pipelinelayoutinfoに追加
pipelineLayoutInfo.pushConstantRangeCount = pushConstants->size();
pipelineLayoutInfo.pPushConstantRanges = pushConstants->data();
if (vkCreatePipelineLayout(device, &pipelineLayoutInfo, nullptr, &mPipelineLayout) !=
VK_SUCCESS)
std::runtime_error("failed to create pipeline layout");
rchiit 면도기의 변경
Sample 코드에서, 모든 정점의 색깔은 rchiit 음영으로 계산됩니다.다음 단계의 예에 따라 이것을 변경합니다.다음은main 함수만 추출합니다.
closesthit.rchitvoid main()
{
ivec3 ind = ivec3(indices[0].i[3 * gl_PrimitiveID + 0], //
indices[0].i[3 * gl_PrimitiveID + 1], //
indices[0].i[3 * gl_PrimitiveID + 2]); //
Vertex3D v0 = vertices[0].v[ind.x];
Vertex3D v1 = vertices[0].v[ind.y];
Vertex3D v2 = vertices[0].v[ind.z]; /*Vertrex3Dはユーザ定義しているstruct*/
const vec3 barycentricCoords = vec3(1.0f - attribs.x - attribs.y, attribs.x, attribs.y);
vec3 normal = v0.normal * barycentricCoords.x +
v1.normal * barycentricCoords.y +
v2.normal * barycentricCoords.z;
// camはuniform bufferで渡しているstruct
vec4 normalP = normalize(cam.modelViewProj * vec4(normal, 0.0));
vec3 worldPos = v0.pos * barycentricCoords.x +
v1.pos * barycentricCoords.y +
v2.pos * barycentricCoords.z;
vec4 worldP = cam.modelViewProj * vec4(worldPos, 0.0);
vec3 L;
float lightIntensity = pushC.lightIntensity;
float lightDistance = 10000.0;
vec3 lDir = pushC.lightPosition - worldP.xyz;
lightDistance = length(lDir);
lightIntensity = lightIntensity / (lightDistance * lightDistance);
L = normalize(lDir);
float dotNL = min(lightIntensity * max(dot(normalP.xyz, L), 0.02), 1.0);
hitValue = vec3(dotNL);
}
실행하면 다음과 같은 예시를 얻을 수 있다. 빛이 입방체를 비춘다. (보기에 장방체만 있다.)
끝맺다
이 글에서, 나는 블랭크의 코드를 바탕으로 Sample 코드에서 다음 단계로 어떻게 전진하는지 보도해 보았다.여기에는 c++ 코드만 말하고 vulkan API에서ray tracking의 구조도 알아야 하기 때문에khronos 공식 홈페이지를 찾아보는 것이 좋습니다.
https://www.khronos.org/blog/ray-tracing-in-vulkan
연휴에는 외출 시간을 극력 줄였지만, 그동안 얻은 지식을 성과물로 남기고 싶어 수출한 것을 여기에 두고 싶다는 동기에서 이번에 투고하기로 했다.욕심이라면 더 어려운 모델이 되고 싶고 배경과 빛이 비치는 상황도 예뻐지고 싶지만 구조와 코딩이 생각보다 어려워 연휴 동안 할 수 있는 건 여기까지다.같은 곳에서 넘어진 사람에게 도움이 되길 바란다.
Reference
이 문제에 관하여(Sample 코드의 다음 단계), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/Aqoole/items/5121cd64dc88ee4d9daf
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Sample code는 2차원 삼각형만 출력하기 때문에 실제 쓰기 효과가 없습니다.다음 단계로 다음 사이트를 참고하게 해 주세요.
https://nvpro-samples.github.io/vk_raytracing_tutorial_KHR/#accelerationstructure/bottom-levelaccelerationstructure
여기에 입방체의 출력과raygen/miss/rchiit의 각종shader의 응용을 기술하였다.
아까 Sample code를 참고할 때 필요한 변경점은 다음과 같습니다.
bottom level acceleration structure 변경 사항
primitive count
Sample 코드는 삼각형만 출력하기 때문에 Geometry 정보는 직접 입력합니다.이곳을 수정하다.
uint32_t primitiveCount = indicesCount / 3;
//build range info
VkAccelerationStructureBuildRangeInfoKHR mRangeInfo = {};
mRangeInfo.primitiveCount = primitiveCount;
mRangeInfo.primitiveOffset = 0;
mRangeInfo.firstVertex = 0;
mRangeInfo.transformOffset = 0;
update flag
Sample 코드에서transform 행렬의 변경을 통해 화면을 업데이트하는 것을 고려하지 않았습니다.먼저 AS(Acceleration Structure)의 정보는 처음 빌드할 때와 마찬가지로 빌드 명령으로 업데이트됩니다.
pfnCmdBuildAccelerationStructuresKHR(
commandBuffer, 1, &mBuildCommandGeometryInfo, rangeInfos.data());
pfn은 기능 지침이다.vulkan에서 extension에서 제공하는 함수를 사용하면 프로그램에 함수를 바늘로 전달해야 합니다.pfnCmdBuildAccelerationStructuresKHR =
reinterpret_cast<PFN_vkCmdBuildAccelerationStructuresKHR>(
vkGetDeviceProcAddr(device,"vkCmdBuildAccelerationStructuresKHR"));
AS의 정보를 업데이트한 후 다시 이 함수를 사용하여 AS를 업데이트하지만 AS를 구축할 때 미리 로고를 설정해야 한다.//build geometry info
mBuildCommandGeometryInfo = {};
mBuildCommandGeometryInfo.sType =
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR;
mBuildCommandGeometryInfo.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR;
mBuildCommandGeometryInfo.flags =
VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR |
VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR;
mBuildCommandGeometryInfo.mode = VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR;
mBuildCommandGeometryInfo.dstAccelerationStructure = mAS;
mBuildCommandGeometryInfo.geometryCount = 1;
mBuildCommandGeometryInfo.pGeometries = &mGeometry;
mBuildCommandGeometryInfo.scratchData.deviceAddress =
scratchBufferDeviceAddress.deviceAddress;
gflags의 멤버 VKBUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR를 미리 설정하지 않으면 업데이트 후 프로그램이 다운돼 PC 자체로 작동할 수 없기 때문에 주의가 필요하다.push constants
light의 위치와 같은 정보는 모든shader에서 같은 데이터를 처리하기 때문에push constants에서 제공됩니다.
VkPushConstantRange pushConstant{};
pushConstant.stageFlags = VK_SHADER_STAGE_RAYGEN_BIT_KHR |
VK_SHADER_STAGE_MISS_BIT_KHR |
VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;
pushConstant.offset = 0;
pushConstant.size = size;/*constantsのサイズ*/
std::vector<VkPushConstantRange> pushConstants = {pushConstant};
//pipelinelayoutinfoに追加
pipelineLayoutInfo.pushConstantRangeCount = pushConstants->size();
pipelineLayoutInfo.pPushConstantRanges = pushConstants->data();
if (vkCreatePipelineLayout(device, &pipelineLayoutInfo, nullptr, &mPipelineLayout) !=
VK_SUCCESS)
std::runtime_error("failed to create pipeline layout");
rchiit 면도기의 변경
Sample 코드에서, 모든 정점의 색깔은 rchiit 음영으로 계산됩니다.다음 단계의 예에 따라 이것을 변경합니다.다음은main 함수만 추출합니다.
closesthit.rchit
void main()
{
ivec3 ind = ivec3(indices[0].i[3 * gl_PrimitiveID + 0], //
indices[0].i[3 * gl_PrimitiveID + 1], //
indices[0].i[3 * gl_PrimitiveID + 2]); //
Vertex3D v0 = vertices[0].v[ind.x];
Vertex3D v1 = vertices[0].v[ind.y];
Vertex3D v2 = vertices[0].v[ind.z]; /*Vertrex3Dはユーザ定義しているstruct*/
const vec3 barycentricCoords = vec3(1.0f - attribs.x - attribs.y, attribs.x, attribs.y);
vec3 normal = v0.normal * barycentricCoords.x +
v1.normal * barycentricCoords.y +
v2.normal * barycentricCoords.z;
// camはuniform bufferで渡しているstruct
vec4 normalP = normalize(cam.modelViewProj * vec4(normal, 0.0));
vec3 worldPos = v0.pos * barycentricCoords.x +
v1.pos * barycentricCoords.y +
v2.pos * barycentricCoords.z;
vec4 worldP = cam.modelViewProj * vec4(worldPos, 0.0);
vec3 L;
float lightIntensity = pushC.lightIntensity;
float lightDistance = 10000.0;
vec3 lDir = pushC.lightPosition - worldP.xyz;
lightDistance = length(lDir);
lightIntensity = lightIntensity / (lightDistance * lightDistance);
L = normalize(lDir);
float dotNL = min(lightIntensity * max(dot(normalP.xyz, L), 0.02), 1.0);
hitValue = vec3(dotNL);
}
실행하면 다음과 같은 예시를 얻을 수 있다. 빛이 입방체를 비춘다. (보기에 장방체만 있다.)끝맺다
이 글에서, 나는 블랭크의 코드를 바탕으로 Sample 코드에서 다음 단계로 어떻게 전진하는지 보도해 보았다.여기에는 c++ 코드만 말하고 vulkan API에서ray tracking의 구조도 알아야 하기 때문에khronos 공식 홈페이지를 찾아보는 것이 좋습니다.
https://www.khronos.org/blog/ray-tracing-in-vulkan
연휴에는 외출 시간을 극력 줄였지만, 그동안 얻은 지식을 성과물로 남기고 싶어 수출한 것을 여기에 두고 싶다는 동기에서 이번에 투고하기로 했다.욕심이라면 더 어려운 모델이 되고 싶고 배경과 빛이 비치는 상황도 예뻐지고 싶지만 구조와 코딩이 생각보다 어려워 연휴 동안 할 수 있는 건 여기까지다.같은 곳에서 넘어진 사람에게 도움이 되길 바란다.
Reference
이 문제에 관하여(Sample 코드의 다음 단계), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/Aqoole/items/5121cd64dc88ee4d9daf
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(Sample 코드의 다음 단계), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/Aqoole/items/5121cd64dc88ee4d9daf텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)