infinite grid skid but it was pain in the ass

This commit is contained in:
4sval 2022-08-28 17:48:05 +02:00
parent dde7688f2e
commit 80e8f3f02d
8 changed files with 278 additions and 89 deletions

View File

@ -93,6 +93,10 @@
<None Remove="Resources\edit.png" />
<None Remove="Resources\go_to_directory.png" />
<None Remove="Resources\npcleftside.png" />
<None Remove="Resources\shader.frag" />
<None Remove="Resources\shader.vert" />
<None Remove="Resources\grid.frag" />
<None Remove="Resources\grid.vert" />
</ItemGroup>
<ItemGroup>
@ -102,6 +106,10 @@
<EmbeddedResource Include="Resources\Xml.xshd" />
<EmbeddedResource Include="Resources\Cpp.xshd" />
<EmbeddedResource Include="Resources\Changelog.xshd" />
<EmbeddedResource Include="Resources\shader.frag" />
<EmbeddedResource Include="Resources\shader.vert" />
<EmbeddedResource Include="Resources\grid.frag" />
<EmbeddedResource Include="Resources\grid.vert" />
</ItemGroup>
<ItemGroup>

View File

@ -0,0 +1,63 @@
#version 430 core
// --------------------- IN ---------------------
in OUT_IN_VARIABLES {
vec3 nearPoint;
vec3 farPoint;
mat4 proj;
mat4 view;
float near;
float far;
} inVar;
// --------------------- OUT --------------------
out vec4 FragColor;
// ------------------- UNIFORM ------------------
uniform vec3 uCamDir;
vec4 grid(vec3 fragPos, float scale) {
vec2 coord = fragPos.xz * scale;
vec2 derivative = fwidth(coord);
vec2 grid = abs(fract(coord - 0.5) - 0.5) / derivative;
float line = min(grid.x, grid.y);
float minimumz = min(derivative.y, 1) * 0.1;
float minimumx = min(derivative.x, 1) * 0.1;
vec4 color = vec4(0.149, 0.149, 0.188, 1.0 - min(line, 1.0));
if(abs(fragPos.x) < minimumx)
color.z = 1.0;
if(abs(fragPos.z) < minimumz)
color.x = 1.0;
return color;
}
float computeDepth(vec3 pos) {
vec4 clip_space_pos = inVar.proj * inVar.view * vec4(pos.xyz, 1.0);
float clip_space_depth = clip_space_pos.z / clip_space_pos.w;
float far = gl_DepthRange.far;
float near = gl_DepthRange.near;
float depth = (((far-near) * clip_space_depth) + near + far) / 2.0;
return depth;
}
float computeLinearDepth(vec3 pos) {
vec4 clip_space_pos = inVar.proj * inVar.view * vec4(pos.xyz, 1.0);
float clip_space_depth = (clip_space_pos.z / clip_space_pos.w) * 2.0 - 1.0;
float linearDepth = (2.0 * inVar.near * inVar.far) / (inVar.far + inVar.near - clip_space_depth * (inVar.far - inVar.near));
return linearDepth / inVar.far;
}
void main() {
float t = -inVar.nearPoint.y / (inVar.farPoint.y - inVar.nearPoint.y);
vec3 fragPos3D = inVar.nearPoint + t * (inVar.farPoint - inVar.nearPoint);
gl_FragDepth = computeDepth(fragPos3D);
float linearDepth = computeLinearDepth(fragPos3D);
float fading = max(0, (0.5 - linearDepth));
FragColor = (grid(fragPos3D, 10) + grid(fragPos3D, 1)) * float(t > 0);
FragColor.a *= fading;
}

View File

@ -0,0 +1,36 @@
#version 430 core
layout (location = 0) in vec3 vPos;
// --------------------- OUT ---------------------
out OUT_IN_VARIABLES {
vec3 nearPoint;
vec3 farPoint;
mat4 proj;
mat4 view;
float near;
float far;
} outVar;
uniform mat4 proj;
uniform mat4 view;
uniform float uNear;
uniform float uFar;
vec3 UnprojectPoint(vec2 xy, float z) {
mat4 viewInv = inverse(view);
mat4 projInv = inverse(proj);
vec4 unprojectedPoint = viewInv * projInv * vec4(xy, z, 1.0);
return unprojectedPoint.xyz / unprojectedPoint.w;
}
void main()
{
outVar.near = uNear;
outVar.far = uFar;
outVar.proj = proj;
outVar.view = view;
outVar.nearPoint = UnprojectPoint(vPos.xy, -1.0).xyz;
outVar.farPoint = UnprojectPoint(vPos.xy, 1.0).xyz;
gl_Position = vec4(vPos, 1.0f);
}

View File

