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
3.1 KiB108 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
22struct [raypayload] RayPayload
23{
24    float4 color : read(caller) : write(caller, closesthit, miss);
25};
26
27uniform RWTexture2D resultTexture;
28uniform RaytracingAccelerationStructure sceneBVH;
29uniform StructuredBuffer<Primitive> primitiveBuffer;
30uniform Uniforms uniforms;
31
32[shader("raygeneration")]
33void rayGenShader()
34{
35    uint2 threadIdx = DispatchRaysIndex().xy;
36    if (threadIdx.x >= (int)uniforms.screenWidth) return;
37    if (threadIdx.y >= (int)uniforms.screenHeight) return;
38
39    float frameWidth = uniforms.screenWidth / uniforms.screenHeight * uniforms.frameHeight;
40    float imageY = (threadIdx.y / uniforms.screenHeight - 0.5f) * uniforms.frameHeight;
41    float imageX = (threadIdx.x / uniforms.screenWidth - 0.5f) * frameWidth;
42    float imageZ = uniforms.focalLength;
43    float3 rayDir = normalize(uniforms.cameraDir.xyz*imageZ - uniforms.cameraUp.xyz * imageY + uniforms.cameraRight.xyz * imageX);
44
45    // Trace the ray.
46    RayDesc ray;
47    ray.Origin = uniforms.cameraPosition.xyz;
48    ray.Direction = rayDir;
49    ray.TMin = 0.001;
50    ray.TMax = 10000.0;
51    RayPayload payload = { float4(0, 0, 0, 0) };
52    TraceRay(sceneBVH, RAY_FLAG_NONE, ~0, 0, 0, 0, ray, payload);
53
54    resultTexture[threadIdx.xy] = payload.color;
55}
56
57[shader("miss")]
58void missShader(inout RayPayload payload)
59{
60    payload.color = float4(0, 0, 0, 1);
61}
62
63[shader("closesthit")]
64void closestHitShader(inout RayPayload payload, in BuiltInTriangleIntersectionAttributes attr)
65{
66    float3 hitLocation = WorldRayOrigin() + WorldRayDirection() * RayTCurrent();
67    float3 shadowRayDir = uniforms.lightDir.xyz;
68
69    RayDesc ray;
70    ray.Origin = hitLocation;
71    ray.Direction = shadowRayDir;
72    ray.TMin = 0.001;
73    ray.TMax = 10000.0;
74    RayPayload shadowPayload = { float4(0, 0, 0, 0) };
75    TraceRay(sceneBVH, RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH, ~0, 1, 0, 0, ray, shadowPayload);
76    float shadow = 1.0 - shadowPayload.color.x;
77
78    let primitiveIndex = PrimitiveIndex();
79    float3 normal = primitiveBuffer[primitiveIndex].getNormal();
80    float3 color = primitiveBuffer[primitiveIndex].getColor();
81    float ndotl = max(0.0, shadow * dot(normal, uniforms.lightDir.xyz));
82    float intensity = ndotl * 0.7 + 0.3;
83    payload.color = float4(color * intensity, 1.0f);
84}
85
86[shader("closesthit")]
87void shadowRayHitShader(inout RayPayload payload, in BuiltInTriangleIntersectionAttributes attr)
88{
89    payload.color = float4(1.0, 1.0, 1.0, 1.0);
90}
91
92/// Vertex and fragment shader for displaying the final image.
93
94[shader("vertex")]
95float4 vertexMain(float2 position : POSITION)
96    : SV_Position
97{
98    return float4(position, 0.5, 1.0);
99}
100
101[shader("fragment")]
102float4 fragmentMain(
103    float4 sv_position : SV_Position,
104    uniform RWTexture2D t)
105    : SV_Target
106{
107    return t.Load(uint2(sv_position.xy));
108}