DRTVWR-592: (WIP) (has debug) Convert colors to linear before triplanar blending. General refactor.
parent
e6777d566f
commit
53a5055ab7
|
|
@ -135,6 +135,17 @@ void main()
|
|||
tnorm *= gl_FrontFacing ? 1.0 : -1.0;
|
||||
|
||||
|
||||
#if 0 // TODO: Remove debug
|
||||
//col.xyz = (tnorm + 1.0) / 2.0;// TODO: Remove
|
||||
//col.xyz = (vary_normal + 1.0) / 2.0;// TODO: Remove
|
||||
//col.xyz = spec; // TODO: Remove
|
||||
//col.xyz = vec3(1); // TODO: Remove
|
||||
//float weight = 1.0; spec.rgb = (weight * spec.rgb) + ((1 - weight) * vec3(1.0, 1.0, 1.0)); // TODO: Remove
|
||||
tnorm = vary_normal; // TODO: Remove
|
||||
spec.r = 1.0; // TODO: Remove
|
||||
spec.gb = vec2(1.0, 0.0); // TODO: Remove
|
||||
emissive.rgb = vec3(0); // TODO: Remove
|
||||
#endif
|
||||
frag_data[0] = max(vec4(col.xyz, 0.0), vec4(0)); // Diffuse
|
||||
frag_data[1] = max(vec4(spec.rgb, base_color_factor_alpha), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal.
|
||||
frag_data[2] = max(vec4(encode_normal(tnorm), base_color_factor_alpha, GBUFFER_FLAG_HAS_PBR), vec4(0)); // normal, environment intensity, flags
|
||||
|
|
|
|||
|
|
@ -69,7 +69,15 @@ vec4 terrain_mix(vec4[4] samples, float alpha1, float alpha2, float alphaFinal)
|
|||
|
||||
// Pre-transformed texture coordinates for each axial uv slice (Packing: xy, yz, (-x)z, unused)
|
||||
#define TerrainCoord vec4[2]
|
||||
#if 0 // TODO: Revert
|
||||
#define TERRAIN_TRIPLANAR_MIX_THRESHOLD 0.01
|
||||
#else
|
||||
#define TERRAIN_TRIPLANAR_MIX_THRESHOLD 0.01
|
||||
#endif
|
||||
|
||||
// Positive value prevents artifacts when weights are close to zero
|
||||
// TODO: Wait a minute... this doesn't prevent artifacts :( (or does it?)
|
||||
#define TERRAIN_TRIPLANAR_OVERDRAW_THRESHOLD 0.0
|
||||
|
||||
vec4 _t_texture(sampler2D tex, vec2 uv_unflipped, float sign)
|
||||
{
|
||||
|
|
@ -79,35 +87,60 @@ vec4 _t_texture(sampler2D tex, vec2 uv_unflipped, float sign)
|
|||
return texture(tex, uv);
|
||||
}
|
||||
|
||||
vec3 _t_texture_n(sampler2D tex, vec2 uv_unflipped, float sign)
|
||||
vec4 _t_texture_c(sampler2D tex, vec2 uv_unflipped, float sign)
|
||||
{
|
||||
// Unpack normal from pixel to vector
|
||||
vec3 n = _t_texture(tex, uv_unflipped, sign).xyz*2.0-1.0;
|
||||
// If the sign is negative, rotate normal by 180 degrees
|
||||
n.xy = (min(0, sign) * n.xy) + (min(0, -sign) * -n.xy);
|
||||
return n;
|
||||
vec4 c = _t_texture(tex, uv_unflipped, sign);
|
||||
c.xyz = srgb_to_linear(c.xyz);
|
||||
return c;
|
||||
}
|
||||
|
||||
vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord)
|
||||
#define SAMPLE_X 1 << 2
|
||||
#define SAMPLE_Y 1 << 1
|
||||
#define SAMPLE_Z 1 << 0
|
||||
#define terrain_coord_x terrain_coord[0].zw
|
||||
#define terrain_coord_y terrain_coord[1].xy
|
||||
#define terrain_coord_z terrain_coord[0].xy
|
||||
#define TERRAIN_DEBUG 1 // TODO: Remove debug
|
||||
struct TerrainWeight
|
||||
{
|
||||
vec3 weight;
|
||||
#if TERRAIN_DEBUG
|
||||
vec3 usage;
|
||||
#endif
|
||||
int type;
|
||||
};
|
||||
|
||||
TerrainWeight _t_weight(TerrainCoord terrain_coord)
|
||||
{
|
||||
float sharpness = TERRAIN_TRIPLANAR_BLEND_FACTOR;
|
||||
vec3 weight = normalize(pow(abs(vary_vertex_normal), vec3(sharpness)));
|
||||
float threshold = TERRAIN_TRIPLANAR_MIX_THRESHOLD;
|
||||
weight = max(vec3(0), sign(weight - threshold));
|
||||
vec3 weight_signed = normalize(pow(abs(vary_vertex_normal), vec3(sharpness)));
|
||||
weight_signed -= vec3(threshold);
|
||||
TerrainWeight tw;
|
||||
tw.weight = max(vec3(0), weight_signed);
|
||||
vec3 usage = max(vec3(0), sign(weight_signed + TERRAIN_TRIPLANAR_OVERDRAW_THRESHOLD));
|
||||
#if TERRAIN_DEBUG
|
||||
tw.usage = usage;
|
||||
#endif
|
||||
tw.type = (int(usage.x) * SAMPLE_X) |
|
||||
(int(usage.y) * SAMPLE_Y) |
|
||||
(int(usage.z) * SAMPLE_Z);
|
||||
return tw;
|
||||
}
|
||||
|
||||
#define SAMPLE_X 1 << 2
|
||||
#define SAMPLE_Y 1 << 1
|
||||
#define SAMPLE_Z 1 << 0
|
||||
int sample_type = (int(weight.x) * SAMPLE_X) |
|
||||
(int(weight.y) * SAMPLE_Y) |
|
||||
(int(weight.z) * SAMPLE_Z);
|
||||
#define terrain_coord_x terrain_coord[0].zw
|
||||
#define terrain_coord_y terrain_coord[1].xy
|
||||
#define terrain_coord_z terrain_coord[0].xy
|
||||
struct TerrainSample
|
||||
{
|
||||
vec4 x;
|
||||
vec4 y;
|
||||
vec4 z;
|
||||
switch (sample_type)
|
||||
};
|
||||
|
||||
TerrainSample _t_sample(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight tw)
|
||||
{
|
||||
vec4 x;
|
||||
vec4 y;
|
||||
vec4 z;
|
||||
switch (tw.type)
|
||||
{
|
||||
case SAMPLE_X | SAMPLE_Y | SAMPLE_Z:
|
||||
x = _t_texture(tex, terrain_coord_x, sign(vary_vertex_normal.x));
|
||||
|
|
@ -117,37 +150,98 @@ vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord)
|
|||
case SAMPLE_X | SAMPLE_Y:
|
||||
x = _t_texture(tex, terrain_coord_x, sign(vary_vertex_normal.x));
|
||||
y = _t_texture(tex, terrain_coord_y, sign(vary_vertex_normal.y));
|
||||
z = vec4(0);
|
||||
z = x;
|
||||
break;
|
||||
case SAMPLE_X | SAMPLE_Z:
|
||||
x = _t_texture(tex, terrain_coord_x, sign(vary_vertex_normal.x));
|
||||
y = vec4(0);
|
||||
z = _t_texture(tex, terrain_coord_z, sign(vary_vertex_normal.z));
|
||||
y = x;
|
||||
break;
|
||||
case SAMPLE_Y | SAMPLE_Z:
|
||||
x = vec4(0);
|
||||
y = _t_texture(tex, terrain_coord_y, sign(vary_vertex_normal.y));
|
||||
z = _t_texture(tex, terrain_coord_z, sign(vary_vertex_normal.z));
|
||||
x = y;
|
||||
break;
|
||||
case SAMPLE_X:
|
||||
x = _t_texture(tex, terrain_coord_x, sign(vary_vertex_normal.x));
|
||||
y = vec4(0);
|
||||
z = vec4(0);
|
||||
y = x;
|
||||
z = x;
|
||||
break;
|
||||
case SAMPLE_Y:
|
||||
x = vec4(0);
|
||||
y = _t_texture(tex, terrain_coord_y, sign(vary_vertex_normal.y));
|
||||
z = vec4(0);
|
||||
x = y;
|
||||
z = y;
|
||||
break;
|
||||
case SAMPLE_Z:
|
||||
z = _t_texture(tex, terrain_coord_z, sign(vary_vertex_normal.z));
|
||||
x = z;
|
||||
y = z;
|
||||
break;
|
||||
default:
|
||||
x = vec4(0);
|
||||
y = vec4(0);
|
||||
z = _t_texture(tex, terrain_coord_z, sign(vary_vertex_normal.z));
|
||||
y = x;
|
||||
z = x;
|
||||
break;
|
||||
}
|
||||
|
||||
return ((x * weight.x) + (y * weight.y) + (z * weight.z)) / (weight.x + weight.y + weight.z);
|
||||
TerrainSample ts;
|
||||
ts.x = x;
|
||||
ts.y = y;
|
||||
ts.z = z;
|
||||
return ts;
|
||||
}
|
||||
|
||||
struct TerrainSampleNormal
|
||||
{
|
||||
vec3 x;
|
||||
vec3 y;
|
||||
vec3 z;
|
||||
};
|
||||
|
||||
TerrainSampleNormal _t_sample_n(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight tw)
|
||||
{
|
||||
TerrainSample ts = _t_sample(tex, terrain_coord, tw);
|
||||
TerrainSampleNormal tsn;
|
||||
tsn.x = ts.x.xyz;
|
||||
tsn.y = ts.y.xyz;
|
||||
tsn.z = ts.z.xyz;
|
||||
vec3 ns = sign(vary_vertex_normal);
|
||||
// If the sign is negative, rotate normal by 180 degrees
|
||||
tsn.x.xy = (min(0, ns.x) * tsn.x.xy) + (min(0, -ns.x) * -tsn.x.xy);
|
||||
tsn.y.xy = (min(0, ns.y) * tsn.y.xy) + (min(0, -ns.y) * -tsn.y.xy);
|
||||
tsn.z.xy = (min(0, ns.z) * tsn.z.xy) + (min(0, -ns.z) * -tsn.z.xy);
|
||||
// *HACK: Transform normals according to orientation of the UVs
|
||||
tsn.x.xy = vec2(-tsn.x.y, tsn.x.x);
|
||||
tsn.y.xy = -tsn.y.xy;
|
||||
return tsn;
|
||||
}
|
||||
|
||||
TerrainSample _t_sample_c(sampler2D tex, TerrainCoord terrain_coord, TerrainWeight tw)
|
||||
{
|
||||
TerrainSample ts = _t_sample(tex, terrain_coord, tw);
|
||||
ts.x.xyz = srgb_to_linear(ts.x.xyz);
|
||||
ts.y.xyz = srgb_to_linear(ts.y.xyz);
|
||||
ts.z.xyz = srgb_to_linear(ts.z.xyz);
|
||||
return ts;
|
||||
}
|
||||
|
||||
vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord)
|
||||
{
|
||||
TerrainWeight tw = _t_weight(terrain_coord);
|
||||
|
||||
TerrainSample ts = _t_sample(tex, terrain_coord, tw);
|
||||
|
||||
#if 1
|
||||
return ((ts.x * tw.weight.x) + (ts.y * tw.weight.y) + (ts.z * tw.weight.z)) / (tw.weight.x + tw.weight.y + tw.weight.z);
|
||||
#else // TODO: Remove debug
|
||||
//return vec4(((tw.usage - normalize(tw.weight))) / 0.5, 1.0);
|
||||
#if 1
|
||||
return vec4(tw.usage, 1.0);
|
||||
#else
|
||||
//return vec4(tw.usage, 1.0);
|
||||
return vec4((tw.usage + weight) / 2.0, 1.0);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
// Specialized triplanar normal texture sampling implementation, taking into
|
||||
|
|
@ -156,74 +250,26 @@ vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord)
|
|||
// *TODO: Decide if we want this. It may be better to just calculate the
|
||||
// tangents on-the-fly here rather than messing with the normals, due to the
|
||||
// subtleties of the effects of triplanar mapping on UVs. These sampled normals
|
||||
// are only valid on the faces of a cube, and the pregenerated tangents are
|
||||
// only valid for uv = xy.
|
||||
// are only valid on the faces of a cube.
|
||||
// *NOTE: Bottom face has not been tested
|
||||
vec3 terrain_texture_normal(sampler2D tex, TerrainCoord terrain_coord)
|
||||
{
|
||||
float sharpness = TERRAIN_TRIPLANAR_BLEND_FACTOR;
|
||||
vec3 weight = normalize(pow(abs(vary_vertex_normal), vec3(sharpness)));
|
||||
float threshold = TERRAIN_TRIPLANAR_MIX_THRESHOLD;
|
||||
weight = max(vec3(0), sign(weight - threshold));
|
||||
TerrainWeight tw = _t_weight(terrain_coord);
|
||||
|
||||
#define SAMPLE_X 1 << 2
|
||||
#define SAMPLE_Y 1 << 1
|
||||
#define SAMPLE_Z 1 << 0
|
||||
int sample_type = (int(weight.x) * SAMPLE_X) |
|
||||
(int(weight.y) * SAMPLE_Y) |
|
||||
(int(weight.z) * SAMPLE_Z);
|
||||
#define terrain_coord_x terrain_coord[0].zw
|
||||
#define terrain_coord_y terrain_coord[1].xy
|
||||
#define terrain_coord_z terrain_coord[0].xy
|
||||
vec3 x;
|
||||
vec3 y;
|
||||
vec3 z;
|
||||
switch (sample_type)
|
||||
{
|
||||
case SAMPLE_X | SAMPLE_Y | SAMPLE_Z:
|
||||
x = _t_texture_n(tex, terrain_coord_x, sign(vary_vertex_normal.x));
|
||||
y = _t_texture_n(tex, terrain_coord_y, sign(vary_vertex_normal.y));
|
||||
z = _t_texture_n(tex, terrain_coord_z, sign(vary_vertex_normal.z));
|
||||
break;
|
||||
case SAMPLE_X | SAMPLE_Y:
|
||||
x = _t_texture_n(tex, terrain_coord_x, sign(vary_vertex_normal.x));
|
||||
y = _t_texture_n(tex, terrain_coord_y, sign(vary_vertex_normal.y));
|
||||
z = vec3(0);
|
||||
break;
|
||||
case SAMPLE_X | SAMPLE_Z:
|
||||
x = _t_texture_n(tex, terrain_coord_x, sign(vary_vertex_normal.x));
|
||||
y = vec3(0);
|
||||
z = _t_texture_n(tex, terrain_coord_z, sign(vary_vertex_normal.z));
|
||||
break;
|
||||
case SAMPLE_Y | SAMPLE_Z:
|
||||
x = vec3(0);
|
||||
y = _t_texture_n(tex, terrain_coord_y, sign(vary_vertex_normal.y));
|
||||
z = _t_texture_n(tex, terrain_coord_z, sign(vary_vertex_normal.z));
|
||||
break;
|
||||
case SAMPLE_X:
|
||||
x = _t_texture_n(tex, terrain_coord_x, sign(vary_vertex_normal.x));
|
||||
y = vec3(0);
|
||||
z = vec3(0);
|
||||
break;
|
||||
case SAMPLE_Y:
|
||||
x = vec3(0);
|
||||
y = _t_texture_n(tex, terrain_coord_y, sign(vary_vertex_normal.y));
|
||||
z = vec3(0);
|
||||
break;
|
||||
case SAMPLE_Z:
|
||||
default:
|
||||
x = vec3(0);
|
||||
y = vec3(0);
|
||||
z = _t_texture_n(tex, terrain_coord_z, sign(vary_vertex_normal.z));
|
||||
break;
|
||||
}
|
||||
TerrainSampleNormal ts = _t_sample_n(tex, terrain_coord, tw);
|
||||
|
||||
// *HACK: Transform normals according to orientation of the UVs
|
||||
x.xy = vec2(-x.y, x.x);
|
||||
y.xy = -y.xy;
|
||||
|
||||
return ((x * weight.x) + (y * weight.y) + (z * weight.z)) / (weight.x + weight.y + weight.z);
|
||||
return ((ts.x * tw.weight.x) + (ts.y * tw.weight.y) + (ts.z * tw.weight.z)) / (tw.weight.x + tw.weight.y + tw.weight.z);
|
||||
}
|
||||
|
||||
vec4 terrain_texture_color(sampler2D tex, TerrainCoord terrain_coord)
|
||||
{
|
||||
TerrainWeight tw = _t_weight(terrain_coord);
|
||||
|
||||
TerrainSample ts = _t_sample_c(tex, terrain_coord, tw);
|
||||
|
||||
return ((ts.x * tw.weight.x) + (ts.y * tw.weight.y) + (ts.z * tw.weight.z)) / (tw.weight.x + tw.weight.y + tw.weight.z);
|
||||
}
|
||||
|
||||
#elif TERRAIN_PLANAR_TEXTURE_SAMPLE_COUNT == 1
|
||||
#define TerrainCoord vec2
|
||||
vec4 terrain_texture(sampler2D tex, TerrainCoord terrain_coord)
|
||||
|
|
@ -235,6 +281,13 @@ vec3 terrain_texture_normal(sampler2D tex, TerrainCoord terrain_coord)
|
|||
{
|
||||
return texture(tex, terrain_coord).xyz*2.0-1.0;
|
||||
}
|
||||
|
||||
vec4 terrain_texture_color(sampler2D tex, TerrainCoord terrain_coord)
|
||||
{
|
||||
vec4 col = texture(tex, terrain_coord);
|
||||
col.xyz = srgb_to_linear(col.xyz);
|
||||
return col;
|
||||
}
|
||||
#endif
|
||||
|
||||
vec3 sample_and_mix_color3(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec3[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3)
|
||||
|
|
@ -258,14 +311,10 @@ vec3 sample_and_mix_color3(float alpha1, float alpha2, float alphaFinal, Terrain
|
|||
vec4 sample_and_mix_color4(float alpha1, float alpha2, float alphaFinal, TerrainCoord texcoord, vec4[4] factors, sampler2D tex0, sampler2D tex1, sampler2D tex2, sampler2D tex3)
|
||||
{
|
||||
vec4[4] samples;
|
||||
samples[0] = terrain_texture(tex0, texcoord);
|
||||
samples[1] = terrain_texture(tex1, texcoord);
|
||||
samples[2] = terrain_texture(tex2, texcoord);
|
||||
samples[3] = terrain_texture(tex3, texcoord);
|
||||
samples[0].xyz = srgb_to_linear(samples[0].xyz);
|
||||
samples[1].xyz = srgb_to_linear(samples[1].xyz);
|
||||
samples[2].xyz = srgb_to_linear(samples[2].xyz);
|
||||
samples[3].xyz = srgb_to_linear(samples[3].xyz);
|
||||
samples[0] = terrain_texture_color(tex0, texcoord);
|
||||
samples[1] = terrain_texture_color(tex1, texcoord);
|
||||
samples[2] = terrain_texture_color(tex2, texcoord);
|
||||
samples[3] = terrain_texture_color(tex3, texcoord);
|
||||
samples[0] *= factors[0];
|
||||
samples[1] *= factors[1];
|
||||
samples[2] *= factors[2];
|
||||
|
|
|
|||
Loading…
Reference in New Issue