diff options
Diffstat (limited to 'drivers/gles3/shaders/canvas.glsl')
-rw-r--r-- | drivers/gles3/shaders/canvas.glsl | 248 |
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 |