127 lines
4.7 KiB
Plaintext
127 lines
4.7 KiB
Plaintext
#version 120
|
|
|
|
/*
|
|
Copyright (C) 2010-2017 Kristian Duske
|
|
|
|
This file is part of TrenchBroom.
|
|
|
|
TrenchBroom is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
TrenchBroom is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with TrenchBroom. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
float getSoftStripes(float value, float gridSize, float stripeSize) {
|
|
float mainVal = value * gridSize;
|
|
float filterWidth = fwidth(value);
|
|
float edge = filterWidth * gridSize * 2.0;
|
|
|
|
// major line shading, currently set to place a major line every 64 units
|
|
float mValue = 1.0 / (64.0 * gridSize);
|
|
float triMajor = abs(2.0 * fract(mainVal * mValue) - 1.0);
|
|
float isMajor = step(1.0 - mValue, triMajor);
|
|
|
|
float outIntensity = isMajor * 0.7 + 0.85; // tweak intensities here
|
|
float sSize = stripeSize;
|
|
|
|
float triangle = abs(2.0 * fract(mainVal) - 1.0);
|
|
return smoothstep(sSize - edge, sSize + edge, triangle) * outIntensity;
|
|
}
|
|
|
|
/**
|
|
* Draws two overlaid grids
|
|
*
|
|
* @param inCoords fragment coordinates (TODO: document units)
|
|
* @param gridRatio the reciprocal of the first grid size, e.g. (1/16) for a 16 unit grid
|
|
* @param gridRatio2 the reciprocal of the second grid size, e.g. (1/16) for a 16 unit grid
|
|
* @param lineWidth the line width (TODO: document units)
|
|
* @param gridBlend the fraction of the two grids to draw, between 0 and 1,
|
|
* where 0.0 means 100% of grid one, and 1.0 means 100% of grid two.
|
|
*/
|
|
float gridLinesSoft(vec2 inCoords, float gridRatio, float gridRatio2, float lineWidth, float gridBlend) {
|
|
float stripeRatio = lineWidth * gridRatio;
|
|
float stripeRatio2 = lineWidth * gridRatio2;
|
|
float stripeSize = 1.0 - stripeRatio;
|
|
float stripeSize2 = 1.0 - stripeRatio2;
|
|
|
|
float theGrid, nextGrid;
|
|
|
|
theGrid = getSoftStripes(inCoords.x, gridRatio, stripeSize);
|
|
theGrid = max(theGrid, getSoftStripes(inCoords.y, gridRatio, stripeSize));
|
|
nextGrid = getSoftStripes(inCoords.x, gridRatio2, stripeSize2);
|
|
nextGrid = max(nextGrid, getSoftStripes(inCoords.y, gridRatio2, stripeSize2));
|
|
|
|
theGrid = mix(theGrid, nextGrid, gridBlend);
|
|
|
|
return theGrid * 0.5;
|
|
}
|
|
|
|
/**
|
|
* Given a valid grid size, returns the next larger one.
|
|
*/
|
|
float gridNextLarger(float size) {
|
|
return 2.0 * size;
|
|
}
|
|
|
|
/**
|
|
* Given any size, finds the next smaller size that is a proper grid size.
|
|
* Returns the input unmodified if it's already a grid size.
|
|
*/
|
|
float gridFloor(float size) {
|
|
return exp2(floor(log2(size)));
|
|
}
|
|
|
|
/*
|
|
* Computes the grid for the current fragment with the given parameters.
|
|
*
|
|
* @param coords the coordinates of the fragment in world space (same units as gridSize)
|
|
* @param normal the normal vector of the fragment
|
|
* @param gridSize the actual size of the grid (e.g. 16, 32, 64, etc.)
|
|
* @param minGridSize the minimal grid size to render (to fade out smaller grids to prevent moire etc.)
|
|
* @param lineWidthFactor a factor for the line width of the grid
|
|
*
|
|
* @return opacity of the grid line to draw on this fragment, in [0..1]
|
|
*/
|
|
float grid(vec3 coords, vec3 normal, float gridSize, float minGridSize, float lineWidthFactor) {
|
|
float lineWidth = (gridSize < 1.0 ? (1.0 / 32.0)
|
|
: (gridSize < 4.0 ? 0.25 : 0.5)) * lineWidthFactor;
|
|
|
|
// magic number to make the grid fade sooner, preventing aliasing
|
|
float minGridSizeToRender = minGridSize * 2.0;
|
|
|
|
float baseGridSize = gridFloor(minGridSizeToRender);
|
|
if (gridSize > baseGridSize) {
|
|
baseGridSize = gridSize;
|
|
}
|
|
float nextGridSize = gridNextLarger(baseGridSize);
|
|
|
|
// This is 0 if we want to render just baseGridSize, and 1 if we want to fully render at nextGridSize
|
|
float gridBlend = smoothstep(baseGridSize, nextGridSize, minGridSizeToRender);
|
|
|
|
float gridRatio = 1.0 / baseGridSize;
|
|
float gridRatio2 = 1.0 / nextGridSize;
|
|
|
|
vec2 baseCoords; // coordinates used for overlay creation
|
|
|
|
if (abs(normal.x) > abs(normal.y)) {
|
|
if (abs(normal.x) > abs(normal.z))
|
|
baseCoords = coords.yz;
|
|
else
|
|
baseCoords = coords.xy;
|
|
} else if (abs(normal.y) > abs(normal.z)) {
|
|
baseCoords = coords.xz;
|
|
} else {
|
|
baseCoords = coords.xy;
|
|
}
|
|
|
|
return gridLinesSoft(baseCoords, gridRatio, gridRatio2, lineWidth, gridBlend);
|
|
}
|