add infiniteGrid, rewrote the shadow , now the shadow is a simple hardware shadow
This commit is contained in:
226
Editor/assets/shaders/InfiniteGrid.glsl
Normal file
226
Editor/assets/shaders/InfiniteGrid.glsl
Normal file
@ -0,0 +1,226 @@
|
||||
// Infinite Grid Shader
|
||||
// Based on "The Best Darn Grid Shader (Yet)" by Ben Golus
|
||||
|
||||
#type vertex
|
||||
#version 450 core
|
||||
|
||||
layout(location = 0) in vec3 a_Position;
|
||||
|
||||
// camera
|
||||
uniform mat4 u_View;
|
||||
uniform mat4 u_Projection;
|
||||
uniform vec3 u_CameraPosition;
|
||||
|
||||
out CameraData{
|
||||
mat4 View;
|
||||
mat4 Projection;
|
||||
vec3 CameraPosition;
|
||||
}CameraOutput;
|
||||
|
||||
out vec3 v_NearPoint;
|
||||
out vec3 v_FarPoint;
|
||||
|
||||
vec3 unprojectPoint(float x, float y, float z) {
|
||||
mat4 viewInv = inverse(u_View);
|
||||
mat4 projInv = inverse(u_Projection);
|
||||
vec4 unprojectedPoint = viewInv * projInv * vec4(x, y, z, 1.0);
|
||||
return unprojectedPoint.xyz / unprojectedPoint.w;
|
||||
}
|
||||
|
||||
void main() {
|
||||
v_NearPoint = unprojectPoint(a_Position.x, a_Position.y, 0.0);
|
||||
v_FarPoint = unprojectPoint(a_Position.x, a_Position.y, 1.0);
|
||||
|
||||
CameraOutput.View = u_View;
|
||||
CameraOutput.Projection = u_Projection;
|
||||
CameraOutput.CameraPosition = u_CameraPosition;
|
||||
|
||||
gl_Position = vec4(a_Position, 1.0);
|
||||
}
|
||||
|
||||
#type fragment
|
||||
#version 450 core
|
||||
|
||||
layout(location = 0) out vec4 o_Color;
|
||||
|
||||
in vec3 v_NearPoint;
|
||||
in vec3 v_FarPoint;
|
||||
|
||||
in CameraData{
|
||||
mat4 View;
|
||||
mat4 Projection;
|
||||
vec3 CameraPosition;
|
||||
}CameraInput;
|
||||
|
||||
// Grid plane: 0 = XZ (Y up), 1 = XY (Z forward), 2 = YZ (X right)
|
||||
uniform int u_GridPlane = 0;
|
||||
uniform float u_GridScale = 1.0;
|
||||
uniform vec4 u_GridColorThin = vec4(0.5, 0.5, 0.5, 0.4);
|
||||
uniform vec4 u_GridColorThick = vec4(0.5, 0.5, 0.5, 0.6);
|
||||
uniform vec4 u_AxisColorX = vec4(0.9, 0.2, 0.2, 1.0);
|
||||
uniform vec4 u_AxisColorZ = vec4(0.2, 0.2, 0.9, 1.0);
|
||||
uniform float u_FadeDistance = 500.0;
|
||||
|
||||
float computeDepth(vec3 pos) {
|
||||
vec4 clipSpacePos = CameraInput.Projection * CameraInput.View * vec4(pos, 1.0);
|
||||
return clipSpacePos.z / clipSpacePos.w;
|
||||
}
|
||||
|
||||
// Get the plane normal based on grid plane type
|
||||
vec3 getPlaneNormal() {
|
||||
if (u_GridPlane == 1) return vec3(0.0, 0.0, 1.0); // XY plane, Z normal
|
||||
if (u_GridPlane == 2) return vec3(1.0, 0.0, 0.0); // YZ plane, X normal
|
||||
return vec3(0.0, 1.0, 0.0); // XZ plane, Y normal (default)
|
||||
}
|
||||
|
||||
// Get 2D coordinates on the plane
|
||||
vec2 getPlaneCoords(vec3 pos) {
|
||||
if (u_GridPlane == 1) return pos.xy; // XY plane
|
||||
if (u_GridPlane == 2) return pos.yz; // YZ plane
|
||||
return pos.xz; // XZ plane (default)
|
||||
}
|
||||
|
||||
// Get the component perpendicular to the plane (for axis drawing)
|
||||
vec2 getAxisCoords(vec3 pos) {
|
||||
// Returns the two coordinates used for drawing axis lines
|
||||
// First component -> first axis color, Second component -> second axis color
|
||||
if (u_GridPlane == 1) return vec2(pos.x, pos.y); // XY: X-axis and Y-axis
|
||||
if (u_GridPlane == 2) return vec2(pos.y, pos.z); // YZ: Y-axis and Z-axis
|
||||
return vec2(pos.x, pos.z); // XZ: X-axis and Z-axis
|
||||
}
|
||||
|
||||
// Calculate t for ray-plane intersection
|
||||
float rayPlaneIntersection(vec3 nearPoint, vec3 farPoint) {
|
||||
vec3 rayDir = farPoint - nearPoint;
|
||||
|
||||
if (u_GridPlane == 1) {
|
||||
// XY plane (z = 0)
|
||||
if (abs(rayDir.z) < 0.0001) return -1.0;
|
||||
return -nearPoint.z / rayDir.z;
|
||||
}
|
||||
if (u_GridPlane == 2) {
|
||||
// YZ plane (x = 0)
|
||||
if (abs(rayDir.x) < 0.0001) return -1.0;
|
||||
return -nearPoint.x / rayDir.x;
|
||||
}
|
||||
// XZ plane (y = 0) - default
|
||||
if (abs(rayDir.y) < 0.0001) return -1.0;
|
||||
return -nearPoint.y / rayDir.y;
|
||||
}
|
||||
|
||||
// Get view angle component for normal fade
|
||||
float getViewAngleComponent(vec3 viewDir) {
|
||||
if (u_GridPlane == 1) return abs(viewDir.z); // XY plane
|
||||
if (u_GridPlane == 2) return abs(viewDir.x); // YZ plane
|
||||
return abs(viewDir.y); // XZ plane
|
||||
}
|
||||
|
||||
// Pristine grid - single pixel line with proper AA
|
||||
float pristineGridLine(vec2 uv) {
|
||||
vec2 dudv = fwidth(uv);
|
||||
vec2 uvMod = fract(uv);
|
||||
vec2 uvDist = min(uvMod, 1.0 - uvMod);
|
||||
vec2 distInPixels = uvDist / dudv;
|
||||
vec2 lineAlpha = 1.0 - smoothstep(0.0, 1.0, distInPixels);
|
||||
float alpha = max(lineAlpha.x, lineAlpha.y);
|
||||
float density = max(dudv.x, dudv.y);
|
||||
float densityFade = 1.0 - smoothstep(0.5, 1.0, density);
|
||||
return alpha * densityFade;
|
||||
}
|
||||
|
||||
// Axis line - single pixel wide
|
||||
float axisLineAA(float coord, float dudv) {
|
||||
float distInPixels = abs(coord) / dudv;
|
||||
return 1.0 - smoothstep(0.0, 1.5, distInPixels);
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
|
||||
float t = rayPlaneIntersection(v_NearPoint, v_FarPoint);
|
||||
|
||||
if (t < 0.0) {
|
||||
discard;
|
||||
}
|
||||
|
||||
vec3 fragPos3D = v_NearPoint + t * (v_FarPoint - v_NearPoint);
|
||||
float depth = computeDepth(fragPos3D);
|
||||
|
||||
if (depth > 1.0 || depth < -1.0) {
|
||||
discard;
|
||||
}
|
||||
|
||||
vec2 worldPos = getPlaneCoords(fragPos3D);
|
||||
|
||||
// === Fading ===
|
||||
|
||||
// Radial fade
|
||||
float dist = length(fragPos3D - CameraInput.CameraPosition);
|
||||
float radialFade = 1.0 - smoothstep(u_FadeDistance * 0.3, u_FadeDistance, dist);
|
||||
|
||||
// Normal fade (view angle)
|
||||
vec3 viewDir = normalize(fragPos3D - CameraInput.CameraPosition);
|
||||
float viewAngle = getViewAngleComponent(viewDir);
|
||||
float normalFade = smoothstep(0.0, 0.15, viewAngle);
|
||||
|
||||
float fadeFactor = radialFade * normalFade;
|
||||
|
||||
if (fadeFactor < 0.001) {
|
||||
discard;
|
||||
}
|
||||
|
||||
// === Grid calculation ===
|
||||
|
||||
vec2 gridCoord1 = worldPos / u_GridScale;
|
||||
vec2 gridCoord10 = worldPos / (u_GridScale * 10.0);
|
||||
|
||||
float grid1 = pristineGridLine(gridCoord1);
|
||||
float grid10 = pristineGridLine(gridCoord10);
|
||||
|
||||
// LOD blend
|
||||
vec2 deriv1 = fwidth(gridCoord1);
|
||||
float lodFactor = smoothstep(0.3, 0.6, max(deriv1.x, deriv1.y));
|
||||
|
||||
// Combine grids
|
||||
float gridIntensity = mix(max(grid1, grid10 * 0.7), grid10, lodFactor);
|
||||
|
||||
// Grid color
|
||||
vec3 gridColor = mix(u_GridColorThin.rgb, u_GridColorThick.rgb, lodFactor);
|
||||
float baseAlpha = mix(u_GridColorThin.a, u_GridColorThick.a, lodFactor);
|
||||
float gridAlpha = baseAlpha * gridIntensity * fadeFactor;
|
||||
|
||||
// === Axis lines ===
|
||||
|
||||
vec2 axisCoords = getAxisCoords(fragPos3D);
|
||||
vec2 worldDeriv = fwidth(worldPos);
|
||||
|
||||
// First axis (uses AxisColorX - typically red)
|
||||
float axis1Alpha = axisLineAA(axisCoords.y, worldDeriv.y) * fadeFactor;
|
||||
// Second axis (uses AxisColorZ - typically blue)
|
||||
float axis2Alpha = axisLineAA(axisCoords.x, worldDeriv.x) * fadeFactor;
|
||||
|
||||
// === Final composition ===
|
||||
|
||||
vec3 finalColor = gridColor;
|
||||
float finalAlpha = gridAlpha;
|
||||
|
||||
// Blend axis colors
|
||||
if (axis2Alpha > 0.001) {
|
||||
float blend = axis2Alpha * u_AxisColorZ.a;
|
||||
finalColor = mix(finalColor, u_AxisColorZ.rgb, blend);
|
||||
finalAlpha = max(finalAlpha, blend);
|
||||
}
|
||||
|
||||
if (axis1Alpha > 0.001) {
|
||||
float blend = axis1Alpha * u_AxisColorX.a;
|
||||
finalColor = mix(finalColor, u_AxisColorX.rgb, blend);
|
||||
finalAlpha = max(finalAlpha, blend);
|
||||
}
|
||||
|
||||
if (finalAlpha < 0.001) {
|
||||
discard;
|
||||
}
|
||||
|
||||
gl_FragDepth = depth * 0.5 + 0.5;
|
||||
o_Color = vec4(finalColor, finalAlpha);
|
||||
}
|
||||
Reference in New Issue
Block a user