Ajout de Jolt Physics + 1ere version des factory entitecomposants - camera, transform, rigidbody, collider, renderer

This commit is contained in:
Tom Ray
2026-03-22 00:28:03 +01:00
parent 6695d46bcd
commit 48348936a8
1147 changed files with 214331 additions and 353 deletions

View File

@@ -0,0 +1,27 @@
Texture2D ShaderTexture : register(t2);
SamplerState SampleType : register(s0);
struct PS_INPUT
{
float4 Position : SV_POSITION;
float2 Tex : TEXCOORD0;
float4 Color : COLOR0;
};
struct PS_OUTPUT
{
float4 RGBColor : SV_TARGET;
};
PS_OUTPUT main(PS_INPUT In)
{
PS_OUTPUT Output;
float t = ShaderTexture.Sample(SampleType, In.Tex).r;
if (t < 0.5)
discard;
Output.RGBColor = float4(In.Color.rgb, t);
return Output;
}

View File

@@ -0,0 +1,35 @@
#include "VertexConstants.h"
struct VS_INPUT
{
float3 vPos : POSITION;
float2 vTex : TEXCOORD0;
float4 vCol : COLOR;
};
struct VS_OUTPUT
{
float4 Position : SV_POSITION;
float2 Tex : TEXCOORD0;
float4 Color : COLOR0;
};
VS_OUTPUT main(VS_INPUT input)
{
VS_OUTPUT Output;
float4 pos = float4(input.vPos, 1.0f);
// Transform the position from object space to homogeneous projection space
pos = mul(View, pos);
pos = mul(Projection, pos);
Output.Position = pos;
// Output texture coordinates
Output.Tex = input.vTex;
// Output color
Output.Color = input.vCol;
return Output;
}

View File

@@ -0,0 +1,19 @@
struct PS_INPUT
{
float4 Position : SV_POSITION;
float4 Color : COLOR0;
};
struct PS_OUTPUT
{
float4 RGBColor : SV_TARGET;
};
PS_OUTPUT main(PS_INPUT In)
{
PS_OUTPUT Output;
Output.RGBColor = In.Color;
return Output;
}

View File

@@ -0,0 +1,30 @@
#include "VertexConstants.h"
struct VS_INPUT
{
float3 vPos : POSITION;
float3 vColor : COLOR;
};
struct VS_OUTPUT
{
float4 Position : SV_POSITION;
float4 Color : COLOR0;
};
VS_OUTPUT main(VS_INPUT input)
{
VS_OUTPUT Output;
float4 pos = float4(input.vPos, 1.0f);
// Transform the position from object space to homogeneous projection space
pos = mul(View, pos);
pos = mul(Projection, pos);
Output.Position = pos;
// Output color
Output.Color = float4(input.vColor, 1.0f);
return Output;
}

View File

@@ -0,0 +1,4 @@
// We only write depth, so this shader does nothing
void main()
{
}

View File

@@ -0,0 +1,43 @@
#include "VertexConstants.h"
struct VS_INPUT
{
// Per vertex data
float3 vPos : POSITION;
float3 vNorm : NORMAL;
float2 vTex : TEXCOORD0;
float4 vCol : COLOR;
// Per instance data
matrix iModel : INSTANCE_TRANSFORM; // model matrix
matrix iModelInvTrans : INSTANCE_INV_TRANSFORM; // (model matrix^-1)^T
float4 iCol : INSTANCE_COLOR; // color of the model
};
struct VS_OUTPUT
{
float4 Position : SV_POSITION;
};
VS_OUTPUT main(VS_INPUT input)
{
VS_OUTPUT output;
// Check if the alpha = 0
if (input.vCol.a * input.iCol.a == 0.0)
{
// Don't draw the triangle by moving it to an invalid location
output.Position = float4(0, 0, 0, 0);
}
else
{
// Transform the position from world space to homogeneous projection space for the light
float4 pos = float4(input.vPos, 1.0f);
pos = mul(input.iModel, pos);
pos = mul(LightView, pos);
pos = mul(LightProjection, pos);
output.Position = pos;
}
return output;
}

View File