@ -0,0 +1,52 @@
#version 330 core
in vec3 fPos;
in vec3 fNormal;
in vec2 fTexCoords;
struct Material {
sampler2D diffuse;
sampler2D normal;
sampler2D specular;
sampler2D metallic;
sampler2D emission;
float shininess;
};
struct Light {
vec3 position;
vec3 ambient;
vec3 diffuse;
vec3 specular;
};
uniform Material material;
uniform Light light;
uniform vec3 viewPos;
out vec4 FragColor;
void main()
{
// ambient
vec3 ambient = light.ambient * vec3(texture(material.diffuse, fTexCoords));
// diffuse
vec3 norm = texture(material.normal, fTexCoords).rgb;
norm = normalize(norm * 2.0 - 1.0);
vec3 lightDir = normalize(light.position - fPos);
float diff = max(dot(norm, lightDir), 0.0f);
vec3 diffuseMap = vec3(texture(material.diffuse, fTexCoords));
vec3 diffuse = light.diffuse * diff * diffuseMap;
// specular
vec3 viewDir = normalize(viewPos - fPos);
vec3 reflectDir = reflect(-lightDir, norm);
float spec = pow(max(dot(viewDir, reflectDir), 0.0f), material.shininess);
vec3 specularMap = vec3(texture(material.specular, fTexCoords));
vec3 specular = light.specular * spec * specularMap;
vec3 result = ambient + diffuse + specular;
FragColor = vec4(result, 1.0);
}

View File

@ -0,0 +1,22 @@
#version 330 core
layout (location = 0) in vec3 vPos;
layout (location = 1) in vec3 vNormal;
layout (location = 2) in vec2 vTexCoords;
uniform mat4 uModel;
uniform mat4 uView;
uniform mat4 uProjection;
out vec3 fPos;
out vec3 fNormal;
out vec2 fTexCoords;
void main()
{
gl_Position = uProjection * uView * uModel * vec4(vPos, 1.0);
fPos = vec3(uModel * vec4(vPos, 1.0));
fNormal = mat3(transpose(inverse(uModel))) * vNormal;
fTexCoords = vTexCoords;
}

View File

@ -0,0 +1,70 @@
using System;
using Silk.NET.OpenGL;
namespace FModel.Views.Snooper;
public class Grid : IDisposable
{
private uint _handle;
private GL _gl;
private BufferObject<uint> _ebo;
private BufferObject<float> _vbo;
private VertexArrayObject<float, uint> _vao;
private Shader _shader;
public readonly uint[] Indices = { 0, 1, 2, 3, 4, 5 };
public readonly float[] Vertices = {
1f, 1f, 0f,
-1f, -1f, 0f,
-1f, 1f, 0f,
-1f, -1f, 0f,
1f, 1f, 0f,
1f, -1f, 0
};
public Grid() {}
public void Setup(GL gl)
{
_gl = gl;
_handle = _gl.CreateProgram();
_shader = new Shader(_gl, "grid.vert", "grid.frag");
_ebo = new BufferObject<uint>(_gl, Indices, BufferTargetARB.ElementArrayBuffer);
_vbo = new BufferObject<float>(_gl, Vertices, BufferTargetARB.ArrayBuffer);
_vao = new VertexArrayObject<float, uint>(_gl, _vbo, _ebo);
_vao.VertexAttributePointer(0, 3, VertexAttribPointerType.Float, 3, 0); // position
}
public void Bind(Camera camera)
{
_gl.DepthMask(false);
_vao.Bind();
_shader.Use();
_shader.SetUniform("view", camera.GetViewMatrix());
_shader.SetUniform("proj", camera.GetProjectionMatrix());
_shader.SetUniform("uNear", -0.01f);
_shader.SetUniform("uFar", 100f);
_gl.DrawArrays(PrimitiveType.Triangles, 0, (uint) Indices.Length);
_gl.DepthMask(true);
}
public void Dispose()
{
_ebo.Dispose();
_vbo.Dispose();
_vao.Dispose();
_shader.Dispose();
_gl.DeleteProgram(_handle);
}
}

View File

