134 lines
3.9 KiB
Python
134 lines
3.9 KiB
Python
$input v_color0
|
|
$input v_normal
|
|
$input v_uv0
|
|
$input v_wpos
|
|
|
|
#include "../common.sh"
|
|
|
|
SAMPLER2D(s_texColor, 0);
|
|
SAMPLER3D(s_ditherSampler, 1);
|
|
SAMPLER2D(s_rampSampler, 2);
|
|
uniform vec4 u_time;
|
|
uniform vec4 u_dotColor;
|
|
uniform vec4 u_texInfo;
|
|
uniform vec4 u_baseColor;
|
|
|
|
float calcBrightness(vec3 lightPos, vec3 vertPos, vec3 normal)
|
|
{
|
|
vec3 lightDir = normalize(lightPos - vertPos);
|
|
float diffuse = max(0.0, dot(lightDir, normal));
|
|
return diffuse * clamp(1.0 - distance(lightPos, vertPos) * 0.01, 0.0, 1.0);
|
|
}
|
|
|
|
float calcBrightnessDirectional(vec3 sunDir, vec3 normal)
|
|
{
|
|
return max(0.0, dot(sunDir, normal));
|
|
}
|
|
|
|
vec3 desaturate(vec3 color)
|
|
{
|
|
return vec3_splat(dot(color, vec3(0.33, 0.34, 0.33)));
|
|
}
|
|
|
|
float dither(float brightness, vec2 inputUv)
|
|
{
|
|
float globalScale = 6;
|
|
|
|
// constants
|
|
float xRes = u_texInfo.z;
|
|
float dotsPerSide = xRes / 16;
|
|
float dotsTotal = dotsPerSide * dotsPerSide;
|
|
float invXRes = 1 / xRes;
|
|
float zRes = dotsTotal;
|
|
float invZRes = 1 / zRes;
|
|
|
|
vec2 rampLookupUv = vec2((0.5 * invXRes + (1 - invXRes) * brightness), 0.5);
|
|
float brightnessCurve = texture2D(s_rampSampler, rampLookupUv).r;
|
|
|
|
// Magic dot frequency calculation
|
|
vec2 dx = dFdx(inputUv);
|
|
vec2 dy = dFdy(inputUv);
|
|
mat2 mat = mat2(dx, dy);
|
|
vec4 vectorized = vec4(dx, dy);
|
|
float qq = dot(vectorized, vectorized);
|
|
float rr = determinant(mat);
|
|
float discriminantSqr = max(0.0, qq*qq - 4.0*rr*rr);
|
|
float discriminant = sqrt(discriminantSqr);
|
|
vec2 freq = sqrt(vec2(qq + discriminant, qq - discriminant) / 2.0);
|
|
|
|
// Figuring out how many dots we want
|
|
float scaleExp = exp2(globalScale);
|
|
float spacing = freq.y * scaleExp;
|
|
spacing *= dotsPerSide * (1 / globalScale); // todo: just guessed that globalScale is the right variable here
|
|
|
|
float brightnessSpacingMultiplier = pow(brightnessCurve * 2 + 0.001, -(1 - 0.5));
|
|
spacing *= brightnessSpacingMultiplier;
|
|
|
|
float spacingLog = log2(spacing);
|
|
int patternScaleLevel = int(floor(spacingLog));
|
|
float patternFractional = spacingLog - patternScaleLevel;
|
|
vec2 uv = inputUv / exp2(patternScaleLevel);
|
|
|
|
// patternFractional *= patternFractional;
|
|
// patternFractional = smoothstep(0, 1, patternFractional);
|
|
float subLayer = lerp(0.25 * dotsTotal, dotsTotal, 1 - patternFractional);
|
|
subLayer = (subLayer - 0.5) * invZRes;
|
|
|
|
float pattern = texture3D(s_ditherSampler, vec3(uv, subLayer)).r;
|
|
|
|
float contrast = 0.5 * scaleExp * brightnessSpacingMultiplier * 0.1;
|
|
contrast *= pow(freq.y / freq.x, 1.0);
|
|
float baseVal = lerp(0.5, brightness, saturate(1.05 / (1 + contrast)));
|
|
float threshold = 1 - brightnessCurve;
|
|
|
|
return saturate((pattern - threshold) * contrast + baseVal);
|
|
}
|
|
|
|
vec4 rgbToCmyk(vec3 rgb)
|
|
{
|
|
return vec4(1.0, 1.0, 1.0, 1.0);
|
|
}
|
|
|
|
vec3 cmykToRgb(vec4 cmyk)
|
|
{
|
|
return vec3(1.0, 1.0, 1.0);
|
|
}
|
|
|
|
vec2 rotateUV(vec2 uv, vec2 angle)
|
|
{
|
|
return uv;
|
|
}
|
|
|
|
void main()
|
|
{
|
|
// setup
|
|
bool isTextured = u_dotColor.x < 0.02;
|
|
float testRadius = 30.0;
|
|
float testSpeed = 1.0;
|
|
vec3 testOffset = vec3(0.0, 0.0, 50.0);
|
|
vec3 lightPos = vec3(sin(u_time.x * testSpeed) * testRadius, 5.0, cos(u_time.x * testSpeed) * testRadius);
|
|
vec3 baseColor = u_baseColor.xyz;
|
|
vec3 texColor = isTextured ? texture2D(s_texColor, v_uv0).xyz : u_dotColor.xyz;
|
|
|
|
// lighting
|
|
float brightness = lerp(0.2, 0.8, calcBrightnessDirectional(vec3(0.5, 0.3, 1.0), v_normal));
|
|
|
|
// dither
|
|
float r = dither(texColor.r * brightness, v_uv0);
|
|
float g = dither(texColor.g * brightness, v_uv0);
|
|
float b = dither(texColor.b * brightness, v_uv0);
|
|
vec3 ditheredColor = vec3(r,g,b);
|
|
|
|
vec4 cmyk = rgbToCmyk(texColor * brightness);
|
|
cmyk.x = dither(cmyk.x, rotateUV(v_uv0, float2(0.966, 0.259)));
|
|
cmyk.y = dither(cmyk.y, rotateUV(v_uv0, float2(0.259, 0.966)));
|
|
cmyk.z = dither(cmyk.z, rotateUV(v_uv0, float2(1.000, 0.000)));
|
|
cmyk.w = dither(cmyk.w, rotateUV(v_uv0, float2(0.707, 0.707)));
|
|
// vec3 ditheredColor = cmykToRgb(cmyk);
|
|
|
|
// finalize
|
|
vec3 finalColor = mix(baseColor, ditheredColor, ditheredColor);
|
|
gl_FragColor = vec4(finalColor, 1.0);
|
|
// gl_FragColor = vec4(texColor * brightness, 1.0);
|
|
}
|