@@ -0,0 +1,121 @@
// Shader that uses a shadow map for rendering shadows, see:
// http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-16-shadow-mapping/
// https://takinginitiative.wordpress.com/2011/05/25/directx10-tutorial-10-shadow-mapping-part-2/
Texture2D LightDepthTexture : register(t2);
SamplerComparisonState LightDepthSampler : register(s2);
cbuffer PixelShaderConstantBuffer : register(b1)
{
float3 CameraPos;
float3 LightPos;
};
struct PS_INPUT
{
float4 Position : SV_POSITION; // interpolated vertex position
float3 Normal : TEXCOORD0;
float3 WorldPos : TEXCOORD1;
float2 Tex : TEXCOORD2;
float4 PositionL : TEXCOORD3; // interpolated vertex position in light space
float4 Color : COLOR0;
};
struct PS_OUTPUT
{
float4 RGBColor : SV_TARGET;
};
PS_OUTPUT main(PS_INPUT input)
{
// Constants
float AmbientFactor = 0.3;
float3 DiffuseColor = float3(input.Color.r, input.Color.g, input.Color.b);
float3 SpecularColor = float3(1, 1, 1);
float SpecularPower = 100.0;
float bias = 1.0e-7;
// Homogenize position in light space
input.PositionL.xyz /= input.PositionL.w;
// Calculate dot product between direction to light and surface normal and clamp between [0, 1]
float3 view_dir = normalize(CameraPos - input.WorldPos);
float3 world_to_light = LightPos - input.WorldPos;
float3 light_dir = normalize(world_to_light);
float3 normal = normalize(input.Normal);
if (dot(view_dir, normal) < 0) // If we're viewing the triangle from the back side, flip the normal to get the correct lighting
normal = -normal;
float normal_dot_light_dir = saturate(dot(normal, light_dir));
// Calculate texture coordinates in light depth texture
float2 tex_coord;
tex_coord.x = input.PositionL.x / 2.0 + 0.5;
tex_coord.y = -input.PositionL.y / 2.0 + 0.5;
// Check that the texture coordinate is inside the depth texture, if not we don't know if it is lit or not so we assume lit
float shadow_factor = 1.0;
if (input.Color.a > 0 // Alpha = 0 means don't receive shadows
&& tex_coord.x == saturate(tex_coord.x) && tex_coord.y == saturate(tex_coord.y))
{
// Modify shadow bias according to the angle between the normal and the light dir
float modified_bias = bias * tan(acos(normal_dot_light_dir));
modified_bias = min(modified_bias, 10.0 * bias);
// Get texture size
float width, height, levels;
LightDepthTexture.GetDimensions(0, width, height, levels);
width = 1.0 / width;
height = 1.0 / height;
// Samples to take
uint num_samples = 16;
float2 offsets[] = {
float2(-1.5 * width, -1.5 * height),
float2(-0.5 * width, -1.5 * height),
float2(0.5 * width, -1.5 * height),
float2(1.5 * width, -1.5 * height),
float2(-1.5 * width, -0.5 * height),
float2(-0.5 * width, -0.5 * height),
float2(0.5 * width, -0.5 * height),
float2(1.5 * width, -0.5 * height),
float2(-1.5 * width, 0.5 * height),
float2(-0.5 * width, 0.5 * height),
float2(0.5 * width, 0.5 * height),
float2(1.5 * width, 0.5 * height),
float2(-1.5 * width, 1.5 * height),
float2(-0.5 * width, 1.5 * height),
float2(0.5 * width, 1.5 * height),
float2(1.5 * width, 1.5 * height),
};
// Calculate depth of this pixel relative to the light
float light_depth = input.PositionL.z + modified_bias;
// Sample shadow factor
shadow_factor = 0.0;
[unroll] for (uint i = 0; i < num_samples; ++i)
shadow_factor += LightDepthTexture.SampleCmp(LightDepthSampler, tex_coord + offsets[i], light_depth);
shadow_factor /= num_samples;
}
// Calculate diffuse and specular
float diffuse = normal_dot_light_dir;
float specular = diffuse > 0.0? pow(saturate(-dot(reflect(light_dir, normal), view_dir)), SpecularPower) : 0.0;
// Apply procedural pattern based on the uv coordinates
bool2 less_half = input.Tex - floor(input.Tex) < float2(0.5, 0.5);
float darken_factor = less_half.r ^ less_half.g? 0.5 : 1.0;
// Fade out checkerboard pattern when it tiles too often
float2 dx = ddx(input.Tex), dy = ddy(input.Tex);
float texel_distance = sqrt(dot(dx, dx) + dot(dy, dy));
darken_factor = lerp(darken_factor, 0.75, clamp(5.0 * texel_distance - 1.5, 0.0, 1.0));
// Calculate color
PS_OUTPUT output;
output.RGBColor = float4(saturate((AmbientFactor + diffuse * shadow_factor) * darken_factor * DiffuseColor + SpecularColor * specular * shadow_factor), 1);
return output;
}

