Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

example shadow #1200

Merged
merged 3 commits into from
Feb 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions Linux/App/example/shader/glsl/default3d_forward_shadow_depth.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright (c) 2008-2023 Ryo Suzuki.
// Copyright (c) 2016-2023 OpenSiv3D Project.
// Licensed under the MIT License.

# version 410

//
// Textures
//
uniform sampler2D Texture0;

//
// PSInput
//
layout(location = 0) in vec3 WorldPosition;
layout(location = 1) in vec2 UV;
layout(location = 2) in vec3 Normal;

//
// PSOutput
//
layout(location = 0) out vec2 FragColor;

//
// Constant Buffer
//
layout(std140) uniform PSPerFrame // slot 0
{
vec3 g_globalAmbientColor;
vec3 g_sunColor;
vec3 g_sunDirection;
};

layout(std140) uniform PSPerView // slot 1
{
vec3 g_eyePosition;
};

layout(std140) uniform PSPerMaterial // slot 3
{
vec3 g_ambientColor;
uint g_hasTexture;
vec4 g_diffuseColor;
vec3 g_specularColor;
float g_shininess;
vec3 g_emissionColor;
};

////////////////////////////////////////////////////////////
//
// Depth
//

layout(std140) uniform PSShadow // slot 4
{
mat4x4 g_worldToProjectedShadow;
vec3 g_sunPosition;
float g_lightBleedingReduction;
};

void main()
{
float depth = length(g_sunPosition - WorldPosition);
FragColor = vec2(depth, (depth * depth));
}

//
////////////////////////////////////////////////////////////
150 changes: 150 additions & 0 deletions Linux/App/example/shader/glsl/default3d_forward_shadow_shading.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
// Copyright (c) 2008-2023 Ryo Suzuki.
// Copyright (c) 2016-2023 OpenSiv3D Project.
// Licensed under the MIT License.

# version 410

//
// Textures
//
uniform sampler2D Texture0;

//
// PSInput
//
layout(location = 0) in vec3 WorldPosition;
layout(location = 1) in vec2 UV;
layout(location = 2) in vec3 Normal;

//
// PSOutput
//
layout(location = 0) out vec4 FragColor;

//
// Constant Buffer
//
layout(std140) uniform PSPerFrame // slot 0
{
vec3 g_globalAmbientColor;
vec3 g_sunColor;
vec3 g_sunDirection;
};

layout(std140) uniform PSPerView // slot 1
{
vec3 g_eyePosition;
};

layout(std140) uniform PSPerMaterial // slot 3
{
vec3 g_ambientColor;
uint g_hasTexture;
vec4 g_diffuseColor;
vec3 g_specularColor;
float g_shininess;
vec3 g_emissionColor;
};

//
// Functions
//
vec4 GetDiffuseColor(vec2 uv)
{
vec4 diffuseColor = g_diffuseColor;

if (g_hasTexture == 1)
{
diffuseColor *= texture(Texture0, uv);
}

return diffuseColor;
}

vec3 CalculateDiffuseReflection(vec3 n, vec3 l, vec3 lightColor, vec3 diffuseColor, vec3 ambientColor)
{
vec3 directColor = lightColor * max(dot(n, l), 0.0f);
return ((ambientColor + directColor) * diffuseColor);
}

vec3 CalculateSpecularReflection(vec3 n, vec3 h, float shininess, float nl, vec3 lightColor, vec3 specularColor)
{
float highlight = pow(max(dot(n, h), 0.0f), shininess) * float(0.0f < nl);
return (lightColor * specularColor * highlight);
}

////////////////////////////////////////////////////////////
//
// Shading
//

uniform sampler2D Texture1;

layout(std140) uniform PSShadow // slot 4
{
mat4x4 g_worldToProjectedShadow;
vec3 g_sunPosition;
float g_lightBleedingReduction;
};

float LineStep(float min, float max, float value)
{
return clamp((value - min) / (max - min), 0.0, 1.0);
}

float ReduceLightBleeding(float p_max, float amount)
{
return LineStep(amount, 1.0, p_max);
}

float CalculateShadow(vec3 worldPosition)
{
vec4 projectedPosition = (vec4(worldPosition, 1.0) * g_worldToProjectedShadow);

if (any(notEqual(clamp(projectedPosition.xyz, 0.0, 1.0), projectedPosition.xyz)))
{
return 1.0;
}

vec2 uv = vec2(projectedPosition.x, (1.0 - projectedPosition.y));
float depth = (length(g_sunPosition - worldPosition) - 0.03125);
vec2 moments = texture(Texture1, uv).rg;

if (depth <= moments.x)
{
return 1.0;
}

float variance = (moments.y - (moments.x * moments.x));
float d = (moments.x - depth);
float lit = (variance / (variance + (d * d)));

return ReduceLightBleeding(lit, g_lightBleedingReduction);
}

void main()
{
// Shadow
float lit = CalculateShadow(WorldPosition);

vec3 lightColor = (g_sunColor * lit);
vec3 lightDirection = g_sunDirection;

vec3 n = normalize(Normal);
vec3 l = lightDirection;
vec4 diffuseColor = GetDiffuseColor(UV);
vec3 ambientColor = (g_ambientColor * g_globalAmbientColor);

// Diffuse
vec3 diffuseReflection = CalculateDiffuseReflection(n, l, lightColor, diffuseColor.rgb, ambientColor);

// Specular
vec3 v = normalize(g_eyePosition - WorldPosition);
vec3 h = normalize(v + lightDirection);
vec3 specularReflection = CalculateSpecularReflection(n, h, g_shininess, dot(n, l), lightColor, g_specularColor);

FragColor = vec4(diffuseReflection + specularReflection + g_emissionColor, diffuseColor.a);
}

