mirror of
https://github.com/4sval/FModel.git
synced 2026-06-21 07:20:05 -05:00
improved maths for point & spot lights to make them look more realistic
This commit is contained in:
parent
b5aecebaf1
commit
e5b66bb8d9
|
|
@ -48,13 +48,35 @@ struct Parameters
|
|||
float UVScale;
|
||||
};
|
||||
|
||||
struct Light {
|
||||
struct BaseLight
|
||||
{
|
||||
vec4 Color;
|
||||
vec3 Position;
|
||||
float Intensity;
|
||||
};
|
||||
|
||||
vec2 Direction;
|
||||
float ConeAngle;
|
||||
//struct PointLight
|
||||
//{
|
||||
// BaseLight Light;
|
||||
//
|
||||
// float Linear;
|
||||
// float Quadratic;
|
||||
//};
|
||||
//
|
||||
//struct SpotLight
|
||||
//{
|
||||
// BaseLight Light;
|
||||
//
|
||||
// float InnerConeAngle;
|
||||
// float OuterConeAngle;
|
||||
// float Attenuation;
|
||||
//};
|
||||
|
||||
struct Light {
|
||||
BaseLight Base;
|
||||
|
||||
float InnerConeAngle;
|
||||
float OuterConeAngle;
|
||||
float Attenuation;
|
||||
|
||||
float Linear;
|
||||
|
|
@ -68,9 +90,8 @@ uniform Light uLights[MAX_LIGHT_COUNT];
|
|||
uniform int uNumLights;
|
||||
uniform int uNumTexCoords;
|
||||
uniform bool uHasVertexColors;
|
||||
uniform vec3 uViewPos;
|
||||
uniform vec3 uViewDir;
|
||||
uniform bool bVertexColors[6];
|
||||
uniform vec3 uViewPos;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
|
|
@ -117,17 +138,16 @@ float geomSmith(float roughness, float dp)
|
|||
return dp / denom;
|
||||
}
|
||||
|
||||
vec3 CalcCameraLight(int layer, vec3 normals)
|
||||
vec3 CalcLight(int layer, vec3 normals, vec3 position, vec3 color, float attenuation, bool global)
|
||||
{
|
||||
vec3 fLambert = SamplerToVector(uParameters.Diffuse[layer].Sampler).rgb * uParameters.Diffuse[layer].Color.rgb;
|
||||
vec3 specular_masks = SamplerToVector(uParameters.SpecularMasks[layer].Sampler).rgb;
|
||||
float roughness = max(0.0f, specular_masks.b * uParameters.Roughness);
|
||||
|
||||
vec3 intensity = vec3(1.0f) * 1.0;
|
||||
vec3 l = -uViewDir;
|
||||
vec3 l = normalize(uViewPos - fPos);
|
||||
|
||||
vec3 n = normals;
|
||||
vec3 v = normalize(uViewPos - fPos);
|
||||
vec3 v = normalize(position - fPos);
|
||||
vec3 h = normalize(v + l);
|
||||
|
||||
float nDotH = max(dot(n, h), 0.0);
|
||||
|
|
@ -145,8 +165,43 @@ vec3 CalcCameraLight(int layer, vec3 normals)
|
|||
float specBrdfDenom = 4.0 * nDotV * nDotL + 0.0001;
|
||||
vec3 specBrdf = uParameters.Specular * specular_masks.r * specBrdfNom / specBrdfDenom;
|
||||
|
||||
vec3 diffuseBrdf = kD * fLambert / PI;
|
||||
return (diffuseBrdf + specBrdf) * intensity * nDotL;
|
||||
vec3 diffuseBrdf = fLambert;
|
||||
if (!global) diffuseBrdf = kD * fLambert / PI;
|
||||
return (diffuseBrdf + specBrdf) * color * nDotL * attenuation;
|
||||
}
|
||||
|
||||
vec3 CalcBaseLight(int layer, vec3 normals, BaseLight base, float attenuation, bool global)
|
||||
{
|
||||
return CalcLight(layer, normals, base.Position, base.Color.rgb * base.Intensity, attenuation, global);
|
||||
}
|
||||
|
||||
vec3 CalcPointLight(int layer, vec3 normals, Light light)
|
||||
{
|
||||
float distanceToLight = length(light.Base.Position - fPos);
|
||||
float attenuation = 1.0 / (1.0 + light.Linear * distanceToLight + light.Quadratic * pow(distanceToLight, 2));
|
||||
return CalcBaseLight(layer, normals, light.Base, attenuation, true);
|
||||
}
|
||||
|
||||
vec3 CalcSpotLight(int layer, vec3 normals, Light light)
|
||||
{
|
||||
vec3 v = normalize(light.Base.Position - fPos);
|
||||
float inner = cos(radians(light.InnerConeAngle));
|
||||
float outer = cos(radians(light.OuterConeAngle));
|
||||
|
||||
float distanceToLight = length(light.Base.Position - fPos);
|
||||
float theta = dot(v, normalize(-vec3(0, -1, 0)));
|
||||
float epsilon = inner - outer;
|
||||
float attenuation = 1.0 / (1.0 + light.Attenuation * pow(distanceToLight, 2));
|
||||
light.Base.Intensity *= smoothstep(0.0, 1.0, (theta - outer) / epsilon);
|
||||
|
||||
if(theta > outer)
|
||||
{
|
||||
return CalcBaseLight(layer, normals, light.Base, attenuation, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
return vec3(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
void main()
|
||||
|
|
@ -190,29 +245,19 @@ void main()
|
|||
|
||||
if (!bVertexColors[1])
|
||||
{
|
||||
result += CalcCameraLight(layer, normals);
|
||||
result += CalcLight(layer, normals, uViewPos, vec3(0.75), 1.0, false);
|
||||
|
||||
vec3 lights = vec3(uNumLights > 0 ? 0 : 1);
|
||||
for (int i = 0; i < uNumLights; i++)
|
||||
{
|
||||
float attenuation = 0.0;
|
||||
float distanceToLight = length(uLights[i].Position - fPos);
|
||||
|
||||
if (uLights[i].Type == 0)
|
||||
{
|
||||
attenuation = 1.0 / (1.0 + uLights[i].Linear * distanceToLight + uLights[i].Quadratic * pow(distanceToLight, 2));
|
||||
lights += CalcPointLight(layer, normals, uLights[i]);
|
||||
}
|
||||
else if (uLights[i].Type == 1)
|
||||
{
|
||||
float theta = dot(normalize(uLights[i].Position - fPos), normalize(-vec3(uLights[i].Direction.x, -uLights[i].Attenuation, uLights[i].Direction.y)));
|
||||
if(theta > uLights[i].ConeAngle)
|
||||
{
|
||||
attenuation = 1.0 / (1.0 + uLights[i].Attenuation * pow(distanceToLight, 2));
|
||||
}
|
||||
lights += CalcSpotLight(layer, normals, uLights[i]);
|
||||
}
|
||||
|
||||
vec3 intensity = uLights[i].Color.rgb * uLights[i].Intensity;
|
||||
lights += result * intensity * attenuation;
|
||||
}
|
||||
result *= lights; // use * to darken the scene, + to lighten it
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ public abstract class Light : IDisposable
|
|||
var r = light.GetOrDefault("RelativeRotation", parent.GetOrDefault("RelativeRotation", FRotator.ZeroRotator));
|
||||
|
||||
Transform = Transform.Identity;
|
||||
Transform.Scale = new FVector(0.25f);
|
||||
Transform.Scale = new FVector(0.2f);
|
||||
Transform.Position = position + r.RotateVector(p.ToMapVector()) * Constants.SCALE_DOWN_RATIO;
|
||||
|
||||
Model = model;
|
||||
|
|
@ -84,9 +84,9 @@ public abstract class Light : IDisposable
|
|||
|
||||
public virtual void Render(int i, Shader shader)
|
||||
{
|
||||
shader.SetUniform($"uLights[{i}].Color", Color);
|
||||
shader.SetUniform($"uLights[{i}].Position", Transform.Position);
|
||||
shader.SetUniform($"uLights[{i}].Intensity", Intensity);
|
||||
shader.SetUniform($"uLights[{i}].Base.Color", Color);
|
||||
shader.SetUniform($"uLights[{i}].Base.Position", Transform.Position);
|
||||
shader.SetUniform($"uLights[{i}].Base.Intensity", Intensity);
|
||||
}
|
||||
|
||||
public virtual void ImGuiLight()
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ public class Renderer : IDisposable
|
|||
if (ShowSkybox) _skybox.Render(viewMatrix, projMatrix);
|
||||
if (ShowGrid) _grid.Render(viewMatrix, projMatrix, cam.Near, cam.Far);
|
||||
|
||||
_shader.Render(viewMatrix, cam.Position, cam.Direction, projMatrix);
|
||||
_shader.Render(viewMatrix, cam.Position, projMatrix);
|
||||
for (int i = 0; i < 6; i++)
|
||||
_shader.SetUniform($"bVertexColors[{i}]", i == VertexColor);
|
||||
|
||||
|
|
|
|||
|
|
@ -56,11 +56,6 @@ public class Shader : IDisposable
|
|||
GL.UseProgram(_handle);
|
||||
}
|
||||
|
||||
public void Render(Matrix4x4 viewMatrix, Vector3 viewPos, Vector3 viewDir, Matrix4x4 projMatrix)
|
||||
{
|
||||
Render(viewMatrix, viewPos, projMatrix);
|
||||
SetUniform("uViewDir", viewDir);
|
||||
}
|
||||
public void Render(Matrix4x4 viewMatrix, Vector3 viewPos, Matrix4x4 projMatrix)
|
||||
{
|
||||
Render(viewMatrix, projMatrix);
|
||||
|
|
|
|||
|
|
@ -587,6 +587,7 @@ hello world!
|
|||
if (ImGui.CollapsingHeader("Textures") && material.ImGuiTextures(icons, model))
|
||||
{
|
||||
_ti_open = true;
|
||||
ImGui.SetWindowFocus("Texture Inspector");
|
||||
}
|
||||
|
||||
ImGui.SetNextItemOpen(true, ImGuiCond.Appearing);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
using System;
|
||||
using System.Numerics;
|
||||
using CUE4Parse.UE4.Assets.Exports;
|
||||
using CUE4Parse.UE4.Assets.Exports;
|
||||
using CUE4Parse.UE4.Objects.Core.Math;
|
||||
using CUE4Parse.UE4.Objects.Core.Misc;
|
||||
using ImGuiNET;
|
||||
|
|
@ -9,9 +7,9 @@ namespace FModel.Views.Snooper;
|
|||
|
||||
public class SpotLight : Light
|
||||
{
|
||||
public Vector2 Direction; // ???
|
||||
public float Attenuation;
|
||||
public float ConeAngle;
|
||||
public float InnerConeAngle;
|
||||
public float OuterConeAngle;
|
||||
|
||||
public SpotLight(FGuid model, Texture icon, UObject parent, UObject spot, FVector position) : base(model, icon, parent, spot, position)
|
||||
{
|
||||
|
|
@ -19,17 +17,16 @@ public class SpotLight : Light
|
|||
Attenuation = 1.0f;
|
||||
|
||||
Attenuation *= Constants.SCALE_DOWN_RATIO;
|
||||
Direction = Vector2.Zero;
|
||||
ConeAngle = (spot.GetOrDefault("InnerConeAngle", 50.0f) + spot.GetOrDefault("OuterConeAngle", 60.0f)) / 2.0f;
|
||||
ConeAngle = MathF.Cos(Helper.DegreesToRadians(ConeAngle));
|
||||
InnerConeAngle = spot.GetOrDefault("InnerConeAngle", 50.0f);
|
||||
OuterConeAngle = spot.GetOrDefault("OuterConeAngle", 60.0f);
|
||||
}
|
||||
|
||||
public override void Render(int i, Shader shader)
|
||||
{
|
||||
base.Render(i, shader);
|
||||
shader.SetUniform($"uLights[{i}].Direction", Direction);
|
||||
shader.SetUniform($"uLights[{i}].Attenuation", Attenuation);
|
||||
shader.SetUniform($"uLights[{i}].ConeAngle", ConeAngle);
|
||||
shader.SetUniform($"uLights[{i}].InnerConeAngle", InnerConeAngle);
|
||||
shader.SetUniform($"uLights[{i}].OuterConeAngle", OuterConeAngle);
|
||||
|
||||
shader.SetUniform($"uLights[{i}].Type", 1);
|
||||
}
|
||||
|
|
@ -37,14 +34,11 @@ public class SpotLight : Light
|
|||
public override void ImGuiLight()
|
||||
{
|
||||
base.ImGuiLight();
|
||||
SnimGui.Layout("Direction");ImGui.PushID(3);
|
||||
ImGui.DragFloat2("", ref Direction, 0.01f);
|
||||
ImGui.PopID();SnimGui.Layout("Attenuation");ImGui.PushID(4);
|
||||
SnimGui.Layout("Attenuation");ImGui.PushID(3);
|
||||
ImGui.DragFloat("", ref Attenuation, 0.1f);ImGui.PopID();
|
||||
|
||||
var angle = Helper.RadiansToDegrees(MathF.Acos(ConeAngle));
|
||||
SnimGui.Layout("Cone Angle");ImGui.PushID(5);
|
||||
ImGui.DragFloat("", ref angle, 0.1f, 0.0f, 90.0f, "%.1f°");ImGui.PopID();
|
||||
ConeAngle = MathF.Cos(Helper.DegreesToRadians(angle));
|
||||
SnimGui.Layout("Inner Cone Angle");ImGui.PushID(4);
|
||||
ImGui.DragFloat("", ref InnerConeAngle, 0.1f, 0.0f, 90.0f, "%.1f°");ImGui.PopID();
|
||||
SnimGui.Layout("Outer Cone Angle");ImGui.PushID(5);
|
||||
ImGui.DragFloat("", ref OuterConeAngle, 0.1f, 0.0f, 90.0f, "%.1f°");ImGui.PopID();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user