> shadow casting lights
This commit is contained in:
parent
ccab1182e1
commit
f74c50e493
|
|
@ -77,6 +77,8 @@ pub const Impl = struct {
|
||||||
|
|
||||||
if (ig.begin("renderer debug", &self.rendererDebug, .{})) {
|
if (ig.begin("renderer debug", &self.rendererDebug, .{})) {
|
||||||
_ = ig.sliderFloat("directional light yaw", &rend.context().directionalLightYaw, 0, 360, null, .{});
|
_ = ig.sliderFloat("directional light yaw", &rend.context().directionalLightYaw, 0, 360, null, .{});
|
||||||
|
_ = ig.sliderFloat("ortho near", &rend.context().shadowOrthoNear, 0, 200, null, .{});
|
||||||
|
_ = ig.sliderFloat("ortho far", &rend.context().shadowOrthoFar, 0, 6000, null, .{});
|
||||||
ig.end();
|
ig.end();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,8 @@ pub fn build(b: *std.Build) void {
|
||||||
sdl3.shaderDefintion(b, mod, "../../lib/sdl3", optimize, "debug.frag", b.path("shaders/debug.frag.json"));
|
sdl3.shaderDefintion(b, mod, "../../lib/sdl3", optimize, "debug.frag", b.path("shaders/debug.frag.json"));
|
||||||
sdl3.shaderDefintion(b, mod, "../../lib/sdl3", optimize, "debug.vert", b.path("shaders/debug.vert.json"));
|
sdl3.shaderDefintion(b, mod, "../../lib/sdl3", optimize, "debug.vert", b.path("shaders/debug.vert.json"));
|
||||||
|
|
||||||
|
sdl3.shaderDefintion(b, mod, "../../lib/sdl3", optimize, "depthOnly.frag", b.path("shaders/depthOnly.frag.json"));
|
||||||
|
|
||||||
// ========== tests ==========
|
// ========== tests ==========
|
||||||
const tests = b.addTest(.{
|
const tests = b.addTest(.{
|
||||||
.target = target,
|
.target = target,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
float4 main(
|
||||||
|
float2 UV : TEXCOORD0,
|
||||||
|
float3 WorldPos: TEXCOORD1,
|
||||||
|
float3 Normal: TEXCOORD2,
|
||||||
|
float4 DirectionalShadowFragPos: TEXCOORD3
|
||||||
|
|
||||||
|
) : SV_Target0
|
||||||
|
{
|
||||||
|
return float4(1.0, 1.0, 1.0, 1.0);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"entryPoints" : [
|
||||||
|
{
|
||||||
|
"name" : "main",
|
||||||
|
"mode" : "frag"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"outputs" : [
|
||||||
|
{
|
||||||
|
"type" : "vec4",
|
||||||
|
"name" : "out.var.SV_Target0",
|
||||||
|
"location" : 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -1,12 +1,16 @@
|
||||||
Texture2D<float4> Texture : register(t0, space2);
|
Texture2D<float4> Texture : register(t0, space2);
|
||||||
SamplerState Sampler : register(s0, space2);
|
SamplerState Sampler : register(s0, space2);
|
||||||
|
|
||||||
|
Texture2D<float> DirectionalShadowDepthMap : register(t1, space2);
|
||||||
|
SamplerState DirectionalShadowSampler : register(s1, space2);
|
||||||
|
|
||||||
cbuffer Uniforms : register(b0, space3)
|
cbuffer Uniforms : register(b0, space3)
|
||||||
{
|
{
|
||||||
float4 viewPos;
|
float4 viewPos;
|
||||||
float4 lightPosition;
|
float4 lightPosition;
|
||||||
float4 directionalLight;
|
float4 directionalLight;
|
||||||
float4 directionalLightColor;
|
float4 directionalLightColor;
|
||||||
|
float2 screenSize;
|
||||||
float time;
|
float time;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -68,8 +72,26 @@ float3 BlinnPhong(float3 normal, float3 fragPos, float3 lightPos, float3 lightCo
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float3 DirectionalLight(float3 normal, float3 fragPos)
|
float shadowCalculation(float3 fragPos, float4 DirectionalShadowFragPos)
|
||||||
{
|
{
|
||||||
|
float3 shadowProjection = DirectionalShadowFragPos.xyz / DirectionalShadowFragPos.w;
|
||||||
|
shadowProjection = shadowProjection * 0.5 + 0.5 ;
|
||||||
|
shadowProjection.x = shadowProjection.x;
|
||||||
|
|
||||||
|
float2 uv = shadowProjection.xy;
|
||||||
|
uv.y = -uv.y;
|
||||||
|
float depthSample = DirectionalShadowDepthMap.Sample(DirectionalShadowSampler, uv);
|
||||||
|
float fragDepth = DirectionalShadowFragPos.z;
|
||||||
|
|
||||||
|
float bias = 0.005;
|
||||||
|
float shadow = fragDepth - bias > depthSample ? 1.0 : 0.0;
|
||||||
|
|
||||||
|
return shadow;
|
||||||
|
}
|
||||||
|
|
||||||
|
float3 DirectionalLight(float3 normal, float3 fragPos, float4 DirectionalShadowFragPos)
|
||||||
|
{
|
||||||
|
|
||||||
float3 lightDir = directionalLight.xyz;
|
float3 lightDir = directionalLight.xyz;
|
||||||
float diff = max(dot(lightDir, normal), 0.0);
|
float diff = max(dot(lightDir, normal), 0.0);
|
||||||
float3 diffuse = diff * directionalLightColor.xyz;
|
float3 diffuse = diff * directionalLightColor.xyz;
|
||||||
|
|
@ -82,13 +104,21 @@ float3 DirectionalLight(float3 normal, float3 fragPos)
|
||||||
spec = pow(max(dot(normal, halfwayDir), 0.0), 30.0);
|
spec = pow(max(dot(normal, halfwayDir), 0.0), 30.0);
|
||||||
float3 specular = spec * directionalLightColor.xyz * 2;
|
float3 specular = spec * directionalLightColor.xyz * 2;
|
||||||
|
|
||||||
|
// shadow mapping
|
||||||
|
|
||||||
|
diffuse = diffuse * (1.0 - shadowCalculation(fragPos, DirectionalShadowFragPos));
|
||||||
|
|
||||||
return diffuse;
|
return diffuse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float4 main(
|
float4 main(
|
||||||
|
float4 ScreenPosition: SV_POSITION,
|
||||||
|
|
||||||
float2 UV : TEXCOORD0,
|
float2 UV : TEXCOORD0,
|
||||||
float3 WorldPos: TEXCOORD1,
|
float3 WorldPos: TEXCOORD1,
|
||||||
float3 Normal: TEXCOORD2
|
float3 Normal: TEXCOORD2,
|
||||||
|
float4 DirectionalShadowFragPos: TEXCOORD3
|
||||||
) : SV_Target0
|
) : SV_Target0
|
||||||
{
|
{
|
||||||
float4 s = Texture.Sample(Sampler, UV);
|
float4 s = Texture.Sample(Sampler, UV);
|
||||||
|
|
@ -102,14 +132,33 @@ float4 main(
|
||||||
float3 lightPos = lightPosition.xyz; //+ float3(0, 20, 0);
|
float3 lightPos = lightPosition.xyz; //+ float3(0, 20, 0);
|
||||||
float3 lightColor = float3(0.8, 0.8, 0.5);
|
float3 lightColor = float3(0.8, 0.8, 0.5);
|
||||||
|
|
||||||
float3 ambient = lerp(float3(0.01, 0.01, 0.003), float3(0.004, 0.004, 0.06), dot(Normal, float3(0.0,1.0,0.0)) ) * 5;
|
float3 ambient = float3(0.1,0.1,0.1);
|
||||||
|
|
||||||
|
|
||||||
float3 col = s.xyz;
|
float3 col = s.xyz;
|
||||||
float3 c2 = col * ambient + col * BlinnPhong(Normal, WorldPos, lightPos, lightColor) + col * DirectionalLight(Normal, WorldPos);
|
float3 c2 = col * ambient
|
||||||
|
+ col * BlinnPhong(Normal, WorldPos, lightPos, lightColor)
|
||||||
|
+ col * DirectionalLight(Normal, WorldPos, DirectionalShadowFragPos);
|
||||||
|
|
||||||
float4 rv = float4(pow(c2, 1.0 / 2.2), alpha);
|
float4 rv = float4(pow(c2, 1.0 / 2.2), alpha);
|
||||||
|
|
||||||
|
// === debug bone zone
|
||||||
|
// float3 shadowProjection = DirectionalShadowFragPos.xyz / DirectionalShadowFragPos.w;
|
||||||
|
// shadowProjection = shadowProjection * 0.5 + 0.5 ;
|
||||||
|
// shadowProjection.x = shadowProjection.x;
|
||||||
|
|
||||||
|
// float2 uv = shadowProjection.xy;
|
||||||
|
// uv.y = -uv.y;
|
||||||
|
// float depthSample = DirectionalShadowDepthMap.Sample(DirectionalShadowSampler, uv);
|
||||||
|
// float fragDepth = shadowProjection.z;
|
||||||
|
|
||||||
|
// float t = DirectionalShadowFragPos.z;
|
||||||
|
// t = depthSample;
|
||||||
|
|
||||||
|
// rv = float4(t, t, t, 1.0);
|
||||||
|
|
||||||
|
// rv.x = rv.x + lightPos.x * 0.0001;
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"types" : {
|
"types" : {
|
||||||
"_11" : {
|
"_14" : {
|
||||||
"name" : "type.Uniforms",
|
"name" : "type.Uniforms",
|
||||||
"members" : [
|
"members" : [
|
||||||
{
|
{
|
||||||
|
|
@ -29,10 +29,15 @@
|
||||||
"type" : "vec4",
|
"type" : "vec4",
|
||||||
"offset" : 48
|
"offset" : 48
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name" : "screenSize",
|
||||||
|
"type" : "vec2",
|
||||||
|
"offset" : 64
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name" : "time",
|
"name" : "time",
|
||||||
"type" : "float",
|
"type" : "float",
|
||||||
"offset" : 64
|
"offset" : 72
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
@ -52,6 +57,11 @@
|
||||||
"type" : "vec3",
|
"type" : "vec3",
|
||||||
"name" : "in.var.TEXCOORD2",
|
"name" : "in.var.TEXCOORD2",
|
||||||
"location" : 2
|
"location" : 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type" : "vec4",
|
||||||
|
"name" : "in.var.TEXCOORD3",
|
||||||
|
"location" : 3
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"outputs" : [
|
"outputs" : [
|
||||||
|
|
@ -67,6 +77,12 @@
|
||||||
"name" : "Texture",
|
"name" : "Texture",
|
||||||
"set" : 2,
|
"set" : 2,
|
||||||
"binding" : 0
|
"binding" : 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type" : "texture2D",
|
||||||
|
"name" : "DirectionalShadowDepthMap",
|
||||||
|
"set" : 2,
|
||||||
|
"binding" : 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"separate_samplers" : [
|
"separate_samplers" : [
|
||||||
|
|
@ -75,13 +91,19 @@
|
||||||
"name" : "Sampler",
|
"name" : "Sampler",
|
||||||
"set" : 2,
|
"set" : 2,
|
||||||
"binding" : 0
|
"binding" : 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type" : "sampler",
|
||||||
|
"name" : "DirectionalShadowSampler",
|
||||||
|
"set" : 2,
|
||||||
|
"binding" : 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ubos" : [
|
"ubos" : [
|
||||||
{
|
{
|
||||||
"type" : "_11",
|
"type" : "_14",
|
||||||
"name" : "type.Uniforms",
|
"name" : "type.Uniforms",
|
||||||
"block_size" : 68,
|
"block_size" : 76,
|
||||||
"set" : 3,
|
"set" : 3,
|
||||||
"binding" : 0
|
"binding" : 0
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
// I just reuse this one for the shadow mapping right?
|
||||||
|
|
||||||
struct Input
|
struct Input
|
||||||
{
|
{
|
||||||
float3 Position : TEXCOORD0;
|
float3 Position : TEXCOORD0;
|
||||||
|
|
@ -15,6 +17,7 @@ struct Output
|
||||||
float2 TexCoord : TEXCOORD0;
|
float2 TexCoord : TEXCOORD0;
|
||||||
float3 WorldPos : TEXCOORD1;
|
float3 WorldPos : TEXCOORD1;
|
||||||
float3 Normal: TEXCOORD2;
|
float3 Normal: TEXCOORD2;
|
||||||
|
float4 DirectionalShadowFragPos: TEXCOORD3;
|
||||||
|
|
||||||
float4 Position : SV_Position;
|
float4 Position : SV_Position;
|
||||||
};
|
};
|
||||||
|
|
@ -29,6 +32,7 @@ StructuredBuffer<Scene> scene: register(t0, space0);
|
||||||
cbuffer Uniforms : register(b0, space1)
|
cbuffer Uniforms : register(b0, space1)
|
||||||
{
|
{
|
||||||
float4x4 ViewProjection;
|
float4x4 ViewProjection;
|
||||||
|
float4x4 ShadowMapProjection;
|
||||||
float time;
|
float time;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -46,6 +50,7 @@ Output main(Input input)
|
||||||
output.Position = mul(ViewProjection, mul(scene[input.Instance].Model, pos));
|
output.Position = mul(ViewProjection, mul(scene[input.Instance].Model, pos));
|
||||||
output.WorldPos = WorldPos.xyz;
|
output.WorldPos = WorldPos.xyz;
|
||||||
output.Normal = input.Normal;
|
output.Normal = input.Normal;
|
||||||
|
output.DirectionalShadowFragPos = mul(ShadowMapProjection, WorldPos);
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"types" : {
|
"types" : {
|
||||||
"_11" : {
|
"_12" : {
|
||||||
"name" : "Scene",
|
"name" : "Scene",
|
||||||
"members" : [
|
"members" : [
|
||||||
{
|
{
|
||||||
|
|
@ -18,12 +18,12 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"_10" : {
|
"_11" : {
|
||||||
"name" : "type.StructuredBuffer.Scene",
|
"name" : "type.StructuredBuffer.Scene",
|
||||||
"members" : [
|
"members" : [
|
||||||
{
|
{
|
||||||
"name" : "_m0",
|
"name" : "_m0",
|
||||||
"type" : "_11",
|
"type" : "_12",
|
||||||
"array" : [
|
"array" : [
|
||||||
0
|
0
|
||||||
],
|
],
|
||||||
|
|
@ -35,7 +35,7 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"_13" : {
|
"_14" : {
|
||||||
"name" : "type.Uniforms",
|
"name" : "type.Uniforms",
|
||||||
"members" : [
|
"members" : [
|
||||||
{
|
{
|
||||||
|
|
@ -45,10 +45,17 @@
|
||||||
"matrix_stride" : 16,
|
"matrix_stride" : 16,
|
||||||
"row_major" : true
|
"row_major" : true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name" : "ShadowMapProjection",
|
||||||
|
"type" : "mat4",
|
||||||
|
"offset" : 64,
|
||||||
|
"matrix_stride" : 16,
|
||||||
|
"row_major" : true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name" : "time",
|
"name" : "time",
|
||||||
"type" : "float",
|
"type" : "float",
|
||||||
"offset" : 64
|
"offset" : 128
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
@ -85,11 +92,16 @@
|
||||||
"type" : "vec3",
|
"type" : "vec3",
|
||||||
"name" : "out.var.TEXCOORD2",
|
"name" : "out.var.TEXCOORD2",
|
||||||
"location" : 2
|
"location" : 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type" : "vec4",
|
||||||
|
"name" : "out.var.TEXCOORD3",
|
||||||
|
"location" : 3
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ssbos" : [
|
"ssbos" : [
|
||||||
{
|
{
|
||||||
"type" : "_10",
|
"type" : "_11",
|
||||||
"name" : "scene",
|
"name" : "scene",
|
||||||
"readonly" : true,
|
"readonly" : true,
|
||||||
"block_size" : 0,
|
"block_size" : 0,
|
||||||
|
|
@ -99,9 +111,9 @@
|
||||||
],
|
],
|
||||||
"ubos" : [
|
"ubos" : [
|
||||||
{
|
{
|
||||||
"type" : "_13",
|
"type" : "_14",
|
||||||
"name" : "type.Uniforms",
|
"name" : "type.Uniforms",
|
||||||
"block_size" : 68,
|
"block_size" : 132,
|
||||||
"set" : 1,
|
"set" : 1,
|
||||||
"binding" : 0
|
"binding" : 0
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -193,7 +193,7 @@ pub fn createPipeline(self: *@This()) !*gpu.GPUGraphicsPipeline {
|
||||||
pci.depth_stencil_state.write_mask = 0xff;
|
pci.depth_stencil_state.write_mask = 0xff;
|
||||||
|
|
||||||
pci.target_info.has_depth_stencil_target = true;
|
pci.target_info.has_depth_stencil_target = true;
|
||||||
pci.target_info.depth_stencil_format = .textureformatD32Float;
|
pci.target_info.depth_stencil_format = rend.context().depthFormat;
|
||||||
pci.target_info.num_color_targets = 1;
|
pci.target_info.num_color_targets = 1;
|
||||||
pci.target_info.color_target_descriptions = &[_]gpu.GPUColorTargetDescription{
|
pci.target_info.color_target_descriptions = &[_]gpu.GPUColorTargetDescription{
|
||||||
.{
|
.{
|
||||||
|
|
|
||||||
|
|
@ -37,9 +37,12 @@ pub const Renderer = struct {
|
||||||
preDraws: std.ArrayListUnmanaged(struct { ptr: *anyopaque, func: *const fn (*anyopaque, *gpu.GPUCommandBuffer) void }) = .{},
|
preDraws: std.ArrayListUnmanaged(struct { ptr: *anyopaque, func: *const fn (*anyopaque, *gpu.GPUCommandBuffer) void }) = .{},
|
||||||
|
|
||||||
depthTexture: *gpu.GPUTexture = undefined,
|
depthTexture: *gpu.GPUTexture = undefined,
|
||||||
|
depthFormat: gpu.GPUTextureFormat = .textureformatD16Unorm,
|
||||||
|
|
||||||
textureList: *TextureList = undefined,
|
textureList: *TextureList = undefined,
|
||||||
|
|
||||||
|
shadowMapProjection: core.Transform = core.zm.identity(),
|
||||||
|
|
||||||
blockySampler: *gpu.GPUSampler = undefined,
|
blockySampler: *gpu.GPUSampler = undefined,
|
||||||
defaultTexture: *rend.Texture = undefined,
|
defaultTexture: *rend.Texture = undefined,
|
||||||
|
|
||||||
|
|
@ -47,9 +50,17 @@ pub const Renderer = struct {
|
||||||
|
|
||||||
debugDrawSys: *DebugDrawSystem = undefined,
|
debugDrawSys: *DebugDrawSystem = undefined,
|
||||||
|
|
||||||
|
shadowOrthoNear: f32 = -150,
|
||||||
|
shadowOrthoFar: f32 = 150,
|
||||||
|
|
||||||
directionalLightYaw: f32 = 0.0,
|
directionalLightYaw: f32 = 0.0,
|
||||||
directionalLightColor: core.colors.Color = .{ .r = 0.8, .g = 0.8, .b = 0.9 },
|
directionalLightColor: core.colors.Color = .{ .r = 0.8, .g = 0.8, .b = 0.9 },
|
||||||
directionalLightDir: core.Vectorf = core.Vectorf.new(0.5, 0.25, -1).normalize(),
|
directionalLightDir: core.Vectorf = core.Vectorf.new(0.5, -0.5, 0.0).normalize(),
|
||||||
|
|
||||||
|
shadowDepthFormat: gpu.GPUTextureFormat = .textureformatD16Unorm,
|
||||||
|
shadowDepthTexture: *gpu.GPUTexture = undefined,
|
||||||
|
shadowDepthDebugOutput: *gpu.GPUTexture = undefined,
|
||||||
|
shadowCastingPipeline: *gpu.GPUGraphicsPipeline = undefined,
|
||||||
|
|
||||||
// transients DO NOT TOUCH
|
// transients DO NOT TOUCH
|
||||||
swapchainTexture: ?*gpu.GPUTexture = undefined,
|
swapchainTexture: ?*gpu.GPUTexture = undefined,
|
||||||
|
|
@ -118,6 +129,13 @@ pub const Renderer = struct {
|
||||||
self.defaultTexture = getTexture(&defaultTextureName).?;
|
self.defaultTexture = getTexture(&defaultTextureName).?;
|
||||||
|
|
||||||
self.debugDrawSys = try self.createRendererEngineObject(DebugDrawSystem);
|
self.debugDrawSys = try self.createRendererEngineObject(DebugDrawSystem);
|
||||||
|
|
||||||
|
try self.createDirectionalShadowsPipeline();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn createDirectionalShadowsPipeline(self: *@This()) !void {
|
||||||
|
try self.createShadowDepthTexture();
|
||||||
|
try self.createShadowCastingPipeline();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn createSamplers(self: *@This()) !void {
|
pub fn createSamplers(self: *@This()) !void {
|
||||||
|
|
@ -174,11 +192,27 @@ pub const Renderer = struct {
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn createShadowDepthTexture(self: *@This()) !void {
|
||||||
|
var gci = std.mem.zeroes(gpu.GPUTextureCreateInfo);
|
||||||
|
|
||||||
|
const shadowMapRes = core.configVar(u32, "renderer.shadowmap.resolution", 2048);
|
||||||
|
gci.type = .texturetype2d;
|
||||||
|
gci.format = self.shadowDepthFormat;
|
||||||
|
gci.width = shadowMapRes;
|
||||||
|
gci.height = shadowMapRes;
|
||||||
|
gci.layer_count_or_depth = 1;
|
||||||
|
gci.num_levels = 1;
|
||||||
|
gci.sample_count = .samplecount1;
|
||||||
|
gci.usage = .{ .textureusageDepthStencilTarget = true, .textureusageSampler = true };
|
||||||
|
|
||||||
|
self.shadowDepthTexture = self.device.createGPUTexture(&gci);
|
||||||
|
}
|
||||||
|
|
||||||
fn createDepthTexture(self: *@This()) !void {
|
fn createDepthTexture(self: *@This()) !void {
|
||||||
var gci = std.mem.zeroes(gpu.GPUTextureCreateInfo);
|
var gci = std.mem.zeroes(gpu.GPUTextureCreateInfo);
|
||||||
|
|
||||||
gci.type = .texturetype2d;
|
gci.type = .texturetype2d;
|
||||||
gci.format = .textureformatD32Float;
|
gci.format = self.depthFormat;
|
||||||
gci.width = @intCast(self.scissor.w);
|
gci.width = @intCast(self.scissor.w);
|
||||||
gci.height = @intCast(self.scissor.h);
|
gci.height = @intCast(self.scissor.h);
|
||||||
gci.layer_count_or_depth = 1;
|
gci.layer_count_or_depth = 1;
|
||||||
|
|
@ -212,26 +246,31 @@ pub const Renderer = struct {
|
||||||
offset.* = offset.* + size;
|
offset.* = offset.* + size;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn createMeshPipeline(self: *@This()) !void {
|
pub fn generateVertexAttributeList(self: *@This()) !std.ArrayList(gpu.GPUVertexAttribute) {
|
||||||
|
var list = std.ArrayList(gpu.GPUVertexAttribute).init(self.allocator);
|
||||||
|
var offset: u32 = 0;
|
||||||
|
{
|
||||||
|
try addAttribute(&list, &offset, @sizeOf(f32) * 3, .vertexelementformatFloat3);
|
||||||
|
try addAttribute(&list, &offset, @sizeOf(f32) * 3, .vertexelementformatFloat3);
|
||||||
|
try addAttribute(&list, &offset, @sizeOf(f32) * 4, .vertexelementformatFloat4);
|
||||||
|
try addAttribute(&list, &offset, @sizeOf(f32) * 2, .vertexelementformatFloat2);
|
||||||
|
try addAttribute(&list, &offset, @sizeOf(u32), .vertexelementformatUint);
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn createShadowCastingPipeline(self: *@This()) !void {
|
||||||
const vertex = try self.loadShader("meshes.vert", meshes_vert.LoadArgs);
|
const vertex = try self.loadShader("meshes.vert", meshes_vert.LoadArgs);
|
||||||
const fragment = try self.loadShader("lit_mesh.frag", lit_mesh_frag.LoadArgs);
|
const fragment = try self.loadShader("depthOnly.frag", depthOnly.LoadArgs);
|
||||||
|
|
||||||
var pci = std.mem.zeroes(gpu.GPUGraphicsPipelineCreateInfo);
|
var pci = std.mem.zeroes(gpu.GPUGraphicsPipelineCreateInfo);
|
||||||
pci.vertex_shader = vertex;
|
pci.vertex_shader = vertex;
|
||||||
pci.fragment_shader = fragment;
|
pci.fragment_shader = fragment;
|
||||||
|
|
||||||
var attributes = std.ArrayList(gpu.GPUVertexAttribute).init(self.allocator);
|
var attributes = try self.generateVertexAttributeList();
|
||||||
defer attributes.deinit();
|
defer attributes.deinit();
|
||||||
|
|
||||||
var offset: u32 = 0;
|
|
||||||
{
|
|
||||||
try addAttribute(&attributes, &offset, @sizeOf(f32) * 3, .vertexelementformatFloat3);
|
|
||||||
try addAttribute(&attributes, &offset, @sizeOf(f32) * 3, .vertexelementformatFloat3);
|
|
||||||
try addAttribute(&attributes, &offset, @sizeOf(f32) * 4, .vertexelementformatFloat4);
|
|
||||||
try addAttribute(&attributes, &offset, @sizeOf(f32) * 2, .vertexelementformatFloat2);
|
|
||||||
try addAttribute(&attributes, &offset, @sizeOf(u32), .vertexelementformatUint);
|
|
||||||
}
|
|
||||||
|
|
||||||
pci.vertex_input_state = .{
|
pci.vertex_input_state = .{
|
||||||
.num_vertex_buffers = 1,
|
.num_vertex_buffers = 1,
|
||||||
.vertex_buffer_descriptions = &[_]gpu.GPUVertexBufferDescription{
|
.vertex_buffer_descriptions = &[_]gpu.GPUVertexBufferDescription{
|
||||||
|
|
@ -247,7 +286,45 @@ pub const Renderer = struct {
|
||||||
pci.depth_stencil_state.write_mask = 0xff;
|
pci.depth_stencil_state.write_mask = 0xff;
|
||||||
|
|
||||||
pci.target_info.has_depth_stencil_target = true;
|
pci.target_info.has_depth_stencil_target = true;
|
||||||
pci.target_info.depth_stencil_format = .textureformatD32Float;
|
pci.target_info.depth_stencil_format = self.shadowDepthFormat;
|
||||||
|
|
||||||
|
pci.target_info.num_color_targets = 0;
|
||||||
|
|
||||||
|
// no color targets
|
||||||
|
pci.rasterizer_state.cull_mode = .cullmodeNone;
|
||||||
|
pci.rasterizer_state.fill_mode = .fillmodeFill;
|
||||||
|
pci.rasterizer_state.enable_depth_bias = true;
|
||||||
|
|
||||||
|
self.shadowCastingPipeline = self.device.createGPUGraphicsPipeline(&pci);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn createMeshPipeline(self: *@This()) !void {
|
||||||
|
const vertex = try self.loadShader("meshes.vert", meshes_vert.LoadArgs);
|
||||||
|
const fragment = try self.loadShader("lit_mesh.frag", lit_mesh_frag.LoadArgs);
|
||||||
|
|
||||||
|
var pci = std.mem.zeroes(gpu.GPUGraphicsPipelineCreateInfo);
|
||||||
|
pci.vertex_shader = vertex;
|
||||||
|
pci.fragment_shader = fragment;
|
||||||
|
|
||||||
|
var attributes = try self.generateVertexAttributeList();
|
||||||
|
defer attributes.deinit();
|
||||||
|
|
||||||
|
pci.vertex_input_state = .{
|
||||||
|
.num_vertex_buffers = 1,
|
||||||
|
.vertex_buffer_descriptions = &[_]gpu.GPUVertexBufferDescription{
|
||||||
|
.{ .slot = 0, .pitch = @sizeOf(rend.MeshVertex), .input_rate = .vertexinputrateVertex, .instance_step_rate = 0 },
|
||||||
|
},
|
||||||
|
.num_vertex_attributes = @intCast(attributes.items.len),
|
||||||
|
.vertex_attributes = @ptrCast(attributes.items.ptr),
|
||||||
|
};
|
||||||
|
|
||||||
|
pci.depth_stencil_state.compare_op = .compareopLess;
|
||||||
|
pci.depth_stencil_state.enable_depth_test = true;
|
||||||
|
pci.depth_stencil_state.enable_depth_write = true;
|
||||||
|
pci.depth_stencil_state.write_mask = 0xff;
|
||||||
|
|
||||||
|
pci.target_info.has_depth_stencil_target = true;
|
||||||
|
pci.target_info.depth_stencil_format = self.depthFormat;
|
||||||
pci.target_info.num_color_targets = 1;
|
pci.target_info.num_color_targets = 1;
|
||||||
pci.target_info.color_target_descriptions = &[_]gpu.GPUColorTargetDescription{
|
pci.target_info.color_target_descriptions = &[_]gpu.GPUColorTargetDescription{
|
||||||
.{
|
.{
|
||||||
|
|
@ -357,6 +434,8 @@ pub const Renderer = struct {
|
||||||
if (self.activeCamera) |camera| {
|
if (self.activeCamera) |camera| {
|
||||||
ptr.ViewProjection = @bitCast(camera.final);
|
ptr.ViewProjection = @bitCast(camera.final);
|
||||||
}
|
}
|
||||||
|
ptr.ShadowMapProjection = @bitCast(self.shadowMapProjection);
|
||||||
|
// ptr.ViewProjection = @bitCast(self.shadowMapProjection);
|
||||||
|
|
||||||
ptr.time = @floatCast(self.totalTime);
|
ptr.time = @floatCast(self.totalTime);
|
||||||
|
|
||||||
|
|
@ -371,8 +450,9 @@ pub const Renderer = struct {
|
||||||
if (self.activeCamera) |cam| {
|
if (self.activeCamera) |cam| {
|
||||||
position = cam.finalPos;
|
position = cam.finalPos;
|
||||||
}
|
}
|
||||||
const resolved = core.Rotation.eulerY(core.radians(self.directionalLightYaw)).rotateVector(self.directionalLightDir);
|
const resolved = core.Rotation.eulerY(core.radians(self.directionalLightYaw)).rotateVector(self.directionalLightDir.fmul(-1));
|
||||||
|
|
||||||
|
ptr.screenSize = @bitCast(platform.context().extent);
|
||||||
ptr.viewPos = @bitCast(position.toZm());
|
ptr.viewPos = @bitCast(position.toZm());
|
||||||
ptr.lightPosition = @bitCast(self.lightPosition.toZm());
|
ptr.lightPosition = @bitCast(self.lightPosition.toZm());
|
||||||
ptr.directionalLight = @bitCast(resolved.toZm());
|
ptr.directionalLight = @bitCast(resolved.toZm());
|
||||||
|
|
@ -425,32 +505,109 @@ pub const Renderer = struct {
|
||||||
|
|
||||||
const cmd = self.device.acquireGPUCommandBuffer();
|
const cmd = self.device.acquireGPUCommandBuffer();
|
||||||
self.frameUploads();
|
self.frameUploads();
|
||||||
try self.uploadUniforms(cmd);
|
|
||||||
|
|
||||||
for (self.preDraws.items) |interface| {
|
for (self.preDraws.items) |interface| {
|
||||||
interface.func(interface.ptr, cmd);
|
interface.func(interface.ptr, cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mesh pre-iteration
|
||||||
|
const container = rend.MeshComponent.BaseContainer;
|
||||||
|
const uploadCount: usize = @min(container.dense.items.len, MaxObjectCount);
|
||||||
|
|
||||||
|
for (0..uploadCount) |i| {
|
||||||
|
const component = &container.dense.items[i].value;
|
||||||
|
|
||||||
|
if (component.mesh == null) {
|
||||||
|
component.updateMesh();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (component.texture == null) {
|
||||||
|
component.updateTexture();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.drawDirectionalShadowMap(cmd);
|
||||||
|
|
||||||
|
self.draw(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
// orthographic view projection from the sun towards the center of the thing
|
||||||
|
pub fn shadowMapOrtho(self: *@This()) core.Transform {
|
||||||
|
const ortho = core.zm.orthographicLh(200, 200, self.shadowOrthoNear, self.shadowOrthoFar);
|
||||||
|
var rotation = core.zm.lookAtLh(
|
||||||
|
.{ 0, 0, 0, 1 },
|
||||||
|
self.directionalLightDir.toZm(),
|
||||||
|
.{ 0, 1, 0, 1 },
|
||||||
|
);
|
||||||
|
|
||||||
|
rotation = core.zm.mul(core.zm.rotationY(core.radians(self.directionalLightYaw)), rotation);
|
||||||
|
|
||||||
|
return core.zm.mul(rotation, ortho);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn drawDirectionalShadowMap(self: *@This(), cmd: *gpu.GPUCommandBuffer) void {
|
||||||
|
{
|
||||||
|
var data = std.mem.zeroes([@sizeOf(meshes_vert.Uniforms) / 8 + 1]usize);
|
||||||
|
const ptr: *meshes_vert.Uniforms = @ptrCast(@alignCast(&data));
|
||||||
|
self.shadowMapProjection = self.shadowMapOrtho();
|
||||||
|
ptr.ViewProjection = @bitCast(self.shadowMapProjection);
|
||||||
|
|
||||||
|
cmd.pushGPUVertexUniformData(0, &data, @sizeOf(meshes_vert.Uniforms));
|
||||||
|
}
|
||||||
|
|
||||||
|
// can cache this
|
||||||
|
const depthTarget = std.mem.zeroInit(gpu.GPUDepthStencilTargetInfo, .{
|
||||||
|
.texture = self.shadowDepthTexture,
|
||||||
|
.load_op = .loadopClear,
|
||||||
|
.store_op = .storeopStore,
|
||||||
|
.stencil_load_op = .loadopDontCare,
|
||||||
|
.stencil_store_op = .storeopDontCare,
|
||||||
|
.clear_depth = 1.0,
|
||||||
|
.clear_stencil = 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
const renderpass = cmd.beginGPURenderPass(null, 0, &depthTarget);
|
||||||
|
renderpass.bindGPUGraphicsPipeline(self.shadowCastingPipeline);
|
||||||
|
renderpass.bindGPUVertexStorageBuffers(0, &self.ssboScene, 1);
|
||||||
|
renderpass.bindGPUVertexBuffers(0, &.{ .buffer = self.meshPool.vertexBuffer, .offset = 0 }, 1);
|
||||||
|
renderpass.bindGPUIndexBuffer(&.{ .buffer = self.meshPool.indexBuffer, .offset = 0 }, .indexelementsize32bit);
|
||||||
|
|
||||||
|
const container = rend.MeshComponent.BaseContainer;
|
||||||
|
const uploadCount: usize = @min(container.dense.items.len, MaxObjectCount);
|
||||||
|
for (0..uploadCount) |i| {
|
||||||
|
const component = &container.dense.items[i].value;
|
||||||
|
if (component.mesh) |mesh| {
|
||||||
|
renderpass.drawGPUIndexedPrimitives(mesh.index.size, 1, mesh.index.start, @intCast(mesh.vertex.start), @intCast(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
renderpass.endGPURenderPass();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw(self: *@This(), cmd: *gpu.GPUCommandBuffer) void {
|
||||||
if (cmd.waitAndAcquireGPUSwapchainTexture(self.window, @ptrCast(&self.swapchainTexture), null, null)) {
|
if (cmd.waitAndAcquireGPUSwapchainTexture(self.window, @ptrCast(&self.swapchainTexture), null, null)) {
|
||||||
if (self.swapchainTexture == null) {
|
if (self.swapchainTexture == null) {
|
||||||
_ = cmd.submitGPUCommandBuffer();
|
_ = cmd.submitGPUCommandBuffer();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
try self.uploadUniforms(cmd);
|
||||||
|
|
||||||
var targetInfo: gpu.GPUColorTargetInfo = std.mem.zeroes(gpu.GPUColorTargetInfo);
|
// can cache this
|
||||||
targetInfo.texture = self.swapchainTexture.?;
|
const targetInfo: gpu.GPUColorTargetInfo = std.mem.zeroInit(gpu.GPUColorTargetInfo, .{
|
||||||
targetInfo.clear_color = .{ .r = 0.1, .g = 0.1, .b = 0.1, .a = 1.0 };
|
.texture = self.swapchainTexture.?,
|
||||||
targetInfo.load_op = .loadopClear;
|
.clear_color = .{ .r = 0.1, .g = 0.1, .b = 0.1, .a = 1.0 },
|
||||||
targetInfo.store_op = .storeopStore;
|
.load_op = .loadopClear,
|
||||||
|
.store_op = .storeopStore,
|
||||||
|
});
|
||||||
|
|
||||||
var depthTarget = std.mem.zeroes(gpu.GPUDepthStencilTargetInfo);
|
const depthTarget = std.mem.zeroInit(gpu.GPUDepthStencilTargetInfo, .{
|
||||||
depthTarget.texture = self.depthTexture;
|
.texture = self.depthTexture,
|
||||||
depthTarget.load_op = .loadopClear;
|
.load_op = .loadopClear,
|
||||||
depthTarget.store_op = .storeopDontCare;
|
.store_op = .storeopDontCare,
|
||||||
depthTarget.stencil_load_op = .loadopDontCare;
|
.stencil_load_op = .loadopDontCare,
|
||||||
depthTarget.stencil_store_op = .storeopDontCare;
|
.stencil_store_op = .storeopDontCare,
|
||||||
depthTarget.clear_depth = 1.0;
|
.clear_depth = 1.0,
|
||||||
depthTarget.clear_stencil = 0;
|
.clear_stencil = 0,
|
||||||
|
});
|
||||||
|
|
||||||
const renderpass = cmd.beginGPURenderPass(&targetInfo, 1, &depthTarget);
|
const renderpass = cmd.beginGPURenderPass(&targetInfo, 1, &depthTarget);
|
||||||
//renderpass.bindGPUGraphicsPipeline(self.testPipeline);
|
//renderpass.bindGPUGraphicsPipeline(self.testPipeline);
|
||||||
|
|
@ -460,36 +617,26 @@ pub const Renderer = struct {
|
||||||
renderpass.bindGPUVertexStorageBuffers(0, &self.ssboScene, 1);
|
renderpass.bindGPUVertexStorageBuffers(0, &self.ssboScene, 1);
|
||||||
renderpass.bindGPUVertexBuffers(0, &.{ .buffer = self.meshPool.vertexBuffer, .offset = 0 }, 1);
|
renderpass.bindGPUVertexBuffers(0, &.{ .buffer = self.meshPool.vertexBuffer, .offset = 0 }, 1);
|
||||||
renderpass.bindGPUIndexBuffer(&.{ .buffer = self.meshPool.indexBuffer, .offset = 0 }, .indexelementsize32bit);
|
renderpass.bindGPUIndexBuffer(&.{ .buffer = self.meshPool.indexBuffer, .offset = 0 }, .indexelementsize32bit);
|
||||||
|
renderpass.bindGPUFragmentSamplers(1, &.{ .texture = self.shadowDepthTexture, .sampler = self.blockySampler }, 1);
|
||||||
// todo move into materials system
|
// todo move into materials system
|
||||||
|
|
||||||
renderpass.setGPUScissor(&self.scissor);
|
renderpass.setGPUScissor(&self.scissor);
|
||||||
|
|
||||||
//SDL_BindGPUFragmentSamplers(renderPass, 0, &(SDL_GPUTextureSamplerBinding){ .texture = Texture, .sampler = Samplers[CurrentSamplerIndex] }, 1);
|
|
||||||
//rendering each mesh
|
//rendering each mesh
|
||||||
{
|
{
|
||||||
const container = rend.MeshComponent.BaseContainer;
|
const container = rend.MeshComponent.BaseContainer;
|
||||||
const uploadCount: usize = @min(container.dense.items.len, MaxObjectCount);
|
const uploadCount: usize = @min(container.dense.items.len, MaxObjectCount);
|
||||||
for (0..uploadCount) |i| {
|
for (0..uploadCount) |i| {
|
||||||
// core.engine_log("pushing draw {d}", .{i});
|
|
||||||
const component = &container.dense.items[i].value;
|
const component = &container.dense.items[i].value;
|
||||||
|
|
||||||
// todo move this to slow tick? only update once every 1 second or so?
|
|
||||||
if (component.mesh == null) {
|
|
||||||
component.updateMesh();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (component.texture == null) {
|
|
||||||
component.updateTexture();
|
|
||||||
}
|
|
||||||
|
|
||||||
var t = component.texture;
|
var t = component.texture;
|
||||||
if (t == null) {
|
if (t == null) {
|
||||||
t = self.defaultTexture;
|
t = self.defaultTexture;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderpass.bindGPUFragmentSamplers(0, &.{ .texture = t.?.texture, .sampler = self.blockySampler }, 1);
|
renderpass.bindGPUFragmentSamplers(0, &.{ .texture = t.?.texture, .sampler = self.blockySampler }, 1);
|
||||||
|
|
||||||
if (component.mesh) |mesh| {
|
if (component.mesh) |mesh| {
|
||||||
// core.engine_log("pushing draw for instance {d}", .{i});
|
|
||||||
renderpass.drawGPUIndexedPrimitives(mesh.index.size, 1, mesh.index.start, @intCast(mesh.vertex.start), @intCast(i));
|
renderpass.drawGPUIndexedPrimitives(mesh.index.size, 1, mesh.index.start, @intCast(mesh.vertex.start), @intCast(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -543,6 +690,7 @@ const gpu = sdl3.gpu;
|
||||||
|
|
||||||
const meshes_vert = @import("meshes.vert");
|
const meshes_vert = @import("meshes.vert");
|
||||||
const lit_mesh_frag = @import("lit_mesh.frag");
|
const lit_mesh_frag = @import("lit_mesh.frag");
|
||||||
|
const depthOnly = @import("depthOnly.frag");
|
||||||
const sample_vert = @import("sample.vert");
|
const sample_vert = @import("sample.vert");
|
||||||
|
|
||||||
const MeshVertices = meshes_vert.Scene;
|
const MeshVertices = meshes_vert.Scene;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
extras are like engine plugins
|
||||||
|
|
||||||
|
they have access to all engine modules without having to be upstreamed as part of the engine
|
||||||
|
|
||||||
|
and they don't have to be linked into your project unless you want them to be.
|
||||||
|
|
@ -620,7 +620,7 @@ pub const GPUColorTargetInfo = extern struct {
|
||||||
clear_color: FColor, // The color to clear the color target to at the start of the render pass. Ignored if SDL_GPU_LOADOP_CLEAR is not used.
|
clear_color: FColor, // The color to clear the color target to at the start of the render pass. Ignored if SDL_GPU_LOADOP_CLEAR is not used.
|
||||||
load_op: GPULoadOp, // What is done with the contents of the color target at the beginning of the render pass.
|
load_op: GPULoadOp, // What is done with the contents of the color target at the beginning of the render pass.
|
||||||
store_op: GPUStoreOp, // What is done with the results of the render pass.
|
store_op: GPUStoreOp, // What is done with the results of the render pass.
|
||||||
resolve_texture: *GPUTexture, // The texture that will receive the results of a multisample resolve operation. Ignored if a RESOLVE* store_op is not used.
|
resolve_texture: ?*GPUTexture, // The texture that will receive the results of a multisample resolve operation. Ignored if a RESOLVE* store_op is not used.
|
||||||
resolve_mip_level: u32, // The mip level of the resolve texture to use for the resolve operation. Ignored if a RESOLVE* store_op is not used.
|
resolve_mip_level: u32, // The mip level of the resolve texture to use for the resolve operation. Ignored if a RESOLVE* store_op is not used.
|
||||||
resolve_layer: u32, // The layer index of the resolve texture to use for the resolve operation. Ignored if a RESOLVE* store_op is not used.
|
resolve_layer: u32, // The layer index of the resolve texture to use for the resolve operation. Ignored if a RESOLVE* store_op is not used.
|
||||||
cycle: bool, // true cycles the texture if the texture is bound and load_op is not LOAD
|
cycle: bool, // true cycles the texture if the texture is bound and load_op is not LOAD
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,17 @@
|
||||||
|
#include <metal_stdlib>
|
||||||
|
#include <simd/simd.h>
|
||||||
|
|
||||||
|
using namespace metal;
|
||||||
|
|
||||||
|
struct main0_out
|
||||||
|
{
|
||||||
|
float4 out_var_SV_Target0 [[color(0)]];
|
||||||
|
};
|
||||||
|
|
||||||
|
fragment main0_out main0()
|
||||||
|
{
|
||||||
|
main0_out out = {};
|
||||||
|
out.out_var_SV_Target0 = float4(1.0);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -9,9 +9,12 @@ struct type_Uniforms
|
||||||
float4 lightPosition;
|
float4 lightPosition;
|
||||||
float4 directionalLight;
|
float4 directionalLight;
|
||||||
float4 directionalLightColor;
|
float4 directionalLightColor;
|
||||||
|
float2 screenSize;
|
||||||
float time;
|
float time;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
constant float3 _56 = {};
|
||||||
|
|
||||||
struct main0_out
|
struct main0_out
|
||||||
{
|
{
|
||||||
float4 out_var_SV_Target0 [[color(0)]];
|
float4 out_var_SV_Target0 [[color(0)]];
|
||||||
|
|
@ -22,14 +25,15 @@ struct main0_in
|
||||||
float2 in_var_TEXCOORD0 [[user(locn0)]];
|
float2 in_var_TEXCOORD0 [[user(locn0)]];
|
||||||
float3 in_var_TEXCOORD1 [[user(locn1)]];
|
float3 in_var_TEXCOORD1 [[user(locn1)]];
|
||||||
float3 in_var_TEXCOORD2 [[user(locn2)]];
|
float3 in_var_TEXCOORD2 [[user(locn2)]];
|
||||||
|
float4 in_var_TEXCOORD3 [[user(locn3)]];
|
||||||
};
|
};
|
||||||
|
|
||||||
fragment main0_out main0(main0_in in [[stage_in]], constant type_Uniforms& Uniforms [[buffer(0)]], texture2d<float> Texture [[texture(0)]], sampler Sampler [[sampler(0)]])
|
fragment main0_out main0(main0_in in [[stage_in]], constant type_Uniforms& Uniforms [[buffer(0)]], texture2d<float> Texture [[texture(0)]], texture2d<float> DirectionalShadowDepthMap [[texture(1)]], sampler Sampler [[sampler(0)]], sampler DirectionalShadowSampler [[sampler(1)]])
|
||||||
{
|
{
|
||||||
main0_out out = {};
|
main0_out out = {};
|
||||||
float4 _61 = Texture.sample(Sampler, in.in_var_TEXCOORD0);
|
float4 _65 = Texture.sample(Sampler, in.in_var_TEXCOORD0);
|
||||||
float _62 = _61.w;
|
float _66 = _65.w;
|
||||||
if (_62 < 0.00999999977648258209228515625)
|
if (_66 < 0.00999999977648258209228515625)
|
||||||
{
|
{
|
||||||
discard_fragment();
|
discard_fragment();
|
||||||
}
|
}
|
||||||
|
|
@ -68,7 +72,12 @@ fragment main0_out main0(main0_in in [[stage_in]], constant type_Uniforms& Unifo
|
||||||
_119 = ((float3(0.800000011920928955078125, 0.800000011920928955078125, 0.5) * precise::max(dot(_100, in.in_var_TEXCOORD2), 0.0)) * _93) + (((float3(0.800000011920928955078125, 0.800000011920928955078125, 0.5) * powr(precise::max(dot(in.in_var_TEXCOORD2, fast::normalize(_100 + fast::normalize(in.in_var_TEXCOORD1 - Uniforms.viewPos.xyz))), 0.0), 30.0)) * 2.0) * _93);
|
_119 = ((float3(0.800000011920928955078125, 0.800000011920928955078125, 0.5) * precise::max(dot(_100, in.in_var_TEXCOORD2), 0.0)) * _93) + (((float3(0.800000011920928955078125, 0.800000011920928955078125, 0.5) * powr(precise::max(dot(in.in_var_TEXCOORD2, fast::normalize(_100 + fast::normalize(in.in_var_TEXCOORD1 - Uniforms.viewPos.xyz))), 0.0), 30.0)) * 2.0) * _93);
|
||||||
break;
|
break;
|
||||||
} while(false);
|
} while(false);
|
||||||
out.out_var_SV_Target0 = float4(powr(_61.xyz * (((mix(float3(0.00999999977648258209228515625, 0.00999999977648258209228515625, 0.0030000000260770320892333984375), float3(0.0040000001899898052215576171875, 0.0040000001899898052215576171875, 0.0599999986588954925537109375), float3(in.in_var_TEXCOORD2.y)) * 5.0) + _119) + (Uniforms.directionalLightColor.xyz * precise::max(dot(Uniforms.directionalLight.xyz, in.in_var_TEXCOORD2), 0.0))), float3(0.4545454680919647216796875)), _62);
|
float3 _136 = ((in.in_var_TEXCOORD3.xyz / float3(in.in_var_TEXCOORD3.w)) * 0.5) + float3(0.5);
|
||||||
|
float3 _138;
|
||||||
|
_138.x = _136.x;
|
||||||
|
float2 _139 = _138.xy;
|
||||||
|
_139.y = -_136.y;
|
||||||
|
out.out_var_SV_Target0 = float4(powr(_65.xyz * ((float3(0.100000001490116119384765625) + _119) + ((Uniforms.directionalLightColor.xyz * precise::max(dot(Uniforms.directionalLight.xyz, in.in_var_TEXCOORD2), 0.0)) * (1.0 - float((in.in_var_TEXCOORD3.z - 0.004999999888241291046142578125) > DirectionalShadowDepthMap.sample(DirectionalShadowSampler, _139).x)))), float3(0.4545454680919647216796875)), _66);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ struct type_StructuredBuffer_Scene
|
||||||
struct type_Uniforms
|
struct type_Uniforms
|
||||||
{
|
{
|
||||||
float4x4 ViewProjection;
|
float4x4 ViewProjection;
|
||||||
|
float4x4 ShadowMapProjection;
|
||||||
float time;
|
float time;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -24,6 +25,7 @@ struct main0_out
|
||||||
float2 out_var_TEXCOORD0 [[user(locn0)]];
|
float2 out_var_TEXCOORD0 [[user(locn0)]];
|
||||||
float3 out_var_TEXCOORD1 [[user(locn1)]];
|
float3 out_var_TEXCOORD1 [[user(locn1)]];
|
||||||
float3 out_var_TEXCOORD2 [[user(locn2)]];
|
float3 out_var_TEXCOORD2 [[user(locn2)]];
|
||||||
|
float4 out_var_TEXCOORD3 [[user(locn3)]];
|
||||||
float4 gl_Position [[position]];
|
float4 gl_Position [[position]];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -37,11 +39,13 @@ struct main0_in
|
||||||
vertex main0_out main0(main0_in in [[stage_in]], constant type_Uniforms& Uniforms [[buffer(0)]], const device type_StructuredBuffer_Scene& scene [[buffer(1)]], uint gl_InstanceIndex [[instance_id]])
|
vertex main0_out main0(main0_in in [[stage_in]], constant type_Uniforms& Uniforms [[buffer(0)]], const device type_StructuredBuffer_Scene& scene [[buffer(1)]], uint gl_InstanceIndex [[instance_id]])
|
||||||
{
|
{
|
||||||
main0_out out = {};
|
main0_out out = {};
|
||||||
float4 _44 = float4(in.in_var_TEXCOORD0, 1.0);
|
float4 _46 = float4(in.in_var_TEXCOORD0, 1.0);
|
||||||
|
float4 _49 = scene._m0[gl_InstanceIndex].Model * _46;
|
||||||
out.out_var_TEXCOORD0 = in.in_var_TEXCOORD3;
|
out.out_var_TEXCOORD0 = in.in_var_TEXCOORD3;
|
||||||
out.out_var_TEXCOORD1 = (scene._m0[gl_InstanceIndex].Model * _44).xyz;
|
out.out_var_TEXCOORD1 = _49.xyz;
|
||||||
out.out_var_TEXCOORD2 = in.in_var_TEXCOORD1;
|
out.out_var_TEXCOORD2 = in.in_var_TEXCOORD1;
|
||||||
out.gl_Position = Uniforms.ViewProjection * (scene._m0[gl_InstanceIndex].Model * _44);
|
out.out_var_TEXCOORD3 = Uniforms.ShadowMapProjection * _49;
|
||||||
|
out.gl_Position = Uniforms.ViewProjection * (scene._m0[gl_InstanceIndex].Model * _46);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue