wip: sticker flip shader
This commit is contained in:
parent
90f690198f
commit
9643e5d88c
2 changed files with 148 additions and 2 deletions
|
@ -38,6 +38,8 @@ var detected_solids:Array
|
||||||
var detected_zones:Array
|
var detected_zones:Array
|
||||||
var Grabbed:bool = false
|
var Grabbed:bool = false
|
||||||
|
|
||||||
|
## Emitted when the sticker overlap a blocking body, preventing to be spawned as an asset in the level. Usually received by the cursor to change his sprite
|
||||||
|
signal spawn_mode_changed(can_spawn:bool)
|
||||||
#region Functions
|
#region Functions
|
||||||
func _get_configuration_warnings():
|
func _get_configuration_warnings():
|
||||||
if (get_parent() == get_tree().get_edited_scene_root()):
|
if (get_parent() == get_tree().get_edited_scene_root()):
|
||||||
|
@ -75,17 +77,19 @@ func _ready():
|
||||||
area_exited.connect(_on_area_exited)
|
area_exited.connect(_on_area_exited)
|
||||||
body_entered.connect(_on_body_entered)
|
body_entered.connect(_on_body_entered)
|
||||||
body_exited.connect(_on_body_exited)
|
body_exited.connect(_on_body_exited)
|
||||||
|
|
||||||
|
|
||||||
# TODO : Solids and interactive zone detection area should not be the same as the sticker area.
|
# TODO : Solids and interactive zone detection area should not be the same as the sticker area.
|
||||||
# IDEA: Need to export a child Area2D
|
# IDEA: Need to export a child Area2D
|
||||||
func _on_body_entered(body:Node2D):
|
func _on_body_entered(body:Node2D):
|
||||||
print("body entered",body)
|
print("body entered",body)
|
||||||
detected_solids.append(body)
|
detected_solids.append(body)
|
||||||
|
spawn_mode_changed.emit(false)
|
||||||
func _on_body_exited(body:Node2D):
|
func _on_body_exited(body:Node2D):
|
||||||
print("body exited",body)
|
print("body exited",body)
|
||||||
detected_solids.erase(body)
|
detected_solids.erase(body)
|
||||||
if(Sticker_mode and Grabbed and detected_solids.size() == 0):
|
if(Sticker_mode and Grabbed and detected_solids.size() == 0 ):
|
||||||
print("Can be released in object mode")
|
spawn_mode_changed.emit(true)
|
||||||
func _on_area_entered(area:Area2D):
|
func _on_area_entered(area:Area2D):
|
||||||
print("area entered",area)
|
print("area entered",area)
|
||||||
#TODO:Filter by type
|
#TODO:Filter by type
|
||||||
|
|
142
shaders/pageflip.gdshader
Normal file
142
shaders/pageflip.gdshader
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
shader_type canvas_item;
|
||||||
|
uniform vec2 scale = vec2(1,1);
|
||||||
|
uniform vec2 flip_pos = vec2(-1.,-1.);
|
||||||
|
|
||||||
|
vec2 Line2point(vec2 linePoint,vec2 lineDire,vec2 point) {
|
||||||
|
lineDire = normalize(lineDire);
|
||||||
|
vec2 line2Ori = - linePoint - dot(-linePoint,lineDire)*lineDire;
|
||||||
|
vec2 p2Ori = - point - dot(-point,lineDire)*lineDire;
|
||||||
|
return line2Ori-p2Ori;
|
||||||
|
}
|
||||||
|
vec4 ColorWithA(vec4 oldCol,vec4 newCol){
|
||||||
|
vec4 finalCol;
|
||||||
|
if((newCol.a + oldCol.a)>=1.)
|
||||||
|
{
|
||||||
|
finalCol.rgb = newCol.rgb ;
|
||||||
|
finalCol.a =1.0;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
finalCol.rgb = newCol.a/(newCol.a + oldCol.a)*newCol.rgb + oldCol.a/(newCol.a + oldCol.a)*oldCol.rgb;
|
||||||
|
finalCol.a = oldCol.a +newCol.a;
|
||||||
|
}
|
||||||
|
return finalCol;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fragment() {
|
||||||
|
vec2 uv = UV;
|
||||||
|
// vec2 mouse_uv = flip_pos ;
|
||||||
|
vec4 finalColor = vec4(0.0); // Initialize with transparent color
|
||||||
|
//拉伸变形校正
|
||||||
|
float scale_min = scale.x/scale.y;
|
||||||
|
vec2 uv_max = vec2(scale_min,1.);
|
||||||
|
float trueScale;
|
||||||
|
if(scale.y<scale.x){
|
||||||
|
scale_min = scale.y/scale.x;
|
||||||
|
uv.y = uv.y * scale_min;
|
||||||
|
uv_max = vec2(1.,scale_min);
|
||||||
|
// mouse_uv = flip_pos * TEXTURE_PIXEL_SIZE /scale.x;
|
||||||
|
trueScale = scale.x;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
uv.x = uv.x*scale_min;
|
||||||
|
// mouse_uv = flip_pos * TEXTURE_PIXEL_SIZE /scale.y;
|
||||||
|
trueScale = scale.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
COLOR= texture(TEXTURE,uv);
|
||||||
|
|
||||||
|
|
||||||
|
//鼠标响应
|
||||||
|
vec2 pPos = uv / TEXTURE_PIXEL_SIZE * trueScale;
|
||||||
|
if (flip_pos.x>-0.0001)
|
||||||
|
{
|
||||||
|
vec2 left_bottom = vec2(0.,uv_max.y/TEXTURE_PIXEL_SIZE.y * trueScale);
|
||||||
|
vec2 midpoint = (flip_pos - left_bottom)/2. + left_bottom;
|
||||||
|
// vec2 midDirect = vec2(-1.,-1.)/1.414;
|
||||||
|
vec2 midDirect = normalize(vec2(-(flip_pos-left_bottom).y,(flip_pos-left_bottom).x));
|
||||||
|
//bg
|
||||||
|
|
||||||
|
//pageback
|
||||||
|
vec2 sharpPoint = vec2(0.,midpoint.y - midDirect.y/midDirect.x * midpoint.x);
|
||||||
|
vec2 flipEdgeDire = normalize(sharpPoint - flip_pos);
|
||||||
|
//pagebackBottom
|
||||||
|
vec2 sharpPointB = vec2(midpoint.x-midDirect.x/midDirect.y * (midpoint-left_bottom).y,left_bottom.y);
|
||||||
|
vec2 flipEdgeDireB = normalize(sharpPointB - flip_pos);
|
||||||
|
|
||||||
|
//圆柱
|
||||||
|
float cyOriOff = length(flip_pos-left_bottom);
|
||||||
|
if (cyOriOff>100.) cyOriOff = 100.;//圆柱向里面缩进
|
||||||
|
float cyR = cyOriOff*2./PI;
|
||||||
|
float pageHDire = PI/6.;
|
||||||
|
vec2 midlineToP = Line2point(midpoint,midDirect,pPos);
|
||||||
|
vec2 sideEdgeToP = Line2point(flip_pos,flipEdgeDire,pPos);
|
||||||
|
vec2 BottomEdgeToP = Line2point(flip_pos,flipEdgeDireB,pPos);
|
||||||
|
|
||||||
|
vec2 cyOriToP = midlineToP - normalize(flip_pos- left_bottom)*cyOriOff;
|
||||||
|
vec2 cyEdgeToP = midlineToP - normalize(flip_pos- left_bottom)*(cyOriOff-cyR);
|
||||||
|
|
||||||
|
bool atBG = (cyOriToP).x<=-0.01;
|
||||||
|
bool atPageBack = !atBG&&(sideEdgeToP.y>0.)&&(BottomEdgeToP.x<=0.);
|
||||||
|
// bool atCy = (cyOriToP).x<=0.;
|
||||||
|
bool atCy = cyEdgeToP.x >=0. && (cyOriToP).x<=0.;
|
||||||
|
bool atCyPage = false;
|
||||||
|
vec2 uvCy ;
|
||||||
|
vec2 uvCyB ;
|
||||||
|
|
||||||
|
|
||||||
|
float shadow = 1.;
|
||||||
|
if (atCy){
|
||||||
|
vec2 cyOri = pPos-cyOriToP;
|
||||||
|
vec2 trueDis = cyR* asin(length(cyOriToP)/cyR)*normalize(cyOriToP);
|
||||||
|
vec2 truePos = cyOri+trueDis;
|
||||||
|
|
||||||
|
vec2 sideEdgeToTP = Line2point(flip_pos,flipEdgeDire,truePos);
|
||||||
|
vec2 BottomEdgeToTP = Line2point(flip_pos,flipEdgeDireB,truePos);
|
||||||
|
uvCyB = truePos * TEXTURE_PIXEL_SIZE /trueScale;
|
||||||
|
shadow *= 1.-pow(length(trueDis)/(cyR*PI/2.),3.);
|
||||||
|
|
||||||
|
if ((BottomEdgeToTP.x<0.)&& (sideEdgeToTP.y>0.))
|
||||||
|
{
|
||||||
|
atCyPage = true;
|
||||||
|
uvCy = vec2(length(sideEdgeToTP),left_bottom.y-length(BottomEdgeToTP))*TEXTURE_PIXEL_SIZE /trueScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((uvCyB.x > uv_max.x)||(uvCyB.y > uv_max.y)||(uvCyB.x <= 0.)|| (uvCyB.y <= 0.))
|
||||||
|
atCy =false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//色彩
|
||||||
|
COLOR = vec4(0.);
|
||||||
|
// Page
|
||||||
|
if (!atBG && !atCy) {
|
||||||
|
vec4 color = texture(TEXTURE, uv);
|
||||||
|
finalColor = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
// cyBottom
|
||||||
|
if (atCy) {
|
||||||
|
vec4 cyColor = texture(TEXTURE, uvCyB);
|
||||||
|
finalColor = cyColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (atCyPage) {
|
||||||
|
vec4 cyPageColor = texture(TEXTURE, uvCy);
|
||||||
|
cyPageColor.xyz *= 0.8;
|
||||||
|
// Blend based on the alpha value of cyPageColor
|
||||||
|
finalColor = mix(finalColor, cyPageColor, cyPageColor.a);
|
||||||
|
} else if (atPageBack) {
|
||||||
|
uv = vec2(length(sideEdgeToP), left_bottom.y - length(BottomEdgeToP)) * TEXTURE_PIXEL_SIZE / trueScale;
|
||||||
|
vec4 pageBackColor = texture(TEXTURE, uv);
|
||||||
|
pageBackColor.xyz *= 0.8;
|
||||||
|
// Blend based on the alpha value of pageBackColor
|
||||||
|
finalColor = mix(finalColor, pageBackColor, pageBackColor.a);
|
||||||
|
}
|
||||||
|
|
||||||
|
COLOR = finalColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Place fragment code here.
|
||||||
|
|
||||||
|
// FRAGCOORD.xy;
|
||||||
|
}
|
Loading…
Reference in a new issue