Skip to content

Commit 225240c

Browse files
Samples: RTX_004_Textures is now bilingual (GLSL + Slang)
1 parent 1b235b4 commit 225240c

File tree

3 files changed

+105
-1
lines changed

3 files changed

+105
-1
lines changed

lvk/vulkan/VulkanUtils.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -792,6 +792,8 @@ lvk::Result lvk::compileShaderSlang(lvk::ShaderStage stage,
792792
.value = {.kind = slang::CompilerOptionValueKind::String, .stringValue0 = "spvMinLod"}},
793793
{.name = slang::CompilerOptionName::Capability,
794794
.value = {.kind = slang::CompilerOptionValueKind::String, .stringValue0 = "spvFragmentFullyCoveredEXT"}},
795+
{.name = slang::CompilerOptionName::Capability,
796+
.value = {.kind = slang::CompilerOptionValueKind::String, .stringValue0 = "spvRayTracingPositionFetchKHR"}},
795797
};
796798

797799
const slang::TargetDesc targetDesc = {

samples/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ if((WIN32 OR UNIX AND NOT (APPLE)) OR LVK_WITH_SAMPLES_ANDROID)
162162
ADD_DEMO("RTX_001_Hello" LVK_WITH_SLANG)
163163
ADD_DEMO("RTX_002_AO")
164164
ADD_DEMO("RTX_003_Pipeline")
165-
ADD_DEMO("RTX_004_Textures")
165+
ADD_DEMO("RTX_004_Textures" LVK_WITH_SLANG)
166166
endif()
167167

168168
ADD_DEMO("DEMO_001_SolarSystem")

samples/RTX_004_Textures.cpp

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,102 @@
1515
// we are going to use raw Vulkan here to initialize VK_KHR_ray_tracing_position_fetch
1616
#include <lvk/vulkan/VulkanUtils.h>
1717

18+
const char* codeSlang = R"(
19+
[[vk::binding(2, 0)]] RWTexture2D<float4> kTextures2DInOut[];
20+
21+
struct Camera {
22+
float4x4 viewInverse;
23+
float4x4 projInverse;
24+
};
25+
26+
struct PushConstants {
27+
Camera* cam;
28+
float2 dim;
29+
uint outTexture;
30+
uint texBackground;
31+
uint texObject;
32+
uint tlas;
33+
float time;
34+
};
35+
[[vk::push_constant]] PushConstants pc;
36+
37+
struct RayPayload {
38+
float3 color;
39+
};
40+
41+
[shader("raygeneration")]
42+
void rayGenMain() {
43+
uint3 launchID = DispatchRaysIndex();
44+
uint3 launchSize = DispatchRaysDimensions();
45+
46+
float2 pixelCenter = float2(launchID.xy) + float2(0.5, 0.5);
47+
float2 d = 2.0 * (pixelCenter / float2(launchSize.xy)) - 1.0;
48+
49+
float4 origin = mul(float4(0, 0, 0, 1), pc.cam->viewInverse);
50+
float4 target = mul(float4(d, 1, 1), pc.cam->projInverse);
51+
float4 direction = mul(float4(normalize(target.xyz), 0), pc.cam->viewInverse);
52+
53+
RayDesc ray;
54+
ray.Origin = origin.xyz;
55+
ray.Direction = direction.xyz;
56+
ray.TMin = 0.1;
57+
ray.TMax = 500.0;
58+
59+
RayPayload payload = { float3(0.0, 0.0, 0.0) };
60+
61+
TraceRay(
62+
kTLAS[NonUniformResourceIndex(pc.tlas)],
63+
RAY_FLAG_FORCE_OPAQUE,
64+
0xff,
65+
0,
66+
0,
67+
0,
68+
ray,
69+
payload
70+
);
71+
72+
kTextures2DInOut[NonUniformResourceIndex(pc.outTexture)][launchID.xy] = float4(payload.color, 1.0);
73+
}
74+
75+
[shader("miss")]
76+
void missMain(inout RayPayload payload) {
77+
float2 uv = float2(DispatchRaysIndex().xy) / pc.dim;
78+
payload.color = textureBindless2D(pc.texBackground, 0, uv).rgb;
79+
}
80+
81+
float4 triplanar(uint tex, float3 worldPos, float3 normal) {
82+
// generate weights, show texture on both sides of the object (positive and negative)
83+
float3 weights = abs(normal);
84+
// make the transition sharper
85+
weights = pow(weights, float3(8.0, 8.0, 8.0));
86+
// make sure the sum of all components is 1
87+
weights = weights / (weights.x + weights.y + weights.z);
88+
89+
// sample the texture for 3 different projections
90+
float4 cXY = textureBindless2D(tex, 0, worldPos.xy);
91+
float4 cZY = textureBindless2D(tex, 0, worldPos.zy);
92+
float4 cXZ = textureBindless2D(tex, 0, worldPos.xz);
93+
94+
// combine the projected colors
95+
return cXY * weights.z + cZY * weights.x + cXZ * weights.y;
96+
}
97+
98+
[shader("closesthit")]
99+
void closestHitMain(inout RayPayload payload, in BuiltInTriangleIntersectionAttributes attribs) {
100+
float3 pos0 = HitTriangleVertexPosition(0);
101+
float3 pos1 = HitTriangleVertexPosition(1);
102+
float3 pos2 = HitTriangleVertexPosition(2);
103+
104+
float3 baryCoords = float3(1.0 - attribs.barycentrics.x - attribs.barycentrics.y,
105+
attribs.barycentrics.x,
106+
attribs.barycentrics.y);
107+
float3 pos = pos0 * baryCoords.x + pos1 * baryCoords.y + pos2 * baryCoords.z;
108+
109+
// triplanar mapping in object-space; for our icosahedron, object-space position and normal vectors are the same
110+
payload.color = triplanar(pc.texObject, pos, normalize(pos)).rgb;
111+
}
112+
)";
113+
18114
const char* codeRayGen = R"(
19115
#version 460
20116
#extension GL_EXT_ray_tracing : require
@@ -337,9 +433,15 @@ VULKAN_APP_MAIN {
337433
res.texBackground = createTextureFromFile(app, "src/bistro/BuildingTextures/wood_polished_01_diff.png");
338434
res.texObject = createTextureFromFile(app, "src/bistro/BuildingTextures/Cobble_02B_Diff.png");
339435

436+
#if defined(LVK_DEMO_WITH_SLANG)
437+
res.raygen_ = ctx_->createShaderModule({codeSlang, lvk::Stage_RayGen, "Shader Module: main (raygen)"});
438+
res.miss_ = ctx_->createShaderModule({codeSlang, lvk::Stage_Miss, "Shader Module: main (miss)"});
439+
res.hit_ = ctx_->createShaderModule({codeSlang, lvk::Stage_ClosestHit, "Shader Module: main (closesthit)"});
440+
#else
340441
res.raygen_ = ctx_->createShaderModule({codeRayGen, lvk::Stage_RayGen, "Shader Module: main (raygen)"});
341442
res.miss_ = ctx_->createShaderModule({codeMiss, lvk::Stage_Miss, "Shader Module: main (miss)"});
342443
res.hit_ = ctx_->createShaderModule({codeClosestHit, lvk::Stage_ClosestHit, "Shader Module: main (closesthit)"});
444+
#endif // defined(LVK_DEMO_WITH_SLANG)
343445

344446
res.pipeline = ctx_->createRayTracingPipeline(lvk::RayTracingPipelineDesc{
345447
.smRayGen = {lvk::ShaderModuleHandle(res.raygen_)},

0 commit comments

Comments
 (0)