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
|
vks::initializers::vertexInputAttributeDescription(0, 2, VK_FORMAT_R32G32B32_SFLOAT, offsetof(vkglTF::Vertex, color)), // Location 2: Texture coordinates
|
||||||
// Per-Instance attributes
|
// Per-Instance attributes
|
||||||
// These are fetched for each instance rendered
|
// 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, 3, 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, 4, VK_FORMAT_R32_SFLOAT, offsetof(InstanceData, scale)), // Location 5: Scale
|
||||||
};
|
};
|
||||||
inputState.pVertexBindingDescriptions = bindingDescriptions.data();
|
inputState.pVertexBindingDescriptions = bindingDescriptions.data();
|
||||||
inputState.pVertexAttributeDescriptions = attributeDescriptions.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