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 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}