Added slang shaders for additional compute samples
This commit is contained in:
parent
80ff4a41d2
commit
829118736f
8 changed files with 460 additions and 2 deletions
|
|
@ -391,8 +391,8 @@ public:
|
|||
vks::initializers::vertexInputAttributeDescription(0, 2, VK_FORMAT_R32G32B32_SFLOAT, offsetof(vkglTF::Vertex, color)), // Location 2: Texture coordinates
|
||||
// Per-Instance attributes
|
||||
// These are fetched for each instance rendered
|
||||
vks::initializers::vertexInputAttributeDescription(1, 4, VK_FORMAT_R32G32B32_SFLOAT, offsetof(InstanceData, pos)), // Location 4: Position
|
||||
vks::initializers::vertexInputAttributeDescription(1, 5, VK_FORMAT_R32_SFLOAT, offsetof(InstanceData, scale)), // Location 5: Scale
|
||||
vks::initializers::vertexInputAttributeDescription(1, 3, VK_FORMAT_R32G32B32_SFLOAT, offsetof(InstanceData, pos)), // Location 4: Position
|
||||
vks::initializers::vertexInputAttributeDescription(1, 4, VK_FORMAT_R32_SFLOAT, offsetof(InstanceData, scale)), // Location 5: Scale
|
||||
};
|
||||
inputState.pVertexBindingDescriptions = bindingDescriptions.data();
|
||||
inputState.pVertexAttributeDescriptions = attributeDescriptions.data();
|
||||
|
|
|
|||
258
shaders/slang/computeraytracing/raytracing.slang
Normal file
258
shaders/slang/computeraytracing/raytracing.slang
Normal file
|
|
@ -0,0 +1,258 @@
|
|||
/* Copyright (c) 2025, Sascha Willems
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
// Shader is looseley based on the ray tracing coding session by Inigo Quilez (www.iquilezles.org)
|
||||
|
||||
#define EPSILON 0.0001
|
||||
#define MAXLEN 1000.0
|
||||
#define SHADOW 0.5
|
||||
#define RAYBOUNCES 2
|
||||
#define REFLECTIONS true
|
||||
#define REFLECTIONSTRENGTH 0.4
|
||||
#define REFLECTIONFALLOFF 0.5
|
||||
|
||||
#define SceneObjectTypeSphere 0
|
||||
#define SceneObjectTypePlane 1
|
||||
|
||||
RWTexture2D<float4> resultImage;
|
||||
|
||||
struct Camera
|
||||
{
|
||||
float3 pos;
|
||||
float3 lookat;
|
||||
float fov;
|
||||
};
|
||||
|
||||
struct UBO
|
||||
{
|
||||
float3 lightPos;
|
||||
float aspectRatio;
|
||||
float4 fogColor;
|
||||
Camera camera;
|
||||
float4x4 rotMat;
|
||||
};
|
||||
ConstantBuffer<UBO> ubo;
|
||||
|
||||
struct SceneObject
|
||||
{
|
||||
float4 objectProperties;
|
||||
float3 diffuse;
|
||||
float specular;
|
||||
int id;
|
||||
int objectType;
|
||||
};
|
||||
StructuredBuffer<SceneObject> sceneObjects;
|
||||
|
||||
void reflectRay(inout float3 rayD, in float3 mormal)
|
||||
{
|
||||
rayD = rayD + 2.0 * -dot(mormal, rayD) * mormal;
|
||||
}
|
||||
|
||||
// Lighting =========================================================
|
||||
|
||||
float lightDiffuse(float3 normal, float3 lightDir)
|
||||
{
|
||||
return clamp(dot(normal, lightDir), 0.1, 1.0);
|
||||
}
|
||||
|
||||
float lightSpecular(float3 normal, float3 lightDir, float specularFactor)
|
||||
{
|
||||
float3 viewVec = normalize(ubo.camera.pos);
|
||||
float3 halfVec = normalize(lightDir + viewVec);
|
||||
return pow(clamp(dot(normal, halfVec), 0.0, 1.0), specularFactor);
|
||||
}
|
||||
|
||||
// Sphere ===========================================================
|
||||
|
||||
float sphereIntersect(in float3 rayO, in float3 rayD, in SceneObject sphere)
|
||||
{
|
||||
float3 oc = rayO - sphere.objectProperties.xyz;
|
||||
float b = 2.0 * dot(oc, rayD);
|
||||
float c = dot(oc, oc) - sphere.objectProperties.w * sphere.objectProperties.w;
|
||||
float h = b*b - 4.0*c;
|
||||
if (h < 0.0)
|
||||
{
|
||||
return -1.0;
|
||||
}
|
||||
float t = (-b - sqrt(h)) / 2.0;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
float3 sphereNormal(in float3 pos, in SceneObject sphere)
|
||||
{
|
||||
return (pos - sphere.objectProperties.xyz) / sphere.objectProperties.w;
|
||||
}
|
||||
|
||||
// Plane ===========================================================
|
||||
|
||||
float planeIntersect(float3 rayO, float3 rayD, SceneObject plane)
|
||||
{
|
||||
float d = dot(rayD, plane.objectProperties.xyz);
|
||||
|
||||
if (d == 0.0)
|
||||
return 0.0;
|
||||
|
||||
float t = -(plane.objectProperties.w + dot(rayO, plane.objectProperties.xyz)) / d;
|
||||
|
||||
if (t < 0.0)
|
||||
return 0.0;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
int intersect(in float3 rayO, in float3 rayD, inout float resT)
|
||||
{
|
||||
int id = -1;
|
||||
float t = MAXLEN;
|
||||
|
||||
uint sceneObjectsLength;
|
||||
uint sceneObjectsStride;
|
||||
sceneObjects.GetDimensions(sceneObjectsLength, sceneObjectsStride);
|
||||
|
||||
for (int i = 0; i < sceneObjectsLength; i++) {
|
||||
// Sphere
|
||||
if (sceneObjects[i].objectType == SceneObjectTypeSphere) {
|
||||
t = sphereIntersect(rayO, rayD, sceneObjects[i]);
|
||||
}
|
||||
// Plane
|
||||
if (sceneObjects[i].objectType == SceneObjectTypePlane) {
|
||||
t = planeIntersect(rayO, rayD, sceneObjects[i]);
|
||||
}
|
||||
if ((t > EPSILON) && (t < resT))
|
||||
{
|
||||
id = sceneObjects[i].id;
|
||||
resT = t;
|
||||
}
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
float calcShadow(in float3 rayO, in float3 rayD, in int objectId, inout float t)
|
||||
{
|
||||
uint sceneObjectsLength;
|
||||
uint sceneObjectsStride;
|
||||
sceneObjects.GetDimensions(sceneObjectsLength, sceneObjectsStride);
|
||||
|
||||
for (int i = 0; i < sceneObjectsLength; i++) {
|
||||
if (sceneObjects[i].id == objectId)
|
||||
continue;
|
||||
|
||||
float tLoc = MAXLEN;
|
||||
|
||||
// Sphere
|
||||
if (sceneObjects[i].objectType == SceneObjectTypeSphere)
|
||||
{
|
||||
tLoc = sphereIntersect(rayO, rayD, sceneObjects[i]);
|
||||
}
|
||||
// Plane
|
||||
if (sceneObjects[i].objectType == SceneObjectTypePlane)
|
||||
{
|
||||
tLoc = planeIntersect(rayO, rayD, sceneObjects[i]);
|
||||
}
|
||||
if ((tLoc > EPSILON) && (tLoc < t))
|
||||
{
|
||||
t = tLoc;
|
||||
return SHADOW;
|
||||
}
|
||||
}
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
float3 fog(in float t, in float3 color)
|
||||
{
|
||||
return lerp(color, ubo.fogColor.rgb, clamp(sqrt(t*t)/20.0, 0.0, 1.0));
|
||||
}
|
||||
|
||||
float3 renderScene(inout float3 rayO, inout float3 rayD, inout int id)
|
||||
{
|
||||
float3 color = float3(0, 0, 0);
|
||||
float t = MAXLEN;
|
||||
|
||||
// Get intersected object ID
|
||||
int objectID = intersect(rayO, rayD, t);
|
||||
|
||||
if (objectID == -1)
|
||||
{
|
||||
return color;
|
||||
}
|
||||
|
||||
float3 pos = rayO + t * rayD;
|
||||
float3 lightVec = normalize(ubo.lightPos - pos);
|
||||
float3 normal;
|
||||
|
||||
uint sceneObjectsLength;
|
||||
uint sceneObjectsStride;
|
||||
sceneObjects.GetDimensions(sceneObjectsLength, sceneObjectsStride);
|
||||
|
||||
for (int i = 0; i < sceneObjectsLength; i++) {
|
||||
if (objectID == sceneObjects[i].id)
|
||||
{
|
||||
// Sphere
|
||||
if (sceneObjects[i].objectType == SceneObjectTypeSphere) {
|
||||
normal = sphereNormal(pos, sceneObjects[i]);
|
||||
}
|
||||
// Plane
|
||||
if (sceneObjects[i].objectType == SceneObjectTypePlane) {
|
||||
normal = sceneObjects[i].objectProperties.xyz;
|
||||
}
|
||||
// Lighting
|
||||
float diffuse = lightDiffuse(normal, lightVec);
|
||||
float specular = lightSpecular(normal, lightVec, sceneObjects[i].specular);
|
||||
color = diffuse * sceneObjects[i].diffuse + specular;
|
||||
}
|
||||
}
|
||||
|
||||
if (id == -1)
|
||||
return color;
|
||||
|
||||
id = objectID;
|
||||
|
||||
// Shadows
|
||||
t = length(ubo.lightPos - pos);
|
||||
color *= calcShadow(pos, lightVec, id, t);
|
||||
|
||||
// Fog
|
||||
color = fog(t, color);
|
||||
|
||||
// Reflect ray for next render pass
|
||||
reflectRay(rayD, normal);
|
||||
rayO = pos;
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
[shader("compute")]
|
||||
[numthreads(16, 16, 1)]
|
||||
void computeMain(uint3 GlobalInvocationID : SV_DispatchThreadID)
|
||||
{
|
||||
int2 dim;
|
||||
resultImage.GetDimensions(dim.x, dim.y);
|
||||
float2 uv = float2(GlobalInvocationID.xy) / dim;
|
||||
|
||||
float3 rayO = ubo.camera.pos;
|
||||
float3 rayD = normalize(float3((-1.0 + 2.0 * uv) * float2(ubo.aspectRatio, 1.0), -1.0));
|
||||
|
||||
// Basic color path
|
||||
int id = 0;
|
||||
float3 finalColor = renderScene(rayO, rayD, id);
|
||||
|
||||
// Reflection
|
||||
if (REFLECTIONS)
|
||||
{
|
||||
float reflectionStrength = REFLECTIONSTRENGTH;
|
||||
for (int i = 0; i < RAYBOUNCES; i++)
|
||||
{
|
||||
float3 reflectionColor = renderScene(rayO, rayD, id);
|
||||
finalColor = (1.0 - reflectionStrength) * finalColor + reflectionStrength * lerp(reflectionColor, finalColor, 1.0 - reflectionStrength);
|
||||
reflectionStrength *= REFLECTIONFALLOFF;
|
||||
}
|
||||
}
|
||||
|
||||
resultImage[int2(GlobalInvocationID.xy)] = float4(finalColor, 0.0);
|
||||
}
|
||||
28
shaders/slang/computeraytracing/texture.slang
Normal file
28
shaders/slang/computeraytracing/texture.slang
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/* Copyright (c) 2025, Sascha Willems
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
struct VSOutput
|
||||
{
|
||||
float4 Pos : SV_POSITION;
|
||||
float2 UV;
|
||||
};
|
||||
|
||||
Sampler2D samplerColor;
|
||||
|
||||
[shader("vertex")]
|
||||
VSOutput vertexMain(uint VertexIndex: SV_VertexID)
|
||||
{
|
||||
VSOutput output;
|
||||
output.UV = float2((VertexIndex << 1) & 2, VertexIndex & 2);
|
||||
output.Pos = float4(output.UV * 2.0f + -1.0f, 0.0f, 1.0f);
|
||||
return output;
|
||||
}
|
||||
|
||||
[shader("fragment")]
|
||||
float4 fragmentMain(VSOutput input)
|
||||
{
|
||||
return samplerColor.Sample(float2(input.UV.x, 1.0 - input.UV.y));
|
||||
}
|
||||
34
shaders/slang/computeshader/edgedetect.slang
Normal file
34
shaders/slang/computeshader/edgedetect.slang
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/* Copyright (c) 2025, Sascha Willems
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
import shared;
|
||||
|
||||
[shader("compute")]
|
||||
[numthreads(16, 16, 1)]
|
||||
void computeMain(uint3 GlobalInvocationID : SV_DispatchThreadID)
|
||||
{
|
||||
float imageData[9];
|
||||
// Fetch neighbouring texels
|
||||
int n = -1;
|
||||
for (int i=-1; i<2; ++i)
|
||||
{
|
||||
for(int j=-1; j<2; ++j)
|
||||
{
|
||||
n++;
|
||||
float3 rgb = inputImage[uint2(GlobalInvocationID.x + i, GlobalInvocationID.y + j)].rgb;
|
||||
imageData[n] = (rgb.r + rgb.g + rgb.b) / 3.0;
|
||||
}
|
||||
}
|
||||
|
||||
float kernel[9];
|
||||
kernel[0] = -1.0/8.0; kernel[1] = -1.0/8.0; kernel[2] = -1.0/8.0;
|
||||
kernel[3] = -1.0/8.0; kernel[4] = 1.0; kernel[5] = -1.0/8.0;
|
||||
kernel[6] = -1.0/8.0; kernel[7] = -1.0/8.0; kernel[8] = -1.0/8.0;
|
||||
|
||||
float4 res = float4(conv(kernel, imageData, 0.1, 0.0).xxx, 1.0);
|
||||
|
||||
resultImage[int2(GlobalInvocationID.xy)] = res;
|
||||
}
|
||||
34
shaders/slang/computeshader/emboss.slang
Normal file
34
shaders/slang/computeshader/emboss.slang
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/* Copyright (c) 2025, Sascha Willems
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
import shared;
|
||||
|
||||
[shader("compute")]
|
||||
[numthreads(16, 16, 1)]
|
||||
void computeMain(uint3 GlobalInvocationID : SV_DispatchThreadID)
|
||||
{
|
||||
float imageData[9];
|
||||
// Fetch neighbouring texels
|
||||
int n = -1;
|
||||
for (int i=-1; i<2; ++i)
|
||||
{
|
||||
for(int j=-1; j<2; ++j)
|
||||
{
|
||||
n++;
|
||||
float3 rgb = inputImage[uint2(GlobalInvocationID.x + i, GlobalInvocationID.y + j)].rgb;
|
||||
imageData[n] = (rgb.r + rgb.g + rgb.b) / 3.0;
|
||||
}
|
||||
}
|
||||
|
||||
float kernel[9];
|
||||
kernel[0] = -1.0; kernel[1] = 0.0; kernel[2] = 0.0;
|
||||
kernel[3] = 0.0; kernel[4] = -1.0; kernel[5] = 0.0;
|
||||
kernel[6] = 0.0; kernel[7] = 0.0; kernel[8] = 2.0;
|
||||
|
||||
float4 res = float4(conv(kernel, imageData, 1.0, 0.50).xxx, 1.0);
|
||||
|
||||
resultImage[int2(GlobalInvocationID.xy)] = res;
|
||||
}
|
||||
20
shaders/slang/computeshader/shared.slang
Normal file
20
shaders/slang/computeshader/shared.slang
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/* Copyright (c) 2025, Sascha Willems
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
module shared;
|
||||
|
||||
public Texture2D inputImage;
|
||||
public RWTexture2D<float4> resultImage;
|
||||
|
||||
public float conv(in float kernel[9], in float data[9], in float denom, in float offset)
|
||||
{
|
||||
float res = 0.0;
|
||||
for (int i=0; i<9; ++i)
|
||||
{
|
||||
res += kernel[i] * data[i];
|
||||
}
|
||||
return saturate(res/denom + offset);
|
||||
}
|
||||
43
shaders/slang/computeshader/sharpen.slang
Normal file
43
shaders/slang/computeshader/sharpen.slang
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/* Copyright (c) 2025, Sascha Willems
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
import shared;
|
||||
|
||||
[shader("compute")]
|
||||
[numthreads(16, 16, 1)]
|
||||
void computeMain(uint3 GlobalInvocationID : SV_DispatchThreadID)
|
||||
{
|
||||
float r[9];
|
||||
float g[9];
|
||||
float b[9];
|
||||
|
||||
// Fetch neighbouring texels
|
||||
int n = -1;
|
||||
for (int i=-1; i<2; ++i)
|
||||
{
|
||||
for(int j=-1; j<2; ++j)
|
||||
{
|
||||
n++;
|
||||
float3 rgb = inputImage[uint2(GlobalInvocationID.x + i, GlobalInvocationID.y + j)].rgb;
|
||||
r[n] = rgb.r;
|
||||
g[n] = rgb.g;
|
||||
b[n] = rgb.b;
|
||||
}
|
||||
}
|
||||
|
||||
float kernel[9];
|
||||
kernel[0] = -1.0; kernel[1] = -1.0; kernel[2] = -1.0;
|
||||
kernel[3] = -1.0; kernel[4] = 9.0; kernel[5] = -1.0;
|
||||
kernel[6] = -1.0; kernel[7] = -1.0; kernel[8] = -1.0;
|
||||
|
||||
float4 res = float4(
|
||||
conv(kernel, r, 1.0, 0.0),
|
||||
conv(kernel, g, 1.0, 0.0),
|
||||
conv(kernel, b, 1.0, 0.0),
|
||||
1.0);
|
||||
|
||||
resultImage[int2(GlobalInvocationID.xy)] = res;
|
||||
}
|
||||
41
shaders/slang/computeshader/texture.slang
Normal file
41
shaders/slang/computeshader/texture.slang
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/* Copyright (c) 2025, Sascha Willems
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
struct VSInput
|
||||
{
|
||||
float3 Pos;
|
||||
float2 UV;
|
||||
};
|
||||
|
||||
struct VSOutput
|
||||
{
|
||||
float4 Pos : SV_POSITION;
|
||||
float2 UV;
|
||||
};
|
||||
|
||||
struct UBO
|
||||
{
|
||||
float4x4 projection;
|
||||
float4x4 model;
|
||||
};
|
||||
ConstantBuffer<UBO> ubo;
|
||||
|
||||
Sampler2D samplerColor;
|
||||
|
||||
[shader("vertex")]
|
||||
VSOutput vertexMain(VSInput input)
|
||||
{
|
||||
VSOutput output;
|
||||
output.UV = input.UV;
|
||||
output.Pos = mul(ubo.projection, mul(ubo.model, float4(input.Pos.xyz, 1.0)));
|
||||
return output;
|
||||
}
|
||||
|
||||
[shader("fragment")]
|
||||
float4 fragmentMain(VSOutput input)
|
||||
{
|
||||
return samplerColor.Sample(input.UV);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue