One: the characteristics of the parabola
In the parabola y^2=2px, the focus is (p/2, 0), the equation of the directrix is x= -p/2, the eccentricity e=1, and the range: x≥0.
In the parabola y^2= -2px, the focus is (-p/2, 0), the equation of the directrix is x=p/2, the eccentricity e=1, and the range: x≤0.
In the parabola x^2=2py, the focus is (0, p/2), the equation of the directrix is y= -p/2, the eccentricity e=1, and the range: y≥0.
In the parabola x^2= -2py, the focus is (0, -p/2), the equation of the directrix is y=p/2, the eccentricity e=1, and the range: y≤0.
Eccentricity is the ratio of the distance of a point on a conic section from the focus to the distance from the directrix
An eccentricity less than one is an ellipse
Equal to one is a parabola
Greater than one is hyperbolic
When it is equal to zero, it is a circle
It shows that when the cone is cut, it is cut continuously.
Deformation:
// 当uv.x - uv.y * 0.5 * uv.y + t = 0的时候表示改像素点在这条线段上,否则不在
float d = uv.x - uv.y * 0.5 * uv.y + t;
// 这里讨论d 是大于零还是小于零
// d > 0 像素点在曲线的右方
// d < 0 像素点在曲线的左方
Works with almost any curve, with some exceptions
1: For a closed curve < 0 is inside the closed curve, greater than zero is outside the curve.
2: Applicable for one x value corresponds to one y value
3: For an unclosed curve with an x value corresponding to two y values, when the opening is to the right, < 0 is on the right side of the curve, > 0 is on the left side of the curve, and the point of the curve opening to the left < 0 is on the left side of the curve , the points >0 are on the right side of the curve
The following uses these principles to achieve the effect of a piece of paper on fire:
Two: cocos creator implementation
// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
CCEffect %{
techniques:
- passes:
- vert: vs
frag: fs
blendState:
targets:
- blend: true
rasterizerState:
cullMode: none
properties:
texture: { value: white }
noiseTexture: {value: white}
alphaThreshold: { value: 0.5 }
}%
CCProgram vs %{
precision highp float;
#include <cc-global>
#include <cc-local>
in vec3 a_position;
in vec4 a_color;
out vec4 v_color;
#if USE_TEXTURE
in vec2 a_uv0;
out vec2 v_uv0;
#endif
void main () {
vec4 pos = vec4(a_position, 1);
#if CC_USE_MODEL
pos = cc_matViewProj * cc_matWorld * pos;
#else
pos = cc_matViewProj * pos;
#endif
#if USE_TEXTURE
v_uv0 = a_uv0;
#endif
v_color = a_color;
gl_Position = pos;
}
}%
CCProgram fs %{
precision highp float;
#include <alpha-test>
#include <texture>
#include <cc-global>
in vec4 v_color;
#if USE_TEXTURE
in vec2 v_uv0;
uniform sampler2D texture;
uniform sampler2D noiseTexture;
#endif
vec4 textureSource(vec2 uv) {
return texture2D(texture,uv).rgba;
}
vec4 textureTarget(vec2 uv) {
return texture2D(noiseTexture,uv).rgba;
}
float hash(vec2 p) {
vec3 p2 = vec3(p.xy,1.);
return fract(sin(dot(p2,vec3(37.1,61.7,12.4))) * 3758.54);
}
float noise(vec2 p) {
vec2 i = floor(p);
vec2 f = fract(p);
f *= f * (3. - 2. *f);
return mix(mix(hash(i + vec2(0.,0.)), hash(i + vec2(1.,0.)),f.x),
mix(hash(i + vec2(0.,1.)), hash(i + vec2(1.,1.)),f.x),
f.y);
}
float fbm(vec2 p) {
float v = 0.0;
v += noise(p*1.)*.5;
v += noise(p*2.)*.25;
v += noise(p*4.)*.125;
return v;
}
vec4 mainImage(vec2 uv) {
vec4 src = textureSource(uv);
vec4 tgt = textureTarget(uv);
vec4 col = src;
uv.x -= 1.5;
// 控制火焰的燃烧时间
float t = 2.;
// [0 ~ 2.5)
float ctime = mod(cc_time.x * .5,t);
// d = x + 0.25 * y * y 抛物线方程 y * y = -x; 开口向左 曲线上的点到抛物线焦点的距离 y * y = 4 - 4x 焦点坐标(-1,0)形状就是抛物线
// 0.5 * fbm(uv * 15.1) 造型函数
// 所有的像素点到曲线的距离(非垂直距离而是直线距离)
float d = uv.x - uv.y * 0.5 * uv.y + 0.5 * fbm(uv * 15.2) + ctime * 1.3;
// d > 0 表示像素点在曲线的右边 d < 0 表示像素点在曲线的左边 d = 0 表示像素点在曲线上
// 约束 col的值的三个分量在【0,0.4】范围内颜色会变暗
if(d > 0.4) col = clamp(col - (d - 0.4) * 10.,0.0,1.0);
if(d > 0.47) {
// 控制火焰颜色
vec4 fireColor = vec4(1.5,0.5,0.,1.);
// 火焰最红的厚度
float fireWeight = 0.4;
// 距离在 0.47 ~ 0.5的时候直接显示火焰的颜色
if(d < 0.5) col += (d - fireWeight) * 33.0 * 0.5 * (0.0 + noise(100. * uv + vec2(-ctime * 2.,0.))) * fireColor;
// 如果距离大于0.5的时候直接显示黑色
else col += vec4(0.,0.,0.,0.);
}
return col;
}
void main () {
vec4 o = vec4(1, 1, 1, 1);
#if USE_TEXTURE
CCTexture(texture, v_uv0, o);
#endif
o *= v_color;
ALPHA_TEST(o);
// mainImage(o);
vec2 uv = v_uv0;
uv.y = 1. - uv.y;
o.rgba = mainImage(uv);
#if USE_BGRA
gl_FragColor = o.bgra;
#else
gl_FragColor = o.rgba;
#endif
}
}%