summaryrefslogtreecommitdiff
path: root/drivers/gles3/shaders/canvas.glsl
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gles3/shaders/canvas.glsl')
-rw-r--r--drivers/gles3/shaders/canvas.glsl248
1 files changed, 215 insertions, 33 deletions
diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl
index e6c72da8f1..f0dc14c35a 100644
--- a/drivers/gles3/shaders/canvas.glsl
+++ b/drivers/gles3/shaders/canvas.glsl
@@ -6,21 +6,36 @@ layout(location=3) in vec4 color_attrib;
#ifdef USE_TEXTURE_RECT
-layout(location=1) in highp vec4 dst_rect;
-layout(location=2) in highp vec4 src_rect;
+uniform vec4 dst_rect;
+uniform vec4 src_rect;
#else
+#ifdef USE_INSTANCING
+
+layout(location=8) in highp vec4 instance_xform0;
+layout(location=9) in highp vec4 instance_xform1;
+layout(location=10) in highp vec4 instance_xform2;
+layout(location=11) in lowp vec4 instance_color;
+
+#ifdef USE_INSTANCE_CUSTOM
+layout(location=12) in highp vec4 instance_custom_data;
+#endif
+
+#endif
+
layout(location=4) in highp vec2 uv_attrib;
//skeletn
#endif
+uniform highp vec2 color_texpixel_size;
+
layout(std140) uniform CanvasItemData { //ubo:0
highp mat4 projection_matrix;
- highp vec4 time;
+ highp float time;
};
uniform highp mat4 modelview_matrix;
@@ -30,6 +45,12 @@ uniform highp mat4 extra_matrix;
out mediump vec2 uv_interp;
out mediump vec4 color_interp;
+#ifdef USE_NINEPATCH
+
+out highp vec2 pixel_size_interp;
+#endif
+
+
#ifdef USE_LIGHTING
layout(std140) uniform LightData { //ubo:1
@@ -51,18 +72,24 @@ layout(std140) uniform LightData { //ubo:1
out vec4 light_uv_interp;
-#if defined(NORMAL_USED)
+
out vec4 local_rot;
-#endif
+
#ifdef USE_SHADOWS
out highp vec2 pos;
#endif
+const bool at_light_pass = true;
+#else
+const bool at_light_pass = false;
#endif
+#ifdef USE_PARTICLES
+uniform int h_frames;
+uniform int v_frames;
+#endif
-VERTEX_SHADER_GLOBALS
#if defined(USE_MATERIAL)
@@ -74,10 +101,18 @@ MATERIAL_UNIFORMS
#endif
+VERTEX_SHADER_GLOBALS
+
void main() {
vec4 vertex_color = color_attrib;
+#ifdef USE_INSTANCING
+ mat4 extra_matrix2 = extra_matrix * transpose(mat4(instance_xform0,instance_xform1,instance_xform2,vec4(0.0,0.0,0.0,1.0)));
+ vertex_color*=instance_color;
+#else
+ mat4 extra_matrix2 = extra_matrix;
+#endif
#ifdef USE_TEXTURE_RECT
@@ -91,6 +126,22 @@ void main() {
#endif
+#ifdef USE_PARTICLES
+ //scale by texture size
+ outvec.xy/=color_texpixel_size;
+
+ //compute h and v frames and adjust UV interp for animation
+ int total_frames = h_frames * v_frames;
+ int frame = min(int(float(total_frames) *instance_custom_data.z),total_frames-1);
+ float frame_w = 1.0/float(h_frames);
+ float frame_h = 1.0/float(v_frames);
+ uv_interp.x = uv_interp.x * frame_w + frame_w * float(frame % h_frames);
+ uv_interp.y = uv_interp.y * frame_h + frame_h * float(frame / v_frames);
+
+#endif
+
+#define extra_matrix extra_matrix2
+
{
vec2 src_vtx=outvec.xy;
@@ -98,11 +149,19 @@ VERTEX_SHADER_CODE
}
+
+#ifdef USE_NINEPATCH
+
+ pixel_size_interp=abs(dst_rect.zw) * vertex;
+#endif
+
#if !defined(SKIP_TRANSFORM_USED)
outvec = extra_matrix * outvec;
outvec = modelview_matrix * outvec;
#endif
+#undef extra_matrix
+
color_interp = vertex_color;
#ifdef USE_PIXEL_SNAP
@@ -121,7 +180,7 @@ VERTEX_SHADER_CODE
pos=outvec.xy;
#endif
-#if defined(NORMAL_USED)
+
local_rot.xy=normalize( (modelview_matrix * ( extra_matrix * vec4(1.0,0.0,0.0,0.0) )).xy );
local_rot.zw=normalize( (modelview_matrix * ( extra_matrix * vec4(0.0,1.0,0.0,0.0) )).xy );
#ifdef USE_TEXTURE_RECT
@@ -129,7 +188,7 @@ VERTEX_SHADER_CODE
local_rot.zw*=sign(src_rect.w);
#endif
-#endif
+
#endif
@@ -141,6 +200,7 @@ VERTEX_SHADER_CODE
uniform mediump sampler2D color_texture; // texunit:0
uniform highp vec2 color_texpixel_size;
+uniform mediump sampler2D normal_texture; // texunit:1
in mediump vec2 uv_interp;
in mediump vec4 color_interp;
@@ -152,10 +212,15 @@ uniform sampler2D screen_texture; // texunit:-3
#endif
+#if defined(SCREEN_UV_USED)
+
+uniform vec2 screen_pixel_size;
+#endif
+
layout(std140) uniform CanvasItemData {
highp mat4 projection_matrix;
- highp vec4 time;
+ highp float time;
};
@@ -180,9 +245,8 @@ uniform lowp sampler2D light_texture; // texunit:-1
in vec4 light_uv_interp;
-#if defined(NORMAL_USED)
in vec4 local_rot;
-#endif
+
#ifdef USE_SHADOWS
@@ -191,11 +255,14 @@ in highp vec2 pos;
#endif
+const bool at_light_pass = true;
+#else
+const bool at_light_pass = false;
#endif
uniform mediump vec4 final_modulate;
-FRAGMENT_SHADER_GLOBALS
+
layout(location=0) out mediump vec4 frag_color;
@@ -211,11 +278,108 @@ MATERIAL_UNIFORMS
#endif
+FRAGMENT_SHADER_GLOBALS
+
+void light_compute(inout vec3 light,vec3 light_vec,float light_height,vec4 light_color,vec2 light_uv,vec4 shadow,vec3 normal,vec2 uv,vec2 screen_uv,vec4 color) {
+
+#if defined(USE_LIGHT_SHADER_CODE)
+
+LIGHT_SHADER_CODE
+
+#endif
+
+}
+
+#ifdef USE_TEXTURE_RECT
+
+uniform vec4 dst_rect;
+uniform vec4 src_rect;
+uniform bool clip_rect_uv;
+
+#ifdef USE_NINEPATCH
+
+in highp vec2 pixel_size_interp;
+
+uniform int np_repeat_v;
+uniform int np_repeat_h;
+uniform bool np_draw_center;
+//left top right bottom in pixel coordinates
+uniform vec4 np_margins;
+
+
+
+float map_ninepatch_axis(float pixel, float draw_size,float tex_pixel_size,float margin_begin,float margin_end,int np_repeat,inout int draw_center) {
+
+
+ float tex_size = 1.0/tex_pixel_size;
+
+ if (pixel < margin_begin) {
+ return pixel * tex_pixel_size;
+ } else if (pixel >= draw_size-margin_end) {
+ return (tex_size-(draw_size-pixel)) * tex_pixel_size;
+ } else {
+ if (!np_draw_center){
+ draw_center--;
+ }
+
+ if (np_repeat==0) { //stretch
+ //convert to ratio
+ float ratio = (pixel - margin_begin) / (draw_size - margin_begin - margin_end);
+ //scale to source texture
+ return (margin_begin + ratio * (tex_size - margin_begin - margin_end)) * tex_pixel_size;
+ } else if (np_repeat==1) { //tile
+ //convert to ratio
+ float ofs = mod((pixel - margin_begin), tex_size - margin_begin - margin_end);
+ //scale to source texture
+ return (margin_begin + ofs) * tex_pixel_size;
+ } else if (np_repeat==2) { //tile fit
+ //convert to ratio
+ float src_area = draw_size - margin_begin - margin_end;
+ float dst_area = tex_size - margin_begin - margin_end;
+ float scale = max(1.0,floor(src_area / max(dst_area,0.0000001) + 0.5));
+
+ //convert to ratio
+ float ratio = (pixel - margin_begin) / src_area;
+ ratio = mod(ratio * scale,1.0);
+ return (margin_begin + ratio * dst_area) * tex_pixel_size;
+ }
+ }
+
+}
+
+#endif
+#endif
+
+uniform bool use_default_normal;
+
void main() {
vec4 color = color_interp;
-#if defined(NORMAL_USED)
- vec3 normal = vec3(0.0,0.0,1.0);
+ vec2 uv = uv_interp;
+
+#ifdef USE_TEXTURE_RECT
+
+#ifdef USE_NINEPATCH
+
+ int draw_center=2;
+ uv = vec2(
+ map_ninepatch_axis(pixel_size_interp.x,abs(dst_rect.z),color_texpixel_size.x,np_margins.x,np_margins.z,np_repeat_h,draw_center),
+ map_ninepatch_axis(pixel_size_interp.y,abs(dst_rect.w),color_texpixel_size.y,np_margins.y,np_margins.w,np_repeat_v,draw_center)
+ );
+
+ if (draw_center==0) {
+ color.a=0.0;
+ }
+
+ uv = uv*src_rect.zw+src_rect.xy; //apply region if needed
+#endif
+
+ if (clip_rect_uv) {
+
+ vec2 half_texpixel = color_texpixel_size * 0.5;
+ uv = clamp(uv,src_rect.xy+half_texpixel,src_rect.xy+abs(src_rect.zw)-color_texpixel_size);
+ }
+
#endif
#if !defined(COLOR_USED)
@@ -223,17 +387,38 @@ void main() {
#ifdef USE_DISTANCE_FIELD
const float smoothing = 1.0/32.0;
- float distance = texture(color_texture, uv_interp).a;
+ float distance = textureLod(color_texture, uv,0.0).a;
color.a = smoothstep(0.5 - smoothing, 0.5 + smoothing, distance) * color.a;
#else
- color *= texture( color_texture, uv_interp );
+ color *= texture( color_texture, uv );
#endif
#endif
-#if defined(ENABLE_SCREEN_UV)
- vec2 screen_uv = gl_FragCoord.xy*screen_uv_mult;
+
+
+ vec3 normal;
+
+#if defined(NORMAL_USED)
+
+ bool normal_used = true;
+#else
+ bool normal_used = false;
+#endif
+
+ if (use_default_normal) {
+ normal.xy = textureLod(normal_texture, uv,0.0).xy * 2.0 - 1.0;
+ normal.z = sqrt(1.0-dot(normal.xy,normal.xy));
+ normal_used=true;
+ } else {
+ normal = vec3(0.0,0.0,1.0);
+ }
+
+
+
+#if defined(SCREEN_UV_USED)
+ vec2 screen_uv = gl_FragCoord.xy*screen_pixel_size;
#endif
@@ -266,9 +451,9 @@ FRAGMENT_SHADER_CODE
vec2 light_vec = light_uv_interp.zw;; //for shadow and normal mapping
-#if defined(NORMAL_USED)
- normal.xy = mat2(local_rot.xy,local_rot.zw) * normal.xy;
-#endif
+ if (normal_used) {
+ normal.xy = mat2(local_rot.xy,local_rot.zw) * normal.xy;
+ }
float att=1.0;
@@ -285,18 +470,15 @@ FRAGMENT_SHADER_CODE
#if defined(USE_LIGHT_SHADER_CODE)
//light is written by the light shader
- {
- vec4 light_out=light*color;
-LIGHT_SHADER_CODE
- color=light_out;
- }
+ light_compute(light,light_vec,light_height,light_color,light_uv,shadow,normal,uv,screen_uv,color);
#else
-#if defined(NORMAL_USED)
- vec3 light_normal = normalize(vec3(light_vec,-light_height));
- light*=max(dot(-light_normal,normal),0.0);
-#endif
+ if (normal_used) {
+
+ vec3 light_normal = normalize(vec3(light_vec,-light_height));
+ light*=max(dot(-light_normal,normal),0.0);
+ }
color*=light;
/*
@@ -350,11 +532,11 @@ LIGHT_SHADER_CODE
#ifdef USE_RGBA_SHADOWS
-#define SHADOW_DEPTH(m_tex,m_uv) dot(texture2D((m_tex),(m_uv)),vec4(1.0 / (256.0 * 256.0 * 256.0),1.0 / (256.0 * 256.0),1.0 / 256.0,1) )
+#define SHADOW_DEPTH(m_tex,m_uv) dot(texture((m_tex),(m_uv)),vec4(1.0 / (256.0 * 256.0 * 256.0),1.0 / (256.0 * 256.0),1.0 / 256.0,1) )
#else
-#define SHADOW_DEPTH(m_tex,m_uv) (texture2D((m_tex),(m_uv)).r)
+#define SHADOW_DEPTH(m_tex,m_uv) (texture((m_tex),(m_uv)).r)
#endif
@@ -373,7 +555,7 @@ LIGHT_SHADER_CODE
#ifdef SHADOW_FILTER_NEAREST
- SHADOW_TEST(su+shadowpixel_size);
+ SHADOW_TEST(su);
#endif