yum-mirror/slang

Making it easier to work with shaders

git clone https://git.yummers.dev/yum-mirror/slang

Gangzheng TongAdd Payload Access Qualifiers to the raytracing examples (#7092)04ba87e23

master
4.0 KiB148 linesraw
1// shaders.slang
2
3struct Uniforms
4{
5    float screenWidth, screenHeight;
6    float focalLength, frameHeight;
7    float4 cameraDir;
8    float4 cameraUp;
9    float4 cameraRight;
10    float4 cameraPosition;
11    float4 lightDir;
12};
13
14struct Primitive
15{
16    float4 data0;
17    float4 color;
18    float3 getNormal() { return data0.xyz; }
19    float3 getColor() { return color.xyz; }
20};
21
22bool traceRayFirstHit(
23    RaytracingAccelerationStructure sceneBVH,
24    float3 rayOrigin,
25    float3 rayDir,
26    out float t,
27    out int primitiveIndex)
28{
29    RayDesc ray;
30    ray.Origin = rayOrigin;
31    ray.TMin = 0.01f;
32    ray.Direction = rayDir;
33    ray.TMax = 1e4f;
34    RayQuery<RAY_FLAG_SKIP_PROCEDURAL_PRIMITIVES |
35             RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH> q;
36    let rayFlags = RAY_FLAG_SKIP_PROCEDURAL_PRIMITIVES |
37             RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH;
38
39    q.TraceRayInline(
40        sceneBVH,
41        rayFlags,
42        0xff,
43        ray);
44    q.Proceed();
45
46    if(q.CommittedStatus() == COMMITTED_TRIANGLE_HIT)
47    {
48        t = q.CommittedRayT();
49        primitiveIndex = q.CommittedPrimitiveIndex();
50        return true;
51    }
52    primitiveIndex = q.CandidatePrimitiveIndex();
53    unused(t);
54    return false;
55}
56
57bool traceRayNearestHit(
58    RaytracingAccelerationStructure sceneBVH,
59    float3 rayOrigin,
60    float3 rayDir,
61    out float t,
62    out int primitiveIndex)
63{
64    RayDesc ray;
65    ray.Origin = rayOrigin;
66    ray.TMin = 0.01f;
67    ray.Direction = rayDir;
68    ray.TMax = 1e4f;
69    RayQuery<RAY_FLAG_NONE> q;
70    let rayFlags = RAY_FLAG_NONE;
71
72    q.TraceRayInline(
73        sceneBVH,
74        rayFlags,
75        0xff,
76        ray);
77
78    q.Proceed();
79    if(q.CommittedStatus() == COMMITTED_TRIANGLE_HIT)
80    {
81        t = q.CommittedRayT();
82        primitiveIndex = q.CommittedPrimitiveIndex();
83        return true;
84    }
85    primitiveIndex = q.CandidatePrimitiveIndex();
86    unused(t);
87    return false;
88}
89
90[shader("compute")]
91[numthreads(16,16,1)]
92void computeMain(
93    uint3 threadIdx : SV_DispatchThreadID,
94    uniform RWTexture2D resultTexture,
95    uniform RaytracingAccelerationStructure sceneBVH,
96    uniform StructuredBuffer<Primitive> primitiveBuffer,
97    uniform Uniforms uniforms)
98{
99    if (threadIdx.x >= (int)uniforms.screenWidth) return;
100    if (threadIdx.y >= (int)uniforms.screenHeight) return;
101
102    float frameWidth = uniforms.screenWidth / uniforms.screenHeight * uniforms.frameHeight;
103    float imageY = (threadIdx.y / uniforms.screenHeight - 0.5f) * uniforms.frameHeight;
104    float imageX = (threadIdx.x / uniforms.screenWidth - 0.5f) * frameWidth;
105    float imageZ = uniforms.focalLength;
106    float3 rayDir = normalize(uniforms.cameraDir.xyz*imageZ - uniforms.cameraUp.xyz * imageY + uniforms.cameraRight.xyz * imageX);
107
108    float4 resultColor = 0;
109
110    int primitiveIndex = 0;
111    float intersectionT;
112    if (traceRayNearestHit(sceneBVH, uniforms.cameraPosition.xyz, rayDir, intersectionT, primitiveIndex))
113    {
114        float3 hitLocation = uniforms.cameraPosition.xyz + rayDir * intersectionT;
115        float3 shadowRayDir = uniforms.lightDir.xyz;
116        float shadow = 1.0;
117        float shadowIntersectionT;
118        int shadowPrimitiveIndex;
119        if (traceRayFirstHit(sceneBVH, hitLocation, shadowRayDir, shadowIntersectionT, shadowPrimitiveIndex))
120        {
121            shadow = 0.0f;
122        }
123        float3 normal = primitiveBuffer[primitiveIndex].getNormal();
124        float3 color = primitiveBuffer[primitiveIndex].getColor();
125        float ndotl = max(0.0, shadow * dot(normal, uniforms.lightDir.xyz));
126        float intensity = ndotl * 0.7 + 0.3;
127        resultColor = float4(color * intensity, 1.0f);
128    }
129    resultTexture[threadIdx.xy] = resultColor;
130}
131
132/// Vertex and fragment shader for displaying the final image.
133
134[shader("vertex")]
135float4 vertexMain(float2 position : POSITION)
136    : SV_Position
137{
138    return float4(position, 0.5, 1.0);
139}
140
141[shader("fragment")]
142float4 fragmentMain(
143    float4 sv_position : SV_Position,
144    uniform RWTexture2D t)
145    : SV_Target
146{
147    return t.Load(uint2(sv_position.xy));
148}