View File

@@ -0,0 +1,59 @@
#include "VertexConstants.h"
struct VS_INPUT
{
// Per vertex data
float3 vPos : POSITION;
float3 vNorm : NORMAL;
float2 vTex : TEXCOORD0;
float4 vCol : COLOR;
// Per instance data
matrix iModel : INSTANCE_TRANSFORM; // model matrix
matrix iModelInvTrans : INSTANCE_INV_TRANSFORM; // (model matrix^-1)^T
float4 iCol : INSTANCE_COLOR; // color of the model
};
struct VS_OUTPUT
{
float4 Position : SV_POSITION;
float3 Normal : TEXCOORD0;
float3 WorldPos : TEXCOORD1;
float2 Tex : TEXCOORD2;
float4 PositionL : TEXCOORD3;
float4 Color : COLOR0;
};
VS_OUTPUT main(VS_INPUT input)
{
VS_OUTPUT output;
// Get world position
float4 pos = float4(input.vPos, 1.0f);
float4 world_pos = mul(input.iModel, pos);
// Transform the position from world space to homogeneous projection space
float4 proj_pos = mul(View, world_pos);
proj_pos = mul(Projection, proj_pos);
output.Position = proj_pos;
// Transform the position from world space to projection space of the light
float4 proj_lpos = mul(LightView, world_pos);
proj_lpos = mul(LightProjection, proj_lpos);
output.PositionL = proj_lpos;
// output normal
float4 norm = float4(input.vNorm, 0.0f);
output.Normal = normalize(mul(input.iModelInvTrans, norm).xyz);
// output world position of the vertex
output.WorldPos = world_pos.xyz;
// output texture coordinates
output.Tex = input.vTex;
// output color
output.Color = input.vCol * input.iCol;
return output;
}

View File

@@ -0,0 +1,23 @@
Texture2D ShaderTexture : register(t2);
SamplerState SampleType : register(s1);
struct PS_INPUT
{
float4 Position : SV_POSITION;
float2 Tex : TEXCOORD0;
float4 Color : COLOR0;
};
struct PS_OUTPUT
{
float4 RGBColor : SV_TARGET;
};
PS_OUTPUT main(PS_INPUT In)
{
PS_OUTPUT Output;
Output.RGBColor = In.Color * ShaderTexture.Sample(SampleType, In.Tex);
return Output;
}

View File

@@ -0,0 +1,20 @@
struct PS_INPUT
{
float4 Position : SV_POSITION;
float2 Tex : TEXCOORD0;
float4 Color : COLOR0;
};
struct PS_OUTPUT
{
float4 RGBColor : SV_TARGET;
};
PS_OUTPUT main(PS_INPUT In)
{
PS_OUTPUT Output;
Output.RGBColor = In.Color;
return Output;
}

View File

@@ -0,0 +1,34 @@
#include "VertexConstants.h"
struct VS_INPUT
{
float3 vPos : POSITION;
float2 vTex : TEXCOORD0;
float4 vCol : COLOR;
};
struct VS_OUTPUT
{
float4 Position : SV_POSITION;
float2 Tex : TEXCOORD0;
float4 Color : COLOR0;
};
VS_OUTPUT main(VS_INPUT input)
{
VS_OUTPUT Output;
float4 pos = float4(input.vPos, 1.0f);
// Transform the position from object space to ortho space
pos = mul(Projection, pos);
Output.Position = pos;
// Output texture coordinates
Output.Tex = input.vTex;
// Output color
Output.Color = input.vCol;
return Output;
}

View File

