mirror of
https://github.com/Relintai/pandemonium_engine_minimal.git
synced 2024-11-10 20:12:10 +01:00
353 lines
7.5 KiB
GLSL
353 lines
7.5 KiB
GLSL
/* clang-format off */
|
|
[vertex]
|
|
|
|
#ifdef USE_GLES_OVER_GL
|
|
#define lowp
|
|
#define mediump
|
|
#define highp
|
|
#else
|
|
precision highp float;
|
|
precision highp int;
|
|
#endif
|
|
|
|
uniform highp mat4 projection_matrix;
|
|
/* clang-format on */
|
|
|
|
#include "stdlib.glsl"
|
|
|
|
uniform highp mat4 modelview_matrix;
|
|
uniform highp mat4 extra_matrix;
|
|
attribute highp vec2 vertex; // attrib:0
|
|
|
|
attribute vec4 color_attrib; // attrib:3
|
|
attribute vec2 uv_attrib; // attrib:4
|
|
|
|
#ifdef USE_ATTRIB_MODULATE
|
|
attribute highp vec4 modulate_attrib; // attrib:5
|
|
#endif
|
|
|
|
// Usually, final_modulate is passed as a uniform. However during batching
|
|
// If larger fvfs are used, final_modulate is passed as an attribute.
|
|
// we need to read from the attribute in custom vertex shader
|
|
// rather than the uniform. We do this by specifying final_modulate_alias
|
|
// in shaders rather than final_modulate directly.
|
|
#ifdef USE_ATTRIB_MODULATE
|
|
#define final_modulate_alias modulate_attrib
|
|
#else
|
|
#define final_modulate_alias final_modulate
|
|
#endif
|
|
|
|
#ifdef USE_INSTANCING
|
|
|
|
attribute highp vec4 instance_xform0; //attrib:8
|
|
attribute highp vec4 instance_xform1; //attrib:9
|
|
attribute highp vec4 instance_xform2; //attrib:10
|
|
attribute highp vec4 instance_color; //attrib:11
|
|
|
|
#ifdef USE_INSTANCE_CUSTOM
|
|
attribute highp vec4 instance_custom_data; //attrib:12
|
|
#endif
|
|
|
|
#endif
|
|
|
|
varying vec2 uv_interp;
|
|
varying vec4 color_interp;
|
|
|
|
#ifdef USE_ATTRIB_MODULATE
|
|
// modulate doesn't need interpolating but we need to send it to the fragment shader
|
|
varying vec4 modulate_interp;
|
|
#endif
|
|
|
|
#ifdef MODULATE_USED
|
|
uniform vec4 final_modulate;
|
|
#endif
|
|
|
|
uniform highp vec2 color_texpixel_size;
|
|
|
|
#ifdef USE_TEXTURE_RECT
|
|
|
|
uniform vec4 dst_rect;
|
|
uniform vec4 src_rect;
|
|
|
|
#endif
|
|
|
|
uniform highp float time;
|
|
|
|
const bool at_light_pass = false;
|
|
|
|
/* clang-format off */
|
|
|
|
VERTEX_SHADER_GLOBALS
|
|
|
|
/* clang-format on */
|
|
|
|
vec2 select(vec2 a, vec2 b, bvec2 c) {
|
|
vec2 ret;
|
|
|
|
ret.x = c.x ? b.x : a.x;
|
|
ret.y = c.y ? b.y : a.y;
|
|
|
|
return ret;
|
|
}
|
|
|
|
void main() {
|
|
vec4 color = color_attrib;
|
|
vec2 uv;
|
|
|
|
#ifdef USE_INSTANCING
|
|
mat4 extra_matrix_instance = extra_matrix * transpose(mat4(instance_xform0, instance_xform1, instance_xform2, vec4(0.0, 0.0, 0.0, 1.0)));
|
|
color *= instance_color;
|
|
|
|
#ifdef USE_INSTANCE_CUSTOM
|
|
vec4 instance_custom = instance_custom_data;
|
|
#else
|
|
vec4 instance_custom = vec4(0.0);
|
|
#endif
|
|
|
|
#else
|
|
mat4 extra_matrix_instance = extra_matrix;
|
|
vec4 instance_custom = vec4(0.0);
|
|
#endif
|
|
|
|
#ifdef USE_TEXTURE_RECT
|
|
|
|
if (dst_rect.z < 0.0) { // Transpose is encoded as negative dst_rect.z
|
|
uv = src_rect.xy + abs(src_rect.zw) * vertex.yx;
|
|
} else {
|
|
uv = src_rect.xy + abs(src_rect.zw) * vertex;
|
|
}
|
|
|
|
vec4 outvec = vec4(0.0, 0.0, 0.0, 1.0);
|
|
|
|
// This is what is done in the GLES 3 bindings and should
|
|
// take care of flipped rects.
|
|
//
|
|
// But it doesn't.
|
|
// I don't know why, will need to investigate further.
|
|
|
|
outvec.xy = dst_rect.xy + abs(dst_rect.zw) * select(vertex, vec2(1.0, 1.0) - vertex, lessThan(src_rect.zw, vec2(0.0, 0.0)));
|
|
|
|
// outvec.xy = dst_rect.xy + abs(dst_rect.zw) * vertex;
|
|
#else
|
|
vec4 outvec = vec4(vertex.xy, 0.0, 1.0);
|
|
|
|
uv = uv_attrib;
|
|
#endif
|
|
|
|
float point_size = 1.0;
|
|
|
|
{
|
|
vec2 src_vtx = outvec.xy;
|
|
/* clang-format off */
|
|
|
|
VERTEX_SHADER_CODE
|
|
|
|
/* clang-format on */
|
|
}
|
|
|
|
gl_PointSize = point_size;
|
|
|
|
#ifdef USE_ATTRIB_MODULATE
|
|
// modulate doesn't need interpolating but we need to send it to the fragment shader
|
|
modulate_interp = modulate_attrib;
|
|
#endif
|
|
|
|
// transform is in uniforms
|
|
#if !defined(SKIP_TRANSFORM_USED)
|
|
outvec = extra_matrix_instance * outvec;
|
|
outvec = modelview_matrix * outvec;
|
|
#endif
|
|
|
|
color_interp = color;
|
|
|
|
#ifdef USE_PIXEL_SNAP
|
|
outvec.xy = floor(outvec + 0.5).xy;
|
|
// precision issue on some hardware creates artifacts within texture
|
|
// offset uv by a small amount to avoid
|
|
uv += 1e-5;
|
|
#endif
|
|
|
|
uv_interp = uv;
|
|
gl_Position = projection_matrix * outvec;
|
|
}
|
|
|
|
/* clang-format off */
|
|
[fragment]
|
|
|
|
// texture2DLodEXT and textureCubeLodEXT are fragment shader specific.
|
|
// Do not copy these defines in the vertex section.
|
|
#ifndef USE_GLES_OVER_GL
|
|
#ifdef GL_EXT_shader_texture_lod
|
|
#extension GL_EXT_shader_texture_lod : enable
|
|
#define texture2DLod(img, coord, lod) texture2DLodEXT(img, coord, lod)
|
|
#define textureCubeLod(img, coord, lod) textureCubeLodEXT(img, coord, lod)
|
|
#endif
|
|
#endif // !USE_GLES_OVER_GL
|
|
|
|
#ifdef GL_ARB_shader_texture_lod
|
|
#extension GL_ARB_shader_texture_lod : enable
|
|
#endif
|
|
|
|
#if !defined(GL_EXT_shader_texture_lod) && !defined(GL_ARB_shader_texture_lod)
|
|
#define texture2DLod(img, coord, lod) texture2D(img, coord, lod)
|
|
#define textureCubeLod(img, coord, lod) textureCube(img, coord, lod)
|
|
#endif
|
|
|
|
#ifdef USE_GLES_OVER_GL
|
|
#define lowp
|
|
#define mediump
|
|
#define highp
|
|
#else
|
|
#if defined(USE_HIGHP_PRECISION)
|
|
precision highp float;
|
|
precision highp int;
|
|
#else
|
|
precision mediump float;
|
|
precision mediump int;
|
|
#endif
|
|
#endif
|
|
|
|
#include "stdlib.glsl"
|
|
|
|
uniform sampler2D color_texture; // texunit:-1
|
|
/* clang-format on */
|
|
uniform highp vec2 color_texpixel_size;
|
|
uniform mediump sampler2D normal_texture; // texunit:-2
|
|
|
|
varying mediump vec2 uv_interp;
|
|
varying mediump vec4 color_interp;
|
|
|
|
#ifdef USE_ATTRIB_MODULATE
|
|
varying mediump vec4 modulate_interp;
|
|
#endif
|
|
|
|
uniform highp float time;
|
|
|
|
uniform vec4 final_modulate;
|
|
|
|
#ifdef SCREEN_TEXTURE_USED
|
|
|
|
uniform sampler2D screen_texture; // texunit:-4
|
|
|
|
#endif
|
|
|
|
#ifdef SCREEN_UV_USED
|
|
|
|
uniform vec2 screen_pixel_size;
|
|
|
|
#endif
|
|
|
|
const bool at_light_pass = false;
|
|
|
|
uniform bool use_default_normal;
|
|
|
|
/* clang-format off */
|
|
|
|
FRAGMENT_SHADER_GLOBALS
|
|
|
|
/* clang-format on */
|
|
|
|
void light_compute(
|
|
inout vec4 light,
|
|
inout vec2 light_vec,
|
|
inout float light_height,
|
|
inout vec4 light_color,
|
|
vec2 light_uv,
|
|
inout vec4 shadow_color,
|
|
inout vec2 shadow_vec,
|
|
vec3 normal,
|
|
vec2 uv,
|
|
#if defined(SCREEN_UV_USED)
|
|
vec2 screen_uv,
|
|
#endif
|
|
vec4 color) {
|
|
|
|
#if defined(USE_LIGHT_SHADER_CODE)
|
|
|
|
/* clang-format off */
|
|
|
|
LIGHT_SHADER_CODE
|
|
|
|
/* clang-format on */
|
|
|
|
#endif
|
|
}
|
|
|
|
void main() {
|
|
vec4 color = color_interp;
|
|
vec2 uv = uv_interp;
|
|
#ifdef USE_FORCE_REPEAT
|
|
//needs to use this to workaround GLES2/WebGL1 forcing tiling that textures that don't support it
|
|
uv = mod(uv, vec2(1.0, 1.0));
|
|
#endif
|
|
|
|
#if !defined(COLOR_USED)
|
|
//default behavior, texture by color
|
|
color *= texture2D(color_texture, uv);
|
|
#endif
|
|
|
|
#ifdef SCREEN_UV_USED
|
|
vec2 screen_uv = gl_FragCoord.xy * screen_pixel_size;
|
|
#endif
|
|
|
|
vec3 normal;
|
|
|
|
#if defined(NORMAL_USED)
|
|
|
|
bool normal_used = true;
|
|
#else
|
|
bool normal_used = false;
|
|
#endif
|
|
|
|
if (use_default_normal) {
|
|
normal.xy = texture2D(normal_texture, uv).xy * 2.0 - 1.0;
|
|
normal.z = sqrt(max(0.0, 1.0 - dot(normal.xy, normal.xy)));
|
|
normal_used = true;
|
|
} else {
|
|
normal = vec3(0.0, 0.0, 1.0);
|
|
}
|
|
|
|
{
|
|
float normal_depth = 1.0;
|
|
|
|
#if defined(NORMALMAP_USED)
|
|
vec3 normal_map = vec3(0.0, 0.0, 1.0);
|
|
normal_used = true;
|
|
#endif
|
|
|
|
// If larger fvfs are used, final_modulate is passed as an attribute.
|
|
// we need to read from this in custom fragment shaders or applying in the post step,
|
|
// rather than using final_modulate directly.
|
|
#if defined(final_modulate_alias)
|
|
#undef final_modulate_alias
|
|
#endif
|
|
#ifdef USE_ATTRIB_MODULATE
|
|
#define final_modulate_alias modulate_interp
|
|
#else
|
|
#define final_modulate_alias final_modulate
|
|
#endif
|
|
|
|
/* clang-format off */
|
|
|
|
FRAGMENT_SHADER_CODE
|
|
|
|
/* clang-format on */
|
|
|
|
#if defined(NORMALMAP_USED)
|
|
normal = mix(vec3(0.0, 0.0, 1.0), normal_map * vec3(2.0, -2.0, 1.0) - vec3(1.0, -1.0, 0.0), normal_depth);
|
|
#endif
|
|
}
|
|
|
|
#if !defined(MODULATE_USED)
|
|
color *= final_modulate_alias;
|
|
#endif
|
|
|
|
#ifdef LINEAR_TO_SRGB
|
|
// regular Linear -> SRGB conversion
|
|
vec3 a = vec3(0.055);
|
|
color.rgb = mix((vec3(1.0) + a) * pow(color.rgb, vec3(1.0 / 2.4)) - a, 12.92 * color.rgb, vec3(lessThan(color.rgb, vec3(0.0031308))));
|
|
#endif
|
|
|
|
gl_FragColor = color;
|
|
}
|