mirror of https://github.com/nothings/stb.git
premultiplied alpha support
This commit is contained in:
parent
f49c90c03d
commit
ba49d37e6a
|
@ -1,7 +1,6 @@
|
|||
// @TODO
|
||||
//
|
||||
// - API for texture rotation on side faces (& top&bottom ?)
|
||||
// - premultiplied alpha
|
||||
// - edge clamp
|
||||
// - better culling of vheight faces with vheight neighbors
|
||||
// - better culling of non-vheight faces with fheight neighbors
|
||||
|
@ -280,6 +279,7 @@ STBVXDEC void stbvox_set_input_stride(stbvox_mesh_maker *mm, int x_stride_in_byt
|
|||
STBVXDEC stbvox_input_description *stbvox_get_input_description(stbvox_mesh_maker *mm);
|
||||
STBVXDEC char *stbvox_get_vertex_shader(void);
|
||||
STBVXDEC char *stbvox_get_fragment_shader(void);
|
||||
STBVXDEC char *stbvox_get_fragment_shader_alpha_only(void);
|
||||
STBVXDEC void stbvox_set_default_mesh(stbvox_mesh_maker *mm, int mesh);
|
||||
STBVXDEC int stbvox_get_quad_count(stbvox_mesh_maker *mm, int mesh);
|
||||
STBVXDEC void stbvox_get_transform(stbvox_mesh_maker *mm, float transform[3][3]);
|
||||
|
@ -754,7 +754,7 @@ static char *stbvox_vertex_encoderogram =
|
|||
|
||||
// fragment output data
|
||||
"flat out uvec4 facedata;\n"
|
||||
" out vec3 objectspace_pos;\n"
|
||||
" out vec3 voxelspace_pos;\n"
|
||||
" out vec3 vnormal;\n"
|
||||
" out float texlerp;\n"
|
||||
" out float amb_occ;\n"
|
||||
|
@ -778,8 +778,8 @@ static char *stbvox_vertex_encoderogram =
|
|||
" texlerp = float( (attr_vertex >> 29u) ) / 7.0;\n" // a[29..31]
|
||||
|
||||
" vnormal = normal_table[(facedata.w>>2) & 31u];\n"
|
||||
" objectspace_pos = offset * transform[0];\n" // object-to-world scale
|
||||
" vec3 position = objectspace_pos + transform[1];\n" // object-to-world translate
|
||||
" voxelspace_pos = offset * transform[0];\n" // mesh-to-object scale
|
||||
" vec3 position = voxelspace_pos + transform[1];\n" // mesh-to-object translate
|
||||
|
||||
#ifdef STBVOX_DEBUG_TEST_NORMALS
|
||||
" if ((facedata.w & 28u) == 16u || (facedata.w & 28u) == 24u)\n"
|
||||
|
@ -812,7 +812,7 @@ static char *stbvox_fragment_program =
|
|||
|
||||
// vertex-shader output data
|
||||
"flat in uvec4 facedata;\n"
|
||||
" in vec3 objectspace_pos;\n"
|
||||
" in vec3 voxelspace_pos;\n"
|
||||
" in vec3 vnormal;\n"
|
||||
" in float texlerp;\n"
|
||||
" in float amb_occ;\n"
|
||||
|
@ -847,7 +847,7 @@ static char *stbvox_fragment_program =
|
|||
"vec3 compute_lighting(vec3 pos, vec3 norm, vec3 albedo, vec3 ambient);\n"
|
||||
#endif
|
||||
#if defined(STBVOX_CONFIG_FOG) || defined(STBVOX_CONFIG_FOG_SMOOTHSTEP)
|
||||
"vec3 compute_fog(vec3 color, vec3 relative_pos);\n"
|
||||
"vec3 compute_fog(vec3 color, vec3 relative_pos, float fragment_alpha);\n"
|
||||
#endif
|
||||
|
||||
"void main()\n"
|
||||
|
@ -878,7 +878,7 @@ static char *stbvox_fragment_program =
|
|||
" vec4 color = texelFetch(color_table, int(color_id & 63u));\n"
|
||||
#endif
|
||||
" vec2 texcoord;\n"
|
||||
" vec3 texturespace_pos = objectspace_pos + transform[2].xyz;\n"
|
||||
" vec3 texturespace_pos = voxelspace_pos + transform[2].xyz;\n"
|
||||
" texcoord.s = dot(texturespace_pos, texgen_s);\n"
|
||||
" texcoord.t = dot(texturespace_pos, texgen_t);\n"
|
||||
|
||||
|
@ -893,13 +893,24 @@ static char *stbvox_fragment_program =
|
|||
" if ((color_id & 64u) != 0u) tex1.xyz *= color.xyz;\n"
|
||||
" if ((color_id & 128u) != 0u) tex2.xyz *= color.xyz;\n"
|
||||
|
||||
#ifdef STBVOX_CONFIG_PREMULTIPLIED_ALPHA
|
||||
" tex2.rgba *= texlerp;\n"
|
||||
#else
|
||||
" tex2.a *= texlerp;\n"
|
||||
#endif
|
||||
|
||||
// @TODO: could use a separate lookup table keyed on tex2 to determine this
|
||||
" if (texblend_mode)\n"
|
||||
" albedo = tex2.xyz * rlerp(tex2.a, 2.0*tex1.xyz, vec3(1.0,1.0,1.0));\n"
|
||||
" else\n"
|
||||
" albedo = rlerp(tex2.a, tex1.xyz, tex2.xyz);\n" // @TODO premultiplied alpha
|
||||
" else {\n"
|
||||
#ifdef STBVOX_CONFIG_PREMULTIPLIED_ALPHA
|
||||
" albedo = (1.0-tex2.a)*tex1.xyz + tex2.xyz;\n"
|
||||
" fragment_alpha = tex1.a;\n"
|
||||
#else
|
||||
" albedo = rlerp(tex2.a, tex1.xyz, tex2.xyz);\n"
|
||||
" fragment_alpha = tex1.a*(1-tex2.a)+tex2.a;\n"
|
||||
#endif
|
||||
" }\n"
|
||||
|
||||
" fragment_alpha = tex1.a;\n"
|
||||
#else // UNTEXTURED
|
||||
|
@ -926,7 +937,7 @@ static char *stbvox_fragment_program =
|
|||
" vec3 lit_color;\n"
|
||||
" if (!emissive)\n"
|
||||
#if defined(STBVOX_ICONFIG_LIGHTING) || defined(STBVOX_CONFIG_LIGHTING_SIMPLE)
|
||||
" lit_color = compute_lighting(objectspace_pos + transform[1], normal, albedo, ambient_color);\n"
|
||||
" lit_color = compute_lighting(voxelspace_pos + transform[1], normal, albedo, ambient_color);\n"
|
||||
#else
|
||||
" lit_color = albedo * ambient_color ;\n"
|
||||
#endif
|
||||
|
@ -934,11 +945,15 @@ static char *stbvox_fragment_program =
|
|||
" lit_color = albedo;\n"
|
||||
|
||||
#if defined(STBVOX_ICONFIG_FOG) || defined(STBVOX_CONFIG_FOG_SMOOTHSTEP)
|
||||
" vec3 dist = objectspace_pos + (transform[1] - camera_pos.xyz);\n"
|
||||
" lit_color = compute_fog(lit_color, dist);\n"
|
||||
" vec3 dist = voxelspace_pos + (transform[1] - camera_pos.xyz);\n"
|
||||
" lit_color = compute_fog(lit_color, dist, fragment_alpha);\n"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef STBVOX_CONFIG_UNPREMULTIPLY
|
||||
" vec4 final_color = vec4(lit_color/fragment_alpha, fragment_alpha);\n"
|
||||
#else
|
||||
" vec4 final_color = vec4(lit_color, fragment_alpha);\n"
|
||||
#endif
|
||||
" outcolor = final_color;\n"
|
||||
"}\n"
|
||||
|
||||
|
@ -956,17 +971,106 @@ static char *stbvox_fragment_program =
|
|||
|
||||
#ifdef STBVOX_CONFIG_FOG_SMOOTHSTEP
|
||||
"\n"
|
||||
"vec3 compute_fog(vec3 color, vec3 relative_pos)\n"
|
||||
"vec3 compute_fog(vec3 color, vec3 relative_pos, float fragment_alpha)\n"
|
||||
"{\n"
|
||||
" float f = sqrt(dot(relative_pos,relative_pos))/1320.0;\n"
|
||||
" f = clamp(f, 0.0, 1.0);\n"
|
||||
" f = 3.0*f*f - 2.0*f*f*f;\n" // smoothstep
|
||||
" f = f*f;\n" // fade in more smoothly
|
||||
#ifdef STBVOX_CONFIG_PREMULTIPLIED_ALPHA
|
||||
" return rlerp(f, color.xyz, ambient[3]*fragment_alpha);\n"
|
||||
#else
|
||||
" return rlerp(f, color.xyz, ambient[3]);\n"
|
||||
#endif
|
||||
"}\n"
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
static char *stbvox_fragment_program_alpha_only =
|
||||
{
|
||||
STBVOX_SHADER_VERSION
|
||||
|
||||
// vertex-shader output data
|
||||
"flat in uvec4 facedata;\n"
|
||||
" in vec3 voxelspace_pos;\n"
|
||||
" in float texlerp;\n"
|
||||
|
||||
// per-buffer data
|
||||
"uniform vec3 transform[3];\n"
|
||||
|
||||
#ifndef STBVOX_ICONFIG_UNTEXTURED
|
||||
// generally constant data
|
||||
"uniform sampler2DArray tex_array[2];\n"
|
||||
|
||||
#ifdef STBVOX_CONFIG_PREFER_TEXBUFFER
|
||||
"uniform samplerBuffer texscale;\n"
|
||||
"uniform samplerBuffer texgen;\n"
|
||||
#else
|
||||
"uniform vec2 texscale[64];\n" // instead of 128, to avoid running out of uniforms
|
||||
"uniform vec3 texgen[64];\n"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
"out vec4 outcolor;\n"
|
||||
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" vec3 albedo;\n"
|
||||
" float fragment_alpha;\n"
|
||||
|
||||
#ifndef STBVOX_ICONFIG_UNTEXTURED
|
||||
// unpack the values
|
||||
" uint tex1_id = facedata.x;\n"
|
||||
" uint tex2_id = facedata.y;\n"
|
||||
" uint texprojid = facedata.w & 31u;\n"
|
||||
" bool texblend_mode = ((facedata.w & 128u) != 0u);\n"
|
||||
|
||||
#ifndef STBVOX_CONFIG_PREFER_TEXBUFFER
|
||||
// load from uniforms / texture buffers
|
||||
" vec3 texgen_s = texgen[texprojid];\n"
|
||||
" vec3 texgen_t = texgen[texprojid+32u];\n"
|
||||
" float tex1_scale = texscale[tex1_id & 63u].x;\n"
|
||||
" float tex2_scale = texscale[tex2_id & 63u].y;\n"
|
||||
#else
|
||||
" vec3 texgen_s = texelFetch(texgen, int(texprojid)).xyz;\n"
|
||||
" vec3 texgen_t = texelFetch(texgen, int(texprojid+32u)).xyz;\n"
|
||||
" float tex1_scale = texelFetch(texscale, int(tex1_id & 127u)).x;\n"
|
||||
" float tex2_scale = texelFetch(texscale, int(tex2_id & 127u)).y;\n"
|
||||
#endif
|
||||
" vec2 texcoord;\n"
|
||||
" vec3 texturespace_pos = voxelspace_pos + transform[2].xyz;\n"
|
||||
" texcoord.s = dot(texturespace_pos, texgen_s);\n"
|
||||
" texcoord.t = dot(texturespace_pos, texgen_t);\n"
|
||||
|
||||
// @TODO: use 2 bits of facedata.w to enable animation of facedata.x & y?
|
||||
|
||||
" vec4 tex1 = texture(tex_array[0], vec3(tex1_scale * texcoord, float(tex1_id)));\n"
|
||||
" vec4 tex2 = texture(tex_array[1], vec3(tex2_scale * texcoord, float(tex2_id)));\n"
|
||||
|
||||
" tex2.a *= texlerp;\n"
|
||||
|
||||
// @TODO: could use a separate lookup table keyed on tex2 to determine this
|
||||
" if (texblend_mode)\n"
|
||||
" ;\n"
|
||||
" else {\n"
|
||||
#ifdef STBVOX_CONFIG_PREMULTIPLIED_ALPHA
|
||||
" fragment_alpha = tex1.a;\n"
|
||||
#else
|
||||
" fragment_alpha = tex1.a*(1-tex2.a)+tex2.a;\n"
|
||||
#endif
|
||||
" }\n"
|
||||
|
||||
#else // UNTEXTURED
|
||||
" vec4 color;"
|
||||
" fragment_alpha = 1.0;\n"
|
||||
#endif
|
||||
|
||||
" outcolor = vec4(0.0, 0.0, 0.0, fragment_alpha);\n"
|
||||
"}\n"
|
||||
};
|
||||
|
||||
|
||||
STBVXDEC char *stbvox_get_vertex_shader(void)
|
||||
{
|
||||
return stbvox_vertex_encoderogram;
|
||||
|
@ -977,6 +1081,11 @@ STBVXDEC char *stbvox_get_fragment_shader(void)
|
|||
return stbvox_fragment_program;
|
||||
}
|
||||
|
||||
STBVXDEC char *stbvox_get_fragment_shader_alpha_only(void)
|
||||
{
|
||||
return stbvox_fragment_program_alpha_only;
|
||||
}
|
||||
|
||||
static float stbvox_dummy_transform[3][3];
|
||||
|
||||
#ifdef STBVOX_CONFIG_PREFER_TEXBUFFER
|
||||
|
|
|
@ -21,7 +21,8 @@
|
|||
#define STBVOX_CONFIG_PREFER_TEXBUFFER
|
||||
//#define STBVOX_CONFIG_LIGHTING_SIMPLE
|
||||
#define STBVOX_CONFIG_FOG_SMOOTHSTEP
|
||||
|
||||
#define STBVOX_CONFIG_PREMULTIPLIED_ALPHA // use this even though it doesn't really work for alpha test without next #define
|
||||
//#define STBVOX_CONFIG_UNPREMULTIPLY // slower, makes windows & fancy leaves look better
|
||||
|
||||
#define STBVOX_ROTATION_IN_LIGHTING
|
||||
#define STB_VOXEL_RENDER_IMPLEMENTATION
|
||||
|
@ -33,7 +34,9 @@ extern void ods(char *fmt, ...);
|
|||
#define FAST_CHUNK
|
||||
#define IN_PLACE
|
||||
|
||||
#define SKIP_TERRAIN 0 // must be a multiple of 16; doesn't build some underground stuff
|
||||
#define SKIP_TERRAIN 0 // use to avoid building underground stuff
|
||||
// allows you to see what perf would be like if underground was efficiently culled,
|
||||
// or if you were making a game without underground
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -189,7 +192,7 @@ unsigned char minecraft_info[256][7] =
|
|||
{ C_empty },
|
||||
{ C_solid, 54,54,54,54,54,54 },
|
||||
{ C_solid, 125,125,125,125,125,125 },
|
||||
{ C_solid, 124,124,124,124,124,124 },
|
||||
{ C_solid, 126,126,126,126,126,126 },
|
||||
{ C_empty }, // bars
|
||||
{ C_trans, 49,49,49,49,49,49 }, // glass pane
|
||||
{ C_solid, 136,136,136,136,137,137 }, // melon
|
||||
|
@ -227,7 +230,7 @@ unsigned char minecraft_info[256][7] =
|
|||
// 128
|
||||
{ C_solid, 192,192,192,192,176,176 }, // sandstone stairs
|
||||
{ C_solid, 32,32,32,32,32,32 }, // emerald ore
|
||||
{ C_empty }, // ender chest
|
||||
{ C_solid, 26,26,26,27,25,25 }, // ender chest
|
||||
{ C_empty },
|
||||
{ C_empty },
|
||||
{ C_solid, 23,23,23,23,23,23 }, // emerald block
|
||||
|
|
Loading…
Reference in New Issue