@@ -0,0 +1,7 @@
cbuffer VertexShaderConstantBuffer : register(b0)
{
matrix View; // view matrix
matrix Projection; // projection matrix
matrix LightView; // view matrix of the light
matrix LightProjection; // projection matrix of the light
};

View File

@@ -0,0 +1,39 @@
#include <metal_stdlib>
using namespace metal;
#include "VertexConstants.h"
constexpr sampler alphaTextureSampler(mag_filter::linear, min_filter::linear);
struct FontVertex
{
float3 vPos [[attribute(0)]];
float2 vTex [[attribute(1)]];
uchar4 vCol [[attribute(2)]];
};
struct FontOut
{
float4 oPosition [[position]];
float2 oTex;
float4 oColor;
};
vertex FontOut FontVertexShader(FontVertex vert [[stage_in]], constant VertexShaderConstantBuffer *constants [[buffer(2)]])
{
FontOut out;
out.oPosition = constants->Projection * constants->View * float4(vert.vPos, 1.0);
out.oTex = vert.vTex;
out.oColor = float4(vert.vCol) / 255.0;
return out;
}
fragment float4 FontPixelShader(FontOut in [[stage_in]], texture2d<float> alphaTexture [[texture(0)]])
{
const float4 sample = alphaTexture.sample(alphaTextureSampler, in.oTex);
if (sample.x < 0.5)
discard_fragment();
return float4(in.oColor.xyz, sample.x);
}

View File

@@ -0,0 +1,30 @@
#include <metal_stdlib>
using namespace metal;
#include "VertexConstants.h"
struct LineVertex
{
float3 iPosition [[attribute(0)]];
uchar4 iColor [[attribute(1)]];
};
struct LineOut
{
float4 oPosition [[position]];
float4 oColor;
};
vertex LineOut LineVertexShader(LineVertex vert [[stage_in]], constant VertexShaderConstantBuffer *constants [[buffer(2)]])
{
LineOut out;
out.oPosition = constants->Projection * constants->View * float4(vert.iPosition, 1.0);
out.oColor = float4(vert.iColor) / 255.0;
return out;
}
fragment float4 LinePixelShader(LineOut in [[stage_in]])
{
return in.oColor;
}

View File

