diff --git a/.gitignore b/.gitignore index c4ab876b..8c318e38 100644 --- a/.gitignore +++ b/.gitignore @@ -240,4 +240,6 @@ android/.idea/** libs/vulkan/*.so -.vscode/* \ No newline at end of file +.vscode/* + +__pycache__** \ No newline at end of file diff --git a/shaders/slang/_rename.py b/shaders/slang/_rename.py new file mode 100644 index 00000000..fe16d519 --- /dev/null +++ b/shaders/slang/_rename.py @@ -0,0 +1,17 @@ +# Copyright (C) 2025 by Sascha Willems - www.saschawillems.de +# This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) + +from shutil import move + +# To match required file names to fother shading languages that don't support multiple entry points, shader files may need to be renamed for some samples +def checkRenameFiles(samplename): + mappings = {} + match samplename: + case "raytracingbasic": + mappings = { + "raytracingbasic.rchit.spv": "closesthit.rchit.spv", + "raytracingbasic.rmiss.spv": "miss.rmiss.spv", + "raytracingbasic.rgen.spv": "raygen.rgen.spv", + } + for x, y in mappings.items(): + move(samplename + "\\" + x, samplename + "\\" + y) diff --git a/shaders/slang/compileshaders.py b/shaders/slang/compileshaders.py index bbd73705..104ca2ff 100644 --- a/shaders/slang/compileshaders.py +++ b/shaders/slang/compileshaders.py @@ -6,6 +6,7 @@ import fileinput import os import subprocess import sys +from _rename import * parser = argparse.ArgumentParser(description='Compile all slang shaders') parser.add_argument('--slangc', type=str, help='path to slangc executable') @@ -70,13 +71,15 @@ dir_path = os.path.dirname(os.path.realpath(__file__)) dir_path = dir_path.replace('\\', '/') for root, dirs, files in os.walk(dir_path): for file in files: - if (compile_single_sample != "" and os.path.basename(root) != compile_single_sample): + folder_name = os.path.basename(root) + if (compile_single_sample != "" and folder_name != compile_single_sample): continue if file.endswith(".slang"): input_file = os.path.join(root, file) # Slang can store multiple shader stages in a single file, we need to split into separate SPIR-V files for the sample framework stages = getShaderStages(input_file) print("Compiling %s" % input_file) + output_base_file_name = input_file for stage in stages: if (len(stages) > 1): entry_point = stage + "Main" @@ -102,8 +105,9 @@ for root, dirs, files in os.walk(dir_path): output_ext = ".mesh" case "amplification": output_ext = ".task" - output_file = input_file + output_ext + ".spv" + output_file = output_base_file_name + output_ext + ".spv" output_file = output_file.replace(".slang", "") res = subprocess.call("%s %s -profile spirv_1_4 -matrix-layout-column-major -target spirv -o %s -entry %s -stage %s -warnings-disable 39001" % (compiler_path, input_file, output_file, entry_point, stage), shell=True) if res != 0: - sys.exit(res) \ No newline at end of file + sys.exit(res) + checkRenameFiles(folder_name) \ No newline at end of file diff --git a/shaders/slang/raytracingbasic/raytracingbasic.slang b/shaders/slang/raytracingbasic/raytracingbasic.slang new file mode 100644 index 00000000..49d8182d --- /dev/null +++ b/shaders/slang/raytracingbasic/raytracingbasic.slang @@ -0,0 +1,60 @@ +/* Copyright (c) 2025, Sascha Willems + * + * SPDX-License-Identifier: MIT + * + */ + +RaytracingAccelerationStructure accelStruct; +RWTexture2D image; +struct CameraProperties +{ + float4x4 viewInverse; + float4x4 projInverse; +}; +ConstantBuffer cam; + +struct Attributes +{ + float2 bary; +}; + +struct Payload +{ + float3 hitValue; +}; + +[shader("raygeneration")] +void raygenerationMain() +{ + uint3 LaunchID = DispatchRaysIndex(); + uint3 LaunchSize = DispatchRaysDimensions(); + + const float2 pixelCenter = float2(LaunchID.xy) + float2(0.5, 0.5); + const float2 inUV = pixelCenter/float2(LaunchSize.xy); + float2 d = inUV * 2.0 - 1.0; + float4 target = mul(cam.projInverse, float4(d.x, d.y, 1, 1)); + + RayDesc rayDesc; + rayDesc.Origin = mul(cam.viewInverse, float4(0,0,0,1)).xyz; + rayDesc.Direction = mul(cam.viewInverse, float4(normalize(target.xyz), 0)).xyz; + rayDesc.TMin = 0.001; + rayDesc.TMax = 10000.0; + + Payload payload; + TraceRay(accelStruct, RAY_FLAG_FORCE_OPAQUE, 0xff, 0, 0, 0, rayDesc, payload); + + image[int2(LaunchID.xy)] = float4(payload.hitValue, 0.0); +} + +[shader("closesthit")] +void closesthitMain(inout Payload p, in Attributes attribs) +{ + const float3 barycentricCoords = float3(1.0f - attribs.bary.x - attribs.bary.y, attribs.bary.x, attribs.bary.y); + p.hitValue = barycentricCoords; +} + +[shader("miss")] +void missMain(inout Payload p) +{ + p.hitValue = float3(0.0, 0.0, 0.2); +}