yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
04ba87e23
master
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}