@@ -0,0 +1,199 @@
#include <metal_stdlib>
using namespace metal;
#include "VertexConstants.h"
constexpr sampler depthSampler(mag_filter::nearest, min_filter::nearest);
struct Vertex
{
float3 vPos [[attribute(0)]];
float3 vNorm [[attribute(1)]];
float2 vTex [[attribute(2)]];
uchar4 vCol [[attribute(3)]];
float4 iModel0 [[attribute(4)]];
float4 iModel1 [[attribute(5)]];
float4 iModel2 [[attribute(6)]];
float4 iModel3 [[attribute(7)]];
float4 iModelInvTrans0 [[attribute(8)]];
float4 iModelInvTrans1 [[attribute(9)]];
float4 iModelInvTrans2 [[attribute(10)]];
float4 iModelInvTrans3 [[attribute(11)]];
uchar4 iCol [[attribute(12)]];
};
struct TriangleOut
{
float4 oPosition [[position]];
float3 oNormal;
float3 oWorldPos;
float2 oTex;
float4 oPositionL;
float4 oColor;
};
vertex TriangleOut TriangleVertexShader(Vertex vert [[stage_in]], constant VertexShaderConstantBuffer *constants [[buffer(2)]])
{
TriangleOut out;
// Convert input matrices
float4x4 iModel(vert.iModel0, vert.iModel1, vert.iModel2, vert.iModel3);
float4x4 iModelInvTrans(vert.iModelInvTrans0, vert.iModelInvTrans1, vert.iModelInvTrans2, vert.iModelInvTrans3);
// Get world position
float4 pos = float4(vert.vPos, 1.0f);
float4 world_pos = iModel * pos;
// Transform the position from world space to homogeneous projection space
float4 proj_pos = constants->View * world_pos;
proj_pos = constants->Projection * proj_pos;
out.oPosition = proj_pos;
// Transform the position from world space to projection space of the light
float4 proj_lpos = constants->LightView * world_pos;
proj_lpos = constants->LightProjection * proj_lpos;
out.oPositionL = proj_lpos;
// output normal
float4 norm = float4(vert.vNorm, 0.0f);
out.oNormal = normalize(iModelInvTrans * norm).xyz;
// output world position of the vertex
out.oWorldPos = world_pos.xyz;
// output texture coordinates
out.oTex = vert.vTex;
// output color
out.oColor = float4(vert.vCol) * float4(vert.iCol) / (255.0 * 255.0);
return out;
}
fragment float4 TrianglePixelShader(TriangleOut vert [[stage_in]], constant PixelShaderConstantBuffer *constants, texture2d<float> depthTexture [[texture(0)]])
{
// Constants
float AmbientFactor = 0.3;
float3 DiffuseColor = float3(vert.oColor.r, vert.oColor.g, vert.oColor.b);
float3 SpecularColor = float3(1, 1, 1);
float SpecularPower = 100.0;
float bias = 1.0e-7;
// Homogenize position in light space
float3 position_l = vert.oPositionL.xyz / vert.oPositionL.w;
// Calculate dot product between direction to light and surface normal and clamp between [0, 1]
float3 view_dir = normalize(constants->CameraPos - vert.oWorldPos);
float3 world_to_light = constants->LightPos - vert.oWorldPos;
float3 light_dir = normalize(world_to_light);
float3 normal = normalize(vert.oNormal);
if (dot(view_dir, normal) < 0) // If we're viewing the triangle from the back side, flip the normal to get the correct lighting
normal = -normal;
float normal_dot_light_dir = clamp(dot(normal, light_dir), 0.0, 1.0);
// Calculate texture coordinates in light depth texture
float2 tex_coord;
tex_coord.x = position_l.x / 2.0 + 0.5;
tex_coord.y = -position_l.y / 2.0 + 0.5;
// Check that the texture coordinate is inside the depth texture, if not we don't know if it is lit or not so we assume lit
float shadow_factor = 1.0;
if (vert.oColor.a > 0 // Alpha = 0 means don't receive shadows
&& tex_coord.x == clamp(tex_coord.x, 0.0, 1.0) && tex_coord.y == clamp(tex_coord.y, 0.0, 1.0))
{
// Modify shadow bias according to the angle between the normal and the light dir
float modified_bias = bias * tan(acos(normal_dot_light_dir));
modified_bias = min(modified_bias, 10.0 * bias);
// Get texture size
float width = 1.0 / 4096;
float height = 1.0 / 4096;
// Samples to take
uint num_samples = 16;
float2 offsets[] = {
float2(-1.5 * width, -1.5 * height),
float2(-0.5 * width, -1.5 * height),
float2(0.5 * width, -1.5 * height),
float2(1.5 * width, -1.5 * height),
float2(-1.5 * width, -0.5 * height),
float2(-0.5 * width, -0.5 * height),
float2(0.5 * width, -0.5 * height),
float2(1.5 * width, -0.5 * height),
float2(-1.5 * width, 0.5 * height),
float2(-0.5 * width, 0.5 * height),
float2(0.5 * width, 0.5 * height),
float2(1.5 * width, 0.5 * height),
float2(-1.5 * width, 1.5 * height),
float2(-0.5 * width, 1.5 * height),
float2(0.5 * width, 1.5 * height),
float2(1.5 * width, 1.5 * height),
};
// Calculate depth of this pixel relative to the light
float light_depth = position_l.z + modified_bias;
// Sample shadow factor
shadow_factor = 0.0;
for (uint i = 0; i < num_samples; ++i)
shadow_factor += depthTexture.sample(depthSampler, tex_coord + offsets[i]).x <= light_depth? 1.0 : 0.0;
shadow_factor /= num_samples;
}
// Calculate diffuse and specular
float diffuse = normal_dot_light_dir;
float specular = diffuse > 0.0? pow(clamp(-dot(reflect(light_dir, normal), view_dir), 0.0, 1.0), SpecularPower) : 0.0;
// Apply procedural pattern based on the uv coordinates
bool2 less_half = (vert.oTex - floor(vert.oTex)) < float2(0.5, 0.5);
float darken_factor = less_half.r ^ less_half.g? 0.5 : 1.0;
// Fade out checkerboard pattern when it tiles too often
float2 dx = dfdx(vert.oTex), dy = dfdy(vert.oTex);
float texel_distance = sqrt(dot(dx, dx) + dot(dy, dy));
darken_factor = mix(darken_factor, 0.75, clamp(5.0 * texel_distance - 1.5, 0.0, 1.0));
// Calculate color
return float4(clamp((AmbientFactor + diffuse * shadow_factor) * darken_factor * DiffuseColor + SpecularColor * specular * shadow_factor, 0, 1), 1);
}
struct DepthOut
{
float4 oPosition [[position]];
};
vertex DepthOut TriangleDepthVertexShader(Vertex vert [[stage_in]], constant VertexShaderConstantBuffer *constants [[buffer(2)]])
{
DepthOut out;
// Check if the alpha = 0
if (vert.vCol.a * vert.iCol.a == 0.0)
{
// Don't draw the triangle by moving it to an invalid location
out.oPosition = float4(0, 0, 0, 0);
}
else
{
// Convert input matrix
float4x4 iModel(vert.iModel0, vert.iModel1, vert.iModel2, vert.iModel3);
// Transform the position from world space to homogeneous projection space for the light
float4 pos = float4(vert.vPos, 1.0f);
pos = iModel * pos;
pos = constants->LightView * pos;
pos = constants->LightProjection * pos;
out.oPosition = pos;
}
return out;
}
fragment float4 TriangleDepthPixelShader(DepthOut in [[stage_in]])
{
// We only write depth, so this shader does nothing
return float4(0.0, 0.0, 0.0, 1.0);
}

