#version 120 uniform sampler2D texture; uniform vec2 texSize; //Margin setting in skin (pixels) uniform vec4 margin_src; uniform vec4 margin_dest; //Position and Size of region being rendered on the texture (pixels) uniform vec2 pos, size; //Size of region being rendered to (pixels) uniform vec2 size_out; //Mode of rendering (0=Uniform, 1=Scaled, 2=Tiled) uniform vec2 dim_mode; //Number of gradients used uniform float gradientCount; //Gradient location (in pixels) relative to the rendered destination uniform vec4 gradientRect; //Gradient colors (tl, tr, bl, br) uniform vec4[4] gradientColors; //Gradient mode uniform float gradientMode; varying vec4 color; varying vec2 uv; varying vec2 qpos; float realPos(int dimension, float point) { if(dim_mode[dimension] == 0.0) //Uniform return pos[dimension] + (point * size[dimension]); else { //Margin expressed in 0-1 for the destination region float l_margin = margin_dest[dimension] / size_out[dimension]; float r_margin = margin_dest[dimension+2] / size_out[dimension]; if(point <= l_margin) return pos[dimension] + (point / l_margin * margin_src[dimension]); else if(point >= 1.0 - r_margin) return pos[dimension] + size[dimension] + (point-1.0) / r_margin * margin_src[dimension+2]; float region_inner_size = size_out[dimension] - margin_dest[dimension] - margin_dest[dimension+2]; float inner_size = size[dimension] - margin_src[dimension] - margin_src[dimension+2]; //point is now 0-1 through the inner destination region point = (point - l_margin) * (size_out[dimension] / region_inner_size); if(dim_mode[dimension] == 1.0) { //Scaled return pos[dimension] + margin_src[dimension] + (point * inner_size); } else { //Tiled point = fract(point * region_inner_size / inner_size); return pos[dimension] + margin_src[dimension] + (point * inner_size); } } } void main() { vec2 tcoord = vec2( realPos(0, uv.x) / float(texSize.x), realPos(1, uv.y) / float(texSize.y) ); vec4 skinSample = texture2D(texture, tcoord, -4); if(skinSample.a < 0.01 && gradientMode == 0.0) discard; //Apply gradients if(gradientCount != 0.0) { vec4 rect = gradientRect / size_out.xyxy; vec2 gPos = vec2( (uv.x - rect.x) / (rect.z - rect.x), (uv.y - rect.y) / (rect.w - rect.y) ); //Make sure the tranformed rect is within (0,0) (1,1) if( all( bvec4(greaterThanEqual(gPos, vec2(0.0,0.0)), lessThanEqual(gPos, vec2(1.0,1.0))) ) ) { //Add noise float rnd = dot(qpos, pos); gPos.y = clamp(gPos.y + mod(rnd/max(mod(uv.x,0.01)/0.01, 0.001), 0.1)-0.05, 0.0, 1.0); gPos.x = clamp(gPos.x + mod(rnd/max(mod(uv.y,0.01)/0.01, 0.001), 0.1)-0.05, 0.0, 1.0); //Bilinear interpolation for the gradient color vec4 gCol = mix( mix(gradientColors[0], gradientColors[1], gPos.x), mix(gradientColors[2], gradientColors[3], gPos.x), gPos.y ); if(gradientMode == 1.0) skinSample = gCol; else skinSample.rgb = mix(skinSample.rgb, gCol.rgb, gCol.a); } } gl_FragColor = skinSample * color; }