You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
127 lines
3.8 KiB
Plaintext
127 lines
3.8 KiB
Plaintext
shader_type spatial;
|
|
render_mode blend_mix, depth_draw_always, cull_back, diffuse_burley, specular_schlick_ggx;
|
|
|
|
uniform vec4 albedo : source_color = vec4(0.6f, 0.6f, 0.6f, 1.0f);
|
|
uniform sampler2D detail_texture;
|
|
uniform vec2 detail_texture_size = vec2(256.0f, 256.0f);
|
|
uniform float specular;
|
|
uniform float metallic : hint_range(0, 1) = 0.0f;
|
|
uniform float roughness : hint_range(0, 1) = 0.5f;
|
|
uniform float point_size : hint_range(0, 128);
|
|
|
|
varying vec3 Position;
|
|
varying vec3 Normal;
|
|
|
|
void vertex()
|
|
{
|
|
Position = VERTEX;
|
|
Normal = NORMAL;
|
|
}
|
|
|
|
float SquareAntialiased(float coord, float dd) // antialiased square wave
|
|
{
|
|
coord += dd * 0.5f;
|
|
|
|
dd = max(dd, 0.0001f);
|
|
float invdd = 1.0f / dd;
|
|
|
|
coord = mod(coord, 1.0f);
|
|
float c = min(coord * invdd, 0.5f - (coord - 0.5f) / dd + 0.5f);
|
|
c = clamp(c, 0.0f, 1.0f);
|
|
|
|
return c;
|
|
}
|
|
|
|
float SXOR(float a, float b) // "smooth" xor, used to combine checker patterns
|
|
{
|
|
return abs(a - b);
|
|
}
|
|
|
|
vec4 SXOR4(vec4 a, vec4 b)
|
|
{
|
|
return abs(a - b);
|
|
}
|
|
|
|
float Checkers(vec3 coord, vec3 ddxyz, vec3 tripCoeff)
|
|
{
|
|
vec3 fade = clamp(1.0f / (ddxyz * 2.0f) - 1.0f, 0.0f, 1.0f);
|
|
|
|
float cx = SquareAntialiased(coord.x, ddxyz.x);
|
|
float cy = SquareAntialiased(coord.y, ddxyz.y);
|
|
float cz = SquareAntialiased(coord.z, ddxyz.z);
|
|
|
|
vec3 filter = clamp(1.0f / ddxyz * 0.5f - 0.5f, 0.0f, 1.0f); // smooth, manual filtering
|
|
|
|
float c = SXOR(cy * filter.y, cz * filter.z) * tripCoeff.x;
|
|
c += SXOR(cz * filter.z, cx * filter.x) * tripCoeff.y;
|
|
c += SXOR(cx * filter.x, cy * filter.y) * tripCoeff.z;
|
|
c += 1.0f - dot(filter, vec3(0.3333f));
|
|
|
|
return c;
|
|
}
|
|
|
|
vec4 texturePointSmooth(sampler2D smp, vec2 uv, vec2 tex_size, vec2 filter_width)
|
|
{
|
|
float fade = clamp(max(1.0f / filter_width.x, 1.0f / filter_width.y) - 1.0f, 0.0f, 1.0f);
|
|
filter_width = max(filter_width, vec2(1.0f));
|
|
vec2 uv_pixels = uv * tex_size;
|
|
|
|
vec2 uv_pixels_floor = round(uv_pixels) - vec2(0.5f);
|
|
vec2 uv_dxy_pixels = uv_pixels - uv_pixels_floor;
|
|
|
|
uv_dxy_pixels = clamp((uv_dxy_pixels - vec2(0.5f)) * filter_width + vec2(0.5f), 0.0f, 1.0f);
|
|
|
|
uv = uv_pixels_floor / tex_size;
|
|
|
|
return mix(textureLod(smp, uv + uv_dxy_pixels / tex_size, 0.0f), vec4(0.5f, 0.5f, 0.5f, 1.0f), fade);
|
|
}
|
|
|
|
vec4 TextureTriplanar(sampler2D smp, vec2 texSize, vec3 coord, vec3 ddxyz, vec3 tripCoeff)
|
|
{
|
|
vec4 cx = texturePointSmooth(smp, coord.yz, texSize, 1.0f / ddxyz.yz / texSize);
|
|
vec4 cy = texturePointSmooth(smp, coord.zx, texSize, 1.0f / ddxyz.zx / texSize);
|
|
vec4 cz = texturePointSmooth(smp, coord.xy, texSize, 1.0f / ddxyz.xy / texSize);
|
|
|
|
vec3 filter = clamp(1.0f / ddxyz * 0.5f - 0.5f, 0.0f, 1.0f); // smooth, manual filtering
|
|
|
|
vec4 c = cx * tripCoeff.x;
|
|
c += cy * tripCoeff.y;
|
|
c += cz * tripCoeff.z;
|
|
|
|
return c;
|
|
}
|
|
|
|
void fragment()
|
|
{
|
|
ALBEDO = albedo.rgb;
|
|
|
|
vec3 coord = Position.xyz * 4.0f;
|
|
vec3 ddxyz = fwidth(coord) * 1.0f;
|
|
|
|
vec3 tripCoeff = max((Normal * Normal * 2.0f - 0.5f), 0.001f);
|
|
tripCoeff /= (tripCoeff.x + tripCoeff.y + tripCoeff.z);
|
|
float checkers = Checkers(coord, ddxyz, tripCoeff);
|
|
|
|
coord = Position.xyz;
|
|
ddxyz = fwidth(coord);
|
|
float checkersL = 1.0f - Checkers(coord, ddxyz, tripCoeff);
|
|
|
|
vec3 detailCoord = Position.xyz * 0.5f; // Position.xyz * 2.0f
|
|
vec4 detail = TextureTriplanar(detail_texture, detail_texture_size, detailCoord, fwidth(detailCoord), tripCoeff);
|
|
|
|
checkers = mix(checkers, checkersL, 0.7f);
|
|
checkers = clamp(checkers * 0.8f + detail.r * 0.2f - 0.025f, 0.0f, 1.0f);
|
|
|
|
ALBEDO = mix(ALBEDO * 0.3f, ALBEDO, mix(checkers, 1.0f, metallic * roughness));
|
|
ROUGHNESS = mix(1.0f, 0.5f, checkers * (1.0f - roughness * 0.333f)) * roughness;
|
|
|
|
/* when using rgb noise as a texture, this can give some variation in roughness and normals
|
|
{
|
|
detail.rgb = detail.rgb * mat3(WORLD_MATRIX[0].xyz, WORLD_MATRIX[1].xyz, WORLD_MATRIX[2].xyz);
|
|
NORMAL = normalize(NORMAL + (detail.rgb - 0.5f) * 0.08f * roughness);
|
|
}
|
|
*/
|
|
|
|
METALLIC = metallic;
|
|
SPECULAR = specular;
|
|
} |