admin 管理员组

文章数量: 894082

CocosCreator Shader学习(三):放大镜缩小镜效果

放大镜缩小镜效果

原理:根据缩放比例,判断镜面范围内的点实际应该显示哪个点的颜色值,问题就变成怎么根据缩放比例进行坐标转换!

顶点着色器代码不用修改。

片元着色器代码如下:

CCProgram fs %{precision highp float;#include <alpha-test>in vec4 v_color;#if USE_TEXTUREin vec2 v_uv0;uniform sampler2D texture;#endifuniform inputData{float scale; //缩放比例 0~1~2float showRadius; //显示半径vec2 imageSize; //图片实际尺寸vec2 point;  //缩放中心点};//检查pos点是否在显示圆内bool checkPointInCircle(vec2 pos){//pos是ndc坐标,转换成实际坐标pos.x *= imageSize.x;pos.y = (1.0 - pos.y)*imageSize.y;//计算pos到point的距离float distance = sqrt(pow(pos.x - point.x, 2.0) + pow(pos.y - point.y, 2.0));return distance <= showRadius;}//根据缩放比例转换坐标vec2 getPointTransition(vec2 pos){vec2 uv = vec2(point.x/imageSize.x, 1.0 - point.y/imageSize.y);uv.x = uv.x - (uv.x - pos.x)/scale;uv.y = uv.y - (uv.y - pos.y)/scale;return uv;}void main () {vec4 o = vec4(1, 1, 1, 1);#if USE_TEXTUREif(checkPointInCircle(v_uv0)){vec2 uv = getPointTransition(v_uv0);if(uv.x > 1.0 || uv.x < 0.0 || uv.y > 1.0 || uv.y < 0.0){//超出纹理范围的用黑色填充o = vec4(0, 0, 0, 1);}else{o *= texture(texture, uv);if(o.a == 0.0){//发现透明度为0的坐标,直接用黑色填充o = vec4(0, 0, 0, 1);}}}else{//不在圆内的点直接获取纹理o *= texture(texture, v_uv0);}#if CC_USE_ALPHA_ATLAS_TEXTUREo.a *= texture2D(texture, v_uv0 + vec2(0, 0.5)).r;#endif#endifo *= v_color;ALPHA_TEST(o);gl_FragColor = o;}
}%

脚本代码如下:

const {ccclass, property} = cc._decorator;@ccclass
export default class Cocos3 extends cc.Component {@property(cc.Label)label: cc.Label = null;@property(cc.Slider)slider: cc.Slider = null;material: cc.Material = null;scale: number = 1.0;start () {this.material = this.node.getComponent(cc.Sprite).getMaterial(0);//设置初始缩放比例this.material.setProperty("scale", this.scale);//设置缩放显示圆的半径this.material.setProperty("showRadius", 50.0);//设置图片宽高this.material.setProperty("imageSize", cc.v2(this.node.width, this.node.height));this.label.string = this.scale.toFixed(2);this.slider.progress = 0.5;this.slider.node.on("slide", this.sliderMoveCallBack, this);this.node.on(cc.Node.EventType.TOUCH_MOVE, this.touchMoveCallBack, this);}// update (dt) {}private sliderMoveCallBack(slider: cc.Slider){this.scale = slider.progress*1.9 + 0.1;this.label.string = this.scale.toFixed(2);//修改缩放比例this.material.setProperty("scale", this.scale);}private touchMoveCallBack(event: cc.Event.EventTouch){//当前获取到的触摸点是相对于左下角为原点的坐标,//需要经过一系列换算成相对于当前精灵左下角为原点的坐标。let pos: cc.Vec2 = event.getLocation();pos = pos.sub(cc.v2(cc.winSize.width/2, cc.winSize.height/2));pos = pos.sub(this.node.getPosition());pos = pos.add(cc.v2(this.node.getContentSize().width/2, this.node.getContentSize().height/2));//修改缩放中心点this.material.setProperty("point", pos);}
}

效果图如下:

本文标签: CocosCreator Shader学习(三)放大镜缩小镜效果