View File

@@ -0,0 +1,41 @@
#include <metal_stdlib>
using namespace metal;
#include "VertexConstants.h"
constexpr sampler uiTextureSampler(mag_filter::linear, min_filter::linear);
struct UIVertex
{
float3 vPos [[attribute(0)]];
float2 vTex [[attribute(1)]];
uchar4 vCol [[attribute(2)]];
};
struct UIOut
{
float4 oPosition [[position]];
float2 oTex;
float4 oColor;
};
vertex UIOut UIVertexShader(UIVertex vert [[stage_in]], constant VertexShaderConstantBuffer *constants [[buffer(2)]])
{
UIOut out;
out.oPosition = constants->Projection * constants->View * float4(vert.vPos, 1.0);
out.oTex = vert.vTex;
out.oColor = float4(vert.vCol) / 255.0;
return out;
}
fragment float4 UIPixelShader(UIOut in [[stage_in]], texture2d<float> uiTexture [[texture(0)]])
{
const float4 sample = uiTexture.sample(uiTextureSampler, in.oTex);
return sample * in.oColor;
}
fragment float4 UIPixelShaderUntextured(UIOut in [[stage_in]])
{
return in.oColor;
}

View File

@@ -0,0 +1,13 @@
struct VertexShaderConstantBuffer
{
float4x4 View; // view matrix
float4x4 Projection; // projection matrix
float4x4 LightView; // view matrix of the light
float4x4 LightProjection; // projection matrix of the light
};
struct PixelShaderConstantBuffer
{
float3 CameraPos;
float3 LightPos;
};

View File

@@ -0,0 +1,17 @@
#version 450
layout(set = 1, binding = 0) uniform sampler2D texSampler;
layout(location = 0) in vec2 iTex;
layout(location = 1) in vec4 iColor;
layout(location = 0) out vec4 oColor;
void main()
{
float t = texture(texSampler, iTex).x;
if (t < 0.5)
discard;
oColor = vec4(iColor.xyz, t);
}

View File

@@ -0,0 +1,17 @@
#version 450
#include "VertexConstants.h"
layout(location = 0) in vec3 vPos;
layout(location = 1) in vec2 vTex;
layout(location = 2) in vec4 vCol;
layout(location = 0) out vec2 oTex;
layout(location = 1) out vec4 oColor;
void main()
{
gl_Position = c.Projection * c.View * vec4(vPos, 1.0f);
oTex = vTex;
oColor = vCol;
}

View File

@@ -0,0 +1,10 @@
#version 450
layout(location = 0) in vec4 iColor;
layout(location = 0) out vec4 oColor;
void main()
{
oColor = iColor;
}

View File