//
////////////////////////////////////////////////////////////
166 changes: 166 additions & 0 deletions Linux/App/example/shader/hlsl/default3d_forward_shadow.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
//-----------------------------------------------
//
// This file is part of the Siv3D Engine.
//
// Copyright (c) 2008-2023 Ryo Suzuki
// Copyright (c) 2016-2023 OpenSiv3D Project
//
// Licensed under the MIT License.
//
//-----------------------------------------------

//
// Textures
//
Texture2D g_texture0 : register(t0);
SamplerState g_sampler0 : register(s0);

namespace s3d
{
//
// VS Output / PS Input
//
struct PSInput
{
float4 position : SV_POSITION;
float3 worldPosition : TEXCOORD0;
float2 uv : TEXCOORD1;
float3 normal : TEXCOORD2;
};
}

//
// Constant Buffer
//
cbuffer PSPerFrame : register(b0)
{
float3 g_globalAmbientColor;
float3 g_sunColor;
float3 g_sunDirection;
}

cbuffer PSPerView : register(b1)
{
float3 g_eyePosition;
}

cbuffer PSPerMaterial : register(b3)
{
float3 g_ambientColor;
uint g_hasTexture;
float4 g_diffuseColor;
float3 g_specularColor;
float g_shininess;
float3 g_emissionColor;
}

float4 GetDiffuseColor(float2 uv)
{
float4 diffuseColor = g_diffuseColor;

if (g_hasTexture)
{
diffuseColor *= g_texture0.Sample(g_sampler0, uv);
}

return diffuseColor;
}

float3 CalculateDiffuseReflection(float3 n, float3 l, float3 lightColor, float3 diffuseColor, float3 ambientColor)
{
const float3 directColor = lightColor * saturate(dot(n, l));
return ((ambientColor + directColor) * diffuseColor);
}

float3 CalculateSpecularReflection(float3 n, float3 h, float shininess, float nl, float3 lightColor, float3 specularColor)
{
const float highlight = pow(saturate(dot(n, h)), shininess) * float(0.0 < nl);
return (lightColor * specularColor * highlight);
}

////////////////////////////////////////////////////////////
//
// Depth
//
cbuffer PSShadow : register(b4)
{
row_major float4x4 g_worldToProjectedShadow;
float3 g_sunPosition;
float g_lightBleedingReduction;
}

float2 Depth_PS(s3d::PSInput input) : SV_TARGET
{
const float depth = length(g_sunPosition - input.worldPosition);
return float2(depth, (depth * depth));
}
//
////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////
//
// Shading
//
Texture2D g_texture1 : register(t1);
SamplerState g_sampler1 : register(s1);

float LineStep(float min, float max, float value)
{
return saturate((value - min) / (max - min));
}

float ReduceLightBleeding(float p_max, float amount)
{
return LineStep(amount, 1.0, p_max);
}

float CalculateShadow(float3 worldPosition)
{
const float4 projectedPosition = mul(float4(worldPosition, 1.0), g_worldToProjectedShadow);

if (any(saturate(projectedPosition.xyz) != projectedPosition.xyz))
{
return 1.0;
}

const float2 uv = float2(projectedPosition.x, (1.0 - projectedPosition.y));
const float depth = (length(g_sunPosition - worldPosition) - 0.03125);
const float2 moments = g_texture1.Sample(g_sampler1, uv).rg;

if (depth <= moments.x)
{
return 1.0;
}

const float variance = (moments.y - (moments.x * moments.x));
const float d = (moments.x - depth);
const float lit = (variance / (variance + (d * d)));

return ReduceLightBleeding(lit, g_lightBleedingReduction);
}

float4 Shading_PS(s3d::PSInput input) : SV_TARGET
{
// Shadow
const float lit = CalculateShadow(input.worldPosition);

const float3 lightColor = (g_sunColor * lit);
const float3 lightDirection = g_sunDirection;

const float3 n = normalize(input.normal);
const float3 l = lightDirection;
float4 diffuseColor = GetDiffuseColor(input.uv);
const float3 ambientColor = (g_ambientColor * g_globalAmbientColor);

// Diffuse
const float3 diffuseReflection = CalculateDiffuseReflection(n, l, lightColor, diffuseColor.rgb, ambientColor);

// Specular
const float3 v = normalize(g_eyePosition - input.worldPosition);
const float3 h = normalize(v + lightDirection);
const float3 specularReflection = CalculateSpecularReflection(n, h, g_shininess, dot(n, l), lightColor, g_specularColor);

return float4(diffuseReflection + specularReflection + g_emissionColor, diffuseColor.a);
}
//
////////////////////////////////////////////////////////////
3 changes: 3 additions & 0 deletions Siv3D/include/Siv3D/Mat4x4.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ namespace s3d
float m30, float m31, float m32, float m33
) noexcept;

SIV3D_NODISCARD_CXX20
explicit Mat4x4(const float* p) noexcept;

SIV3D_NODISCARD_CXX20
explicit Mat4x4(Quaternion q) noexcept;

Expand Down
Loading
Loading