@ -1,5 +1,7 @@
using System;
using System.IO;
using System.Numerics;
using System.Reflection;
using Silk.NET.OpenGL;
namespace FModel.Views.Snooper;
@ -9,104 +11,28 @@ public class Shader : IDisposable
private uint _handle;
private GL _gl;
private readonly string VertexShaderSource = @"
#version 330 core
layout (location = 0) in vec3 vPos;
layout (location = 1) in vec3 vNormal;
layout (location = 2) in vec2 vTexCoords;
public Shader(GL gl) : this(gl, "shader.vert", "shader.frag") {}
uniform mat4 uModel;
uniform mat4 uView;
uniform mat4 uProjection;
out vec3 fPos;
out vec3 fNormal;
out vec2 fTexCoords;
void main()
{
gl_Position = uProjection * uView * uModel * vec4(vPos, 1.0);
fPos = vec3(uModel * vec4(vPos, 1.0));
fNormal = mat3(transpose(inverse(uModel))) * vNormal;
fTexCoords = vTexCoords;
}
";
private readonly string FragmentShaderSource = @"
#version 330 core
in vec3 fPos;
in vec3 fNormal;
in vec2 fTexCoords;
struct Material {
sampler2D diffuse;
sampler2D normal;
sampler2D specular;
sampler2D metallic;
sampler2D emission;
float shininess;
};
struct Light {
vec3 position;
vec3 ambient;
vec3 diffuse;
vec3 specular;
};
uniform Material material;
uniform Light light;
uniform vec3 viewPos;
out vec4 FragColor;
void main()
{
// ambient
vec3 ambient = light.ambient * vec3(texture(material.diffuse, fTexCoords));
// diffuse
vec3 norm = texture(material.normal, fTexCoords).rgb;
norm = normalize(norm * 2.0 - 1.0);
vec3 lightDir = normalize(light.position - fPos);
float diff = max(dot(norm, lightDir), 0.0f);
vec3 diffuseMap = vec3(texture(material.diffuse, fTexCoords));
vec3 diffuse = light.diffuse * diff * diffuseMap;
// specular
vec3 viewDir = normalize(viewPos - fPos);
vec3 reflectDir = reflect(-lightDir, norm);
float spec = pow(max(dot(viewDir, reflectDir), 0.0f), material.shininess);
vec3 specularMap = vec3(texture(material.specular, fTexCoords));
vec3 specular = light.specular * spec * specularMap;
vec3 result = ambient + diffuse + specular;
FragColor = vec4(result, 1.0);
}
";
public Shader(GL gl)
public Shader(GL gl, string vertex, string fragment)
{
_gl = gl;
uint vertex = LoadShader(ShaderType.VertexShader, VertexShaderSource);
uint fragment = LoadShader(ShaderType.FragmentShader, FragmentShaderSource);
_handle = _gl.CreateProgram();
_gl.AttachShader(_handle, vertex);
_gl.AttachShader(_handle, fragment);
uint v = LoadShader(ShaderType.VertexShader, vertex);
uint f = LoadShader(ShaderType.FragmentShader, fragment);
_gl.AttachShader(_handle, v);
_gl.AttachShader(_handle, f);
_gl.LinkProgram(_handle);
_gl.GetProgram(_handle, GLEnum.LinkStatus, out var status);
if (status == 0)
{
throw new Exception($"Program failed to link with error: {_gl.GetProgramInfoLog(_handle)}");
}
_gl.DetachShader(_handle, vertex);
_gl.DetachShader(_handle, fragment);
_gl.DeleteShader(vertex);
_gl.DeleteShader(fragment);
_gl.DetachShader(_handle, v);
_gl.DetachShader(_handle, f);
_gl.DeleteShader(v);
_gl.DeleteShader(f);
}
public void Use()
@ -160,10 +86,13 @@ void main()
_gl.DeleteProgram(_handle);
}
private uint LoadShader(ShaderType type, string content)
private uint LoadShader(ShaderType type, string file)
{
var executingAssembly = Assembly.GetExecutingAssembly();
using var stream = executingAssembly.GetManifestResourceStream($"{executingAssembly.GetName().Name}.Resources.{file}");
using var reader = new StreamReader(stream);
uint handle = _gl.CreateShader(type);
_gl.ShaderSource(handle, content);
_gl.ShaderSource(handle, reader.ReadToEnd());
_gl.CompileShader(handle);
string infoLog = _gl.GetShaderInfoLog(handle);
if (!string.IsNullOrWhiteSpace(infoLog))

View File

@ -21,6 +21,7 @@ public class Snooper
private Vector2 _previousMousePosition;
private Model[] _models;
private Grid _grid;
public int Width { get; }
public int Height { get; }
@ -43,6 +44,7 @@ public class Snooper
_window.Render += OnRender;
_window.Closing += OnClose;
_grid = new Grid();
_models = new Model[1];
switch (export)
{
@ -88,7 +90,11 @@ public class Snooper
}
_gl = GL.GetApi(_window);
_gl.Enable(EnableCap.Blend);
_gl.Enable(EnableCap.DepthTest);
_gl.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
_grid.Setup(_gl);
foreach (var model in _models)
{
@ -101,6 +107,8 @@ public class Snooper
_gl.ClearColor(0.149f, 0.149f, 0.188f, 1.0f);
_gl.Clear((uint) ClearBufferMask.ColorBufferBit | (uint) ClearBufferMask.DepthBufferBit);
_grid.Bind(_camera);
foreach (var model in _models)
{
model.Bind(_camera);
@ -158,6 +166,7 @@ public class Snooper
private void OnClose()
{
_grid.Dispose();
foreach (var model in _models)
{
model.Dispose();