@@ -0,0 +1,14 @@
#version 450
#include "VertexConstants.h"
layout(location = 0) in vec3 iPosition;
layout(location = 1) in vec4 iColor;
layout(location = 0) out vec4 oColor;
void main()
{
gl_Position = c.Projection * c.View * vec4(iPosition, 1.0);
oColor = iColor;
}

View File

@@ -0,0 +1,6 @@
#version 450
// We only write depth, so this shader does nothing
void main()
{
}

View File

@@ -0,0 +1,31 @@
#version 450
#include "VertexConstants.h"
layout(location = 0) in vec3 vPos;
layout(location = 1) in vec3 vNorm;
layout(location = 2) in vec2 vTex;
layout(location = 3) in vec4 vCol;
layout(location = 4) in mat4 iModel;
layout(location = 8) in mat4 iModelInvTrans;
layout(location = 12) in vec4 iCol;
void main()
{
// Check if the alpha = 0
if (vCol.a * iCol.a == 0.0)
{
// Don't draw the triangle by moving it to an invalid location
gl_Position = vec4(0, 0, 0, 0);
}
else
{
// Transform the position from world space to homogeneous projection space for the light
vec4 pos = vec4(vPos, 1.0f);
pos = iModel * pos;
pos = c.LightView * pos;
pos = c.LightProjection * pos;
gl_Position = pos;
}
}

View File

@@ -0,0 +1,107 @@
#version 450
layout(binding = 1) uniform PixelShaderConstantBuffer
{
vec3 CameraPos;
vec3 LightPos;
} c;
layout(location = 0) in vec3 iNormal;
layout(location = 1) in vec3 iWorldPos;
layout(location = 2) in vec2 iTex;
layout(location = 3) in vec4 iPositionL;
layout(location = 4) in vec4 iColor;
layout(location = 0) out vec4 oColor;
layout(set = 1, binding = 0) uniform sampler2D LightDepthSampler;
void main()
{
// Constants
float AmbientFactor = 0.3;
vec3 DiffuseColor = vec3(iColor.r, iColor.g, iColor.b);
vec3 SpecularColor = vec3(1, 1, 1);
float SpecularPower = 100.0;
float bias = 1.0e-7;
// Homogenize position in light space
vec3 position_l = iPositionL.xyz / iPositionL.w;
// Calculate dot product between direction to light and surface normal and clamp between [0, 1]
vec3 view_dir = normalize(c.CameraPos - iWorldPos);
vec3 world_to_light = c.LightPos - iWorldPos;
vec3 light_dir = normalize(world_to_light);
vec3 normal = normalize(iNormal);
if (dot(view_dir, normal) < 0) // If we're viewing the triangle from the back side, flip the normal to get the correct lighting
normal = -normal;
float normal_dot_light_dir = clamp(dot(normal, light_dir), 0, 1);
// Calculate texture coordinates in light depth texture
vec2 tex_coord;
tex_coord.x = position_l.x / 2.0 + 0.5;
tex_coord.y = position_l.y / 2.0 + 0.5;
// Check that the texture coordinate is inside the depth texture, if not we don't know if it is lit or not so we assume lit
float shadow_factor = 1.0;
if (iColor.a > 0 // Alpha = 0 means don't receive shadows
&& tex_coord.x == clamp(tex_coord.x, 0, 1) && tex_coord.y == clamp(tex_coord.y, 0, 1))
{
// Modify shadow bias according to the angle between the normal and the light dir
float modified_bias = bias * tan(acos(normal_dot_light_dir));
modified_bias = min(modified_bias, 10.0 * bias);
// Get texture size
float width = 1.0 / 4096;
float height = 1.0 / 4096;
// Samples to take
uint num_samples = 16;
vec2 offsets[] = {
vec2(-1.5 * width, -1.5 * height),
vec2(-0.5 * width, -1.5 * height),
vec2(0.5 * width, -1.5 * height),
vec2(1.5 * width, -1.5 * height),
vec2(-1.5 * width, -0.5 * height),
vec2(-0.5 * width, -0.5 * height),
vec2(0.5 * width, -0.5 * height),
vec2(1.5 * width, -0.5 * height),
vec2(-1.5 * width, 0.5 * height),
vec2(-0.5 * width, 0.5 * height),
vec2(0.5 * width, 0.5 * height),
vec2(1.5 * width, 0.5 * height),
vec2(-1.5 * width, 1.5 * height),
vec2(-0.5 * width, 1.5 * height),
vec2(0.5 * width, 1.5 * height),
vec2(1.5 * width, 1.5 * height),
};
// Calculate depth of this pixel relative to the light
float light_depth = position_l.z + modified_bias;
// Sample shadow factor
shadow_factor = 0.0;
for (uint i = 0; i < num_samples; ++i)
shadow_factor += texture(LightDepthSampler, tex_coord + offsets[i]).x <= light_depth? 1.0 : 0.0;
shadow_factor /= num_samples;
}
// Calculate diffuse and specular
float diffuse = normal_dot_light_dir;
float specular = diffuse > 0.0? pow(clamp(-dot(reflect(light_dir, normal), view_dir), 0, 1), SpecularPower) : 0.0;
// Apply procedural pattern based on the uv coordinates
bvec2 less_half = lessThan(iTex - floor(iTex), vec2(0.5, 0.5));
float darken_factor = less_half.r ^^ less_half.g? 0.5 : 1.0;
// Fade out checkerboard pattern when it tiles too often
vec2 dx = dFdx(iTex), dy = dFdy(iTex);
float texel_distance = sqrt(dot(dx, dx) + dot(dy, dy));
darken_factor = mix(darken_factor, 0.75, clamp(5.0 * texel_distance - 1.5, 0.0, 1.0));
// Calculate color
oColor = vec4(clamp((AmbientFactor + diffuse * shadow_factor) * darken_factor * DiffuseColor + SpecularColor * specular * shadow_factor, 0, 1), 1);
}

View File

@@ -0,0 +1,48 @@
#version 450
#include "VertexConstants.h"
layout(location = 0) in vec3 vPos;
layout(location = 1) in vec3 vNorm;
layout(location = 2) in vec2 vTex;
layout(location = 3) in vec4 vCol;
layout(location = 4) in mat4 iModel;
layout(location = 8) in mat4 iModelInvTrans;
layout(location = 12) in vec4 iCol;
layout(location = 0) out vec3 oNormal;
layout(location = 1) out vec3 oWorldPos;
layout(location = 2) out vec2 oTex;
layout(location = 3) out vec4 oPositionL;
layout(location = 4) out vec4 oColor;
void main()
{
// Get world position
vec4 pos = vec4(vPos, 1.0f);
vec4 world_pos = iModel * pos;
// Transform the position from world space to homogeneous projection space
vec4 proj_pos = c.View * world_pos;
proj_pos = c.Projection * proj_pos;
gl_Position = proj_pos;
// Transform the position from world space to projection space of the light
vec4 proj_lpos = c.LightView * world_pos;
proj_lpos = c.LightProjection * proj_lpos;
oPositionL = proj_lpos;
// output normal
vec4 norm = vec4(vNorm, 0.0f);
oNormal = normalize(iModelInvTrans * norm).xyz;
// output world position of the vertex
oWorldPos = world_pos.xyz;
// output texture coordinates
oTex = vTex;
// output color
oColor = vCol * iCol;
}

View File

@@ -0,0 +1,13 @@
#version 450
layout(set = 1, binding = 0) uniform sampler2D texSampler;
layout(location = 0) in vec4 iColor;
layout(location = 1) in vec2 iTex;
layout(location = 0) out vec4 oColor;
void main()
{
oColor = iColor * texture(texSampler, iTex);
}

View File

@@ -0,0 +1,10 @@
#version 450
layout(location = 0) in vec4 iColor;
layout(location = 0) out vec4 oColor;
void main()
{
oColor = iColor;
}

View File

@@ -0,0 +1,17 @@
#version 450
#include "VertexConstants.h"
layout(location = 0) in vec3 vPos;
layout(location = 1) in vec2 vTex;
layout(location = 2) in vec4 vCol;
layout(location = 0) out vec4 oColor;
layout(location = 1) out vec2 oTex;
void main()
{
gl_Position = c.Projection * c.View * vec4(vPos, 1.0f);
oTex = vTex;
oColor = vCol;
}

View File

@@ -0,0 +1,7 @@
layout(binding = 0) uniform VertexShaderConstantBuffer
{
mat4 View;
mat4 Projection;
mat4 LightView;
mat4 LightProjection;
} c;