自己写Shader-翻书效果
尝试练习翻书效果shader的制作
- 思路
- 翻页原理
- 直翻页:
- 思路:
- 代码:
- 总结:
- 曲线从一角翻页
- 思路:
- 效果
- 把效果和数学联系起来
- 角翻页有点复杂,,,
思路
- 直直的翻页,即将页面旋转180完成翻页,不存在弯曲效果
- 弯曲翻页,页面从一个角有曲线的翻动
翻页原理
https://blog.csdn.net/ls4985/article/details/110195030
https://gitbook.cn/books/5f3bd55ab74e2f16f57ea9e6/index.html
直翻页:
https://zhuanlan.zhihu.com/p/28836892
直翻页参考上边,但是他的效果不好(谁见过书从中间翻出来一页的。。),所以自己使用unity默认plane来重新弄了一个,将plane分为两半,使用一半来贴纹理,然后翻页到另一半。
思路:
书本效果分析:
如图,将书分为三种页面:
第一种:黄色的竖起来的那一页,正反两个面
第二种:想象自己在桌子下面,往天上看到的两个页面,即图中紧贴地面的两个面
第三种:剩下的两个面,即 图中看到的左右两个灰色页面shader设计:
对三种页面进行分析:
其中两个页面可以公用顶点着色器,一个页面需要顶点翻转效果
我这里分出了四个pass:
第一个 渲染正面 左半页不动,采样 右半页翻动,采样
第二个 渲染背面 左半页不动,不采样(多余) 右半页翻动,采样
第三个 渲染正面 左半页不动,不采样(多余) 右半页不动,采样
第四个 渲染背面 左半页不动,采样 右半页不动,采样
渲染了8个页面,两个不需要,进行透明,这样6个页面就都渲染出来
注意在翻书的 开始和结尾 透明控制纹理设计:
对渲染的贴图分析:
将一本书的图片分成左右两部分图片,封面为右侧第一张,封底为左侧最后一张
即
Texture bookfirst;
Texture booklast;
Texture[] leftPages;
Texture[] rightPages;
之所以记录封面和封底是因为书不管什么状态这两个图片总是要渲染出来。翻页逻辑:
剔除第一页和最后一页的特殊情况。
书本会同时出现左侧两幅图,右侧两幅图 +封面和封底。(6张贴图)
每翻动一次,贴图往后移动一张。其他:
这里因为书本第一页和书本最后一页翻动时需要透明,所以这两处情况需要特殊处理,再shader中判断。
针对这种情况,可以对 左右分页的图片 增加透明图片来变为通用情况。即第一页时左侧第一个图片为透明图片,最后一页时,右侧最后图片为透明。 这样在逻辑判断时就不需要多余判断了脚本逻辑:
因为shader需要不断更替左右页的贴图。所以必然要通过脚本来控制
1.控制贴图在翻页完成时 更替。
2.由总贴图数量,控制翻页次数。
3.管理翻页进度。给定进度即可渲染当前书状态。使用进度条管理书本翻动。
代码:
这里贴出了使用透明图片占位的代码。不使用透明图片需要自己再加前后状态的判断即可。
Shader部分:
Shader "SxerShader/BookEffectShader1"
{ /*翻页效果,实现页面直翻动180度的效果参考:https://zhuanlan.zhihu.com/p/28836892制作思路:1.使用unity默认plane来实现翻页,且 要分为 左右 页面来翻动,而不是参考中的一个页面从中间翻动2.为了将plane分为左右部分,需要对原plane顶点uv重新划分(以uv横坐标的一半来划分)右侧:uv横坐标大于0.5的部分,即【0.5,1】映射为【0,1】 (向左移0.5再扩大2即可)左侧:【0,0.5】映射为【0,1】 (扩大2即可)3.这样划分的话,左右页面会共用中线的顶点数据,所以分开存储两幅uv坐标4.在片元着色器采样时,因为片元取的是多个顶点混合数据,所以会产生一侧的纹理对另一侧影响【即在中线左右两排的顶点之间存在颜色过渡】5.为了剔除这种影响,增加左右顶点标识变量LR,值为1则说明该点位于哪一侧6.但 若是直接将标识为0的颜色透明,则会有花屏现象,应该还是顶点混合的缘故,所以以<0.0001来代替*///把书平铺打开,然后翻起一页(倒T型)//可以划分出三个正面,三个背面//紧贴桌面的两个面(背面),和两个面的反面(正面) 翻动的页面的正反两面//当书是这个状态时,渲染了6副图, 书封面和封底,左侧的一页,翻起的左侧第二页,翻起的右侧一页,平铺的右侧第二页//把书页划分为左右//右一即为封面//左最后为封底//且在翻动过程中 存在特殊情况:即刚开始 左一为透明(书本未打开时)// 结束时 右最后为透明(最后一页翻过来时)// 不考虑特殊情况时 每翻动一次书页 左右图片进度+1//左面 右面Properties{//封面_BookFirst("BookFirst Page",2D) = "white"{}_BookLast("BookLast Page",2D) = "white"{}//右1 右2 左1 左2_RightPageTex("RightPage Texture",2D)= "white"{}_RightPage2Tex("RightPage 2 Texture",2D) = "white"{}_LeftPageTex("LeftPage Texture",2D)= "white"{}_LeftPage2Tex("LeftPage 2 Texture",2D)="white"{}_PlaneXLength("PlaneModel X Length",float)=1_BookState("Book State",int)=2// _MainTex("Main Texture",2D)="white"{}_DiffuseColor("Diffuse Color",Color)=(1,1,1,0)_PageAngle("Page Angle",Range(0,1)) = 0}SubShader{Tags{"RenderType" = "Transparent""Queue" = "Transparent""IgnoreProjector" = "True"}CGINCLUDE#include "UnityCG.cginc"sampler2D _RightPageTex;sampler2D _RightPage2Tex;sampler2D _LeftPageTex;sampler2D _LeftPage2Tex;sampler2D _BookFirst;sampler2D _BookLast;fixed4 _DiffuseColor;float _PageAngle;float _PlaneXLength;int _BookState;#define PI 3.1415926float4 moveVertexByAngle(float4 ver){float an = PI * _PageAngle;float4 tempVertex = ver;tempVertex.x = ver.x * cos(an);tempVertex.y = ver.x * sin(an);return tempVertex;}struct v2f{float4 pos:SV_POSITION;float4 uv:TEXCOORD0;//xy存储右侧,zw存储左侧float2 LR:TEXCOORD1;//区分左右页的顶点};//顶点翻转效果v2f vert_flip(appdata_base v){v2f o;float4 vPos;o.uv.xy = o.uv.zw = 1 - v.texcoord;//plane颠倒//unity默认plane的x>0部分为书的右半部分 右侧的顶点uv变动 贴一张纹理if(o.uv.x >= 0.5){o.uv.x = (o.uv.x - 0.5) * 2;//右侧一半为一页o.LR = float2(0,1);//右侧标记vPos = moveVertexByAngle(v.vertex);//右侧旋转}//左边if(o.uv.z <= 0.5){o.uv.z *= 2;//默认uv原点即在左边,且plane左右对称,所以左侧u缩小一半即可o.LR = float2(1,0);//左侧vPos = v.vertex;//左侧不动}//左右分页存在公用顶点(中线)。且顶点的参数值在片元着色时会产生影响。这里单独设置if(v.vertex.x == 0){//纹理采样时 两个顶点间会有颜色过渡 左右页面会互相影响 0.5影响小点o.LR = float2(0,0);}o.pos = UnityObjectToClipPos(vPos);return o;}//仅改变uvv2f vert(appdata_base v){v2f o;float4 vPos;vPos = v.vertex;o.uv.xy = o.uv.zw = 1 - v.texcoord;//unity默认plane的x>0部分为书的右半部分 右侧的顶点uv变动 贴一张纹理if(o.uv.x >= 0.5){o.uv.x = (o.uv.x - 0.5) * 2;//右侧一半为一页o.LR = float2(0,1);//右侧标记}//左边if(o.uv.z <= 0.5){o.uv.z *= 2;//默认uv原点即在左边,且plane左右对称,所以左侧u缩小一半即可o.LR = float2(1,0);//左侧}//左右分页存在公用顶点(中线)。且顶点的参数值在片元着色时会产生影响。这里单独设置if(v.vertex.x == 0){//纹理采样时 两个顶点间会有颜色过渡 左右页面会互相影响 0.5影响小点o.LR = float2(0,0);}o.pos = UnityObjectToClipPos(vPos);return o;}//底部的左右页面fixed4 frag_back_both(v2f i):SV_Target{fixed4 rightColor;fixed4 leftColor;fixed4 mainColor;//根据视觉 翻转i.uv.x = 1- i.uv.x;i.uv.z = 1- i.uv.z;//右页纹理采样//背部封面if(_BookState<0){rightColor.rgba = fixed4(1,1,1,0);}else{rightColor.rgba = tex2D(_BookLast,i.uv.xy).rgba;} //片元着色器差值影响 //片元的值受周围顶点影响,所以不做变动的话,左右页面交界处会相互影响。//在顶点中,以中线为0,中线两侧逐渐增大,所以,这里的值越接近零,两个页面越接近,//对右侧页面来说,左边透明if(i.LR.y<0.00001)rightColor.a = 0;//左页纹理采样//封面if(_BookState>0){leftColor.rgba = fixed4(1,1,1,0);}else{leftColor.rgba = tex2D(_BookFirst,i.uv.zw).rgba;}//对左侧来说,右侧透明if(i.LR.x<0.00001)leftColor.a = 0;//左页纹理采样//应用两侧的透明mainColor = leftColor * leftColor.a + rightColor * rightColor.a;return mainColor;}fixed4 frag_both(v2f i):SV_Target{fixed4 rightColor;fixed4 leftColor;fixed4 mainColor;//右一纹理采样rightColor.rgba = tex2D(_RightPageTex,i.uv.xy).rgba;if(i.LR.y<0.00001)rightColor.a = 0;//左一纹理采样 //如果用透明图占位 则直接采样左一纹理即可leftColor.rgba = tex2D(_LeftPageTex,i.uv.zw).rgba;if(i.LR.x<0.00001)leftColor.a = 0;//应用两侧的透明mainColor = leftColor * leftColor.a + rightColor * rightColor.a;return mainColor;}//左二纹理采样 fixed4 frag_back_half(v2f i):SV_Target{fixed4 rightColor;i.uv.x = 1 - i.uv.x;//根据视觉背面左右颠倒//封面 //如果用透明图占位 则直接采样左二纹理即可rightColor.rgba = tex2D(_LeftPage2Tex,i.uv.xy).rgba;//右页纹理采样//片元着色器差值影响 //片元的值受周围顶点影响,所以不做变动的话,左右页面交界处会相互影响。//在顶点中,以中线为0,中线两侧逐渐增大,所以,这里的值越接近零,两个页面越接近,//对右侧页面来说,左边透明if(i.LR.y<0.00001)rightColor.a = 0;return rightColor;}//左右采样不反转,采样右侧第二纹理fixed4 frag_half_Second(v2f i):SV_Target{fixed4 rightColor;//背部封面//如果用透明图占位 则直接采样右二纹理即可rightColor.rgba = tex2D(_RightPage2Tex,i.uv.xy).rgba;if(i.LR.y<0.00001)rightColor.a = 0;return rightColor;}ENDCG//第三个 渲染正面 左半页不动,不采样 右半页不动,采样//最后一页正面 左侧 透明 右侧显示第二页 //Pass{//这个pass如果放在第一页正面后边,会出现显示bugCull Back//Offset 1, 1ZWrite OffBlend SrcAlpha OneMinusSrcAlphaCGPROGRAM#pragma vertex vert#pragma fragment frag_half_Second ENDCG}//第一个 渲染正面 左半页不动,采样 右半页翻动,采样Pass{Cull Back//剔除背面ZWrite OffBlend SrcAlpha OneMinusSrcAlphaCGPROGRAM#pragma vertex vert_flip#pragma fragment frag_bothENDCG}//第二个 渲染背面 左半页不动,不采样 右半页翻动,采样 //采样左侧第一张纹理Pass{Cull Front//剔除正面ZWrite OffBlend SrcAlpha OneMinusSrcAlphaCGPROGRAM#pragma vertex vert_flip#pragma fragment frag_back_halfENDCG}//最后一页 背面 左侧透明 右侧显示左侧最后一页//第四个 渲染背面 左半页不动,采样 右半页不动,采样Pass{Cull FrontZWrite OffBlend SrcAlpha OneMinusSrcAlphaCGPROGRAM#pragma vertex vert#pragma fragment frag_back_both ENDCG}}FallBack Off
}
脚本控制部分:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;/** 思路:* 1.一本书的一个页面由左页和右页组成* 2.注意左右页在翻动时的变动规则:* 因为在翻书的过程中,会出现 右页两个页面同时出现* * 可以看作:对于左侧页面来说,第一页放了一张透明图占位* 对于右侧页面来说,最后一页放了一张透明图占位*/[ExecuteInEditMode]
public class BookEffect1 : MonoBehaviour
{public const int leng = 10;[Range(0, leng)]public float progress = 0;public Material mat;public List<Texture> rightPages;public List<Texture> leftPages;/// <summary>/// 可翻页数/// </summary>public int maxPage = 0;private void Start(){//因为前后都多透明图片,所以可翻页数-1maxPage = rightPages.Count - 1;//将progress映射到书页进度ChangePageImage(progress / (float)leng * (maxPage));}private void ChangePageImage(float pro){int page = (int)pro;//页数//翻页角度float angle = pro - page;mat.SetFloat("_PageAngle", angle);//页数限制page = Mathf.Clamp(page, 0, maxPage);if (page == 0)//首页{mat.SetInt("_BookState", 1);}else if (page == maxPage - 1) //最后一页图片替换{mat.SetInt("_BookState", -1);}else if(page == maxPage)//保持最终的看完状态{mat.SetFloat("_PageAngle", 1);return;}else{mat.SetInt("_BookState", 0);}mat.SetTexture("_LeftPageTex", leftPages[page]);mat.SetTexture("_LeftPage2Tex", leftPages[page + 1]);mat.SetTexture("_RightPageTex", rightPages[page]);mat.SetTexture("_RightPage2Tex", rightPages[page + 1]);mat.SetTexture("_BookFirst", rightPages[0]);mat.SetTexture("_BookLast", leftPages[maxPage - 1]);}private void Update(){ChangePageImage(progress / (float)leng * (maxPage));}
}
总结:
问题:
这算是自己第一次边思考效果,边写功能,边解决出现的问题实现的shader。
遇到了很多新鲜的问题
1.片元着色器的混合顶点间边界值问题
2.pass顺序前后遮挡效果
3.自己写功能达不到先设计再写,理清楚思路再动手的境界,往往是想一点写一点,写完后再总结修改。
4.遇到特殊问题时,在换方案和解决问题之间需要在多思考。比如这次遇到的边界值混合,一侧的纹理总是会影响另一侧,偶然的情况下判断了0.0001的阈值解决了,原本都准备换模型来适配了。
优化:
可以对直翻页加入参考连接里的曲线效果,看起来更柔和点。
??:
既然三页的书本效果出来了,是不是能做一个 支持多页的翻书?
曲线从一角翻页
先从最简单的效果搞起,如图,说是曲线翻页,先做角翻页
思路:
效果
在写翻书效果前,先看下这个简单shader
Shader "Unlit/Linear"
{Properties{_MainTex ("Texture", 2D) = "white" {}_Value("Value", Range(0,1))=0_Value2("Value2", Range(0,1))=0}SubShader{Tags{"RenderType" = "Transparent""Queue" = "Transparent""IgnoreProjector" = "True"}Pass{ ZWrite OffBlend SrcAlpha OneMinusSrcAlphaCGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct v2f{float2 uv : TEXCOORD0;UNITY_FOG_COORDS(1)float4 vertex : SV_POSITION;};sampler2D _MainTex;float4 _MainTex_ST;float _Value;float _Value2;v2f vert (appdata_base v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);return o;}fixed4 frag (v2f i) : SV_Target{// sample the texturefixed4 col = tex2D(_MainTex, i.uv);//lerp混合x,y //if(lerp(i.uv.x,i.uv.y,_Value)<_Value)// col *= 0;if(lerp(i.uv.x,i.uv.y,_Value)<_Value2)col *= 0;//if(distance(i.uv,float2(0.5,0.5))>_Value)// col *= 0;return col;}ENDCG}}FallBack Off
}
调节_value与_value2 可以看到类似书页折叠的效果,两个值一个是翻书角度,一个是翻开大小
对于一个角来说,两个极值点,当_value=0(书页直翻转90) 当_value=1(从另一个方向翻转90) 在0-1之间时存在角的翻页。
注意,当为0时,_value2可以取0-1,但为1时,_value2只能是0【书本只能一个方向翻页,左右翻页的书,你不可能上下翻】
针对这一现象,你会发现在_value变化时,对应的_value2范围是变化的,即
【_value2的取值为(0,1-_value)】 虽然在shader里超过也可以,但是实际翻书时,如果超过了,你就把书页撕掉了!
把效果和数学联系起来
看下边shadertoy第一个效果:
通过自己翻动发现:
- 翻折角的位置是以半页书的宽度为半径,以中点为圆心的原内
- 当鼠标x不变,y值影响 翻转角度 即上边的_value 且x影响y的最大值
当鼠标y不变,x值影响 进度 即_value2
角翻页有点复杂,,,
先贴几个shadertoy的翻书效果和代码:
- 效果不错的:
翻书
代码:
#define PI 3.14159265#define BOOK_BOUNDS vec4(0.15, 0.05, 0.85, 0.95)#define LIGHT_DIR vec3(5,3,1)
#define SPECULAR_SHININESS 16.0
#define SPECULAR_COLOR vec3(1.0,1.0,1.0)
#define SPECULAR_POWER 10.0vec3 fakeSpine(vec3 col, float t, float darken)
{return mix(col * darken,col , min(1.0,pow(abs(t - 0.5) * 30.0, 0.5)));
}vec3 fakeNormal(float t, float center)
{t -= center;float interp =(1.0 - abs((t - 0.5) * 2.0)) * PI + PI * (3.0/4.0) ;vec3 normal = vec3(abs(sin(interp)) ,0,abs(cos(interp)));return mix(normal, vec3(0,0,1), min(1.0,pow(abs(t - 0.5) * 5.0, 0.5)));
}vec3 specular(vec3 viewDir, vec3 normal )
{vec3 lightDir = normalize(LIGHT_DIR);float dist = length(lightDir);vec3 halfV = normalize(lightDir + normalize(viewDir));float NdotH = dot(normal, halfV);float intensity = pow(max(NdotH, 0.0), SPECULAR_SHININESS);return intensity * SPECULAR_COLOR * SPECULAR_POWER / dist;
}bool pageFlip(vec2 uv, vec2 mouse, vec2 topRight, inout vec2 sampleUV, inout vec3 normal, out float toHalfEdge)
{vec2 toEdge = topRight - mouse;vec2 toEdgeN = normalize(toEdge);vec2 toPixel = uv - mouse;vec2 diagonal = normalize(vec2(1.0));float cosT = dot(toEdgeN, diagonal);float cosT2 = 2.0 * cosT * cosT - 1.0;vec2 toEdgePerp = vec2(toEdgeN.y, -toEdgeN.x);float dir = sign(dot(toEdgePerp,diagonal));float sinT2 = dir * sqrt(1.0 - cosT2 * cosT2);vec2 nextPageUp = vec2(-sinT2, cosT2);vec2 nextPageRight = vec2(nextPageUp.y, -nextPageUp.x);if(dot(toPixel, nextPageUp) >= 0.0 && dot(toPixel, nextPageRight) >= 0.0){vec2 halfPoint = mouse + toEdge * 0.5;vec2 toPixHP = uv - halfPoint;float proj = dot(toEdgePerp, (uv - halfPoint));vec2 projPoint = halfPoint + toEdgePerp * proj;float distDiff = distance(projPoint, uv) / distance(mouse, halfPoint);toHalfEdge = distDiff;if(dot(toPixHP, toEdge) < 0.0){sampleUV = (sampleUV - mouse);sampleUV = vec2(sampleUV.y, -sampleUV.x);mat2 rot = mat2(cosT2, -sinT2, sinT2, cosT2); sampleUV = rot * sampleUV;sampleUV.y *= -1.0;sampleUV.y = 1.0 - sampleUV.y;distDiff *= 0.5;normal = fakeNormal(distDiff, -0.43);}else{normal = fakeNormal(uv.x / topRight.x, 0.07);}return false;}return true;
}void mainImage( out vec4 fragColor, in vec2 fragCoord )
{vec2 uv = fragCoord/iResolution.xy;vec3 bgCol = texture(iChannel0, uv).xyz;vec3 outCol = bgCol;vec2 bookUV = uv - BOOK_BOUNDS.xy;vec2 bookSize = vec2(BOOK_BOUNDS.zw - BOOK_BOUNDS.xy);bookUV /= bookSize;vec2 topRight = vec2(bookSize.y / bookSize.x, 1); vec2 sUV = bookUV;sUV.x *= topRight.x;vec2 nMouse = iMouse.xy / iResolution.xy;nMouse -= BOOK_BOUNDS.xy;nMouse /= bookSize.xy;nMouse = clamp(nMouse, vec2(0.0),vec2(1.0));if(iMouse.z <= 0.0 && iTime > 0.0){nMouse = vec2((sin(iTime + 0.3) + 1.0) * 0.5,(cos(iTime * 0.5) + 1.0) * 0.5);}nMouse.x *= topRight.x;float radius = topRight.x * 0.5;vec2 spineTop = vec2(radius, 1.0);vec2 spineMouse = nMouse - spineTop;float len = length(spineMouse);nMouse = spineTop + normalize(spineMouse) * min(len, radius);vec2 sampleUV = sUV;vec3 normal = vec3(0,0,1);float halfEdgeDist = 1.0;bool firstPage = pageFlip(sUV, nMouse, topRight, sampleUV, normal, halfEdgeDist);sampleUV.x /= topRight.x;vec3 page1 = texture(iChannel2, sampleUV).xyz;vec3 page2 = texture(iChannel1, sampleUV).xyz;page1 = fakeSpine(page1,bookUV.x, 0.2);page2 = fakeSpine(page2,sampleUV.x, 0.2);page2 = fakeSpine(page2, (1.0 -halfEdgeDist) * 0.5, 0.4);vec3 pageCol = firstPage ? page1 : page2;vec3 normal2 = fakeNormal(bookUV.x > 0.5 ? bookUV.x : 1.0 - bookUV.x, 0.07);normal = firstPage ? normal2 : normal;normalize(normal);pageCol += min(vec3(1,1,1), specular(vec3(0,0,1), normal)) * 0.3;if(sampleUV.x >= 0.0 && sampleUV.x <= 1.0 && sampleUV.y >= 0.0 && sampleUV.y <= 1.0){outCol = pageCol;}fragColor = vec4(outCol,1.0);
}
- 效果太好的,但也可以学习方法:翻书
代码:
/* "Flip Page" by Lucian Stanculescu - 2019Free to use, credit if you want/can.A simple page flip - the page wraps around a rolling cylinderIMPROVEMENTS- normals and lighting- compute time when page exits completely- use a cone instead of the cylinder with changing radius/height/orientation
*/ #define r 0.05
#define rep 1.0void mainImage( out vec4 fragColor, in vec2 fragCoord )
{float R = r * iResolution.x; // radius of rolling cylinderfloat v = 1.5 * iResolution.x / rep;float time = fract(iTime / rep);vec2 s = fragCoord; // pixel coordinatesvec2 u = normalize(vec2(3.0, 1.0)); // direction of movementvec2 o = vec2(time *rep* v, 0.0); // origin of cylinderfloat d = dot(s - o, u); // distance to generator of cylindervec2 h = s - u * d; // projection on generatorbool onCylinder = abs(d) < R;float angle = onCylinder ? asin(d / R) : 0.0;bool neg = d < 0.0;float a0 = 3.141592653 + angle;float a = onCylinder ? (neg ? -angle : (3.141592653 + angle)) : 0.0; // anglefloat l = R * a; // length of arcvec2 p = h - u * l; // unwrapped point from cylinder to planebool outside = any(lessThan(p, vec2(0.0))) || any(greaterThan(p, iResolution.xy));bool previous = (!onCylinder ||outside) && neg;vec4 color = (previous ? mix(0.1, 1.0, time): 1.0) * texture(iChannel0, (!onCylinder || outside ? fragCoord : p) / iResolution.xy);l = R * a0; // length of arcp = h - u * l; // unwrapped point from cylinder to planeoutside = any(lessThan(p, vec2(0.0))) || any(greaterThan(p, iResolution.xy));color = outside || !onCylinder ? color : texture(iChannel0, p / iResolution.xy);// Output to screenfragColor = color;
}
额。。搁置了。。滚去复习数学知识了。
自己写Shader-翻书效果相关推荐
- Unity Shader - 翻书效果
今天实现一个简单的翻书的效果,话不多说,先上一张效果图: 这里就随便用的一张纹理了,我们还是称为"翻木板"吧,哈哈. 实现过程: 其实这个效果实现起来还是挺简单的,大概思路其实就是 ...
- Unity 翻书效果
Unity翻书效果 目前做的VR项目中需要一个翻阅魔法书的效果,考虑过使用UnityBookPageCurl-master插件,但是那个插件是纯UI显示的,只有二维效果,在VR里观感不佳,之后在网上找 ...
- 自定义控件android特效,Android自定义控件eBook实现翻书效果实例详解
本文实例讲述了Android自定义控件eBook实现翻书效果的方法.分享给大家供大家参考,具体如下: 效果图: Book.java文件: package com.book; import androi ...
- settimeout怎么用_怎么实现一个3d翻书效果
本篇主要讨论以下两种翻书动画的实现: 第一种是整页翻转的效果: 这种整页翻转的效果主要是做rotateY的动画,并结合一些CSS的3d属性实现. 第二种折线翻转的效果,如下图所示: 主要是通过计算页面 ...
- 3d饼图 vue_怎么实现一个3d翻书效果
本篇主要讨论以下两种翻书动画的实现: 第一种是整页翻转的效果: 这种整页翻转的效果主要是做rotateY的动画,并结合一些CSS的3d属性实现. 第二种折线翻转的效果,如下图所示: 主要是通过计算页面 ...
- Starling实现的硬皮翻书效果
原文:Starling实现的硬皮翻书效果 作者:郭少瑞 ---------------------------------------– 更新(2012-12-31): 在今年的最后一天,这个效果终于 ...
- 如何用css实现左右翻页效果图,如何利用CSS3实现3D翻书效果
这篇文章主要介绍了CSS3实现3D翻书效果,基于CSS3新属性Animation及transform实现类似翻书效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 先上效果图:(样式有点丑,可以忽 ...
- Android利用贝塞尔曲线实现翻书效果(适配AndroidX)
实现背景 不知道你有没有遇到同样的问题,要实现翻书效果,如果你是使用github上的demo或者好多博客上写的方式,你会发现,当api从28开始,会抛出Invalid Region.Op.REPLAC ...
- ajax实现翻书效果,jquery实现的翻书效果
插件描述:利用jquery插件实现的类似图书翻书效果功能 Booklet是一个基于jQuery库的实现网页上翻书动画效果的插件,在jBooklet页面上可以写任何支持html的内容,而软件设置相当简单 ...
- html局部翻页效果,基于Turn.js 实现翻书效果实例解析
最近项目经理我个项目练练手,其项目需求是要实现翻书效果,看到这个需求后,我真是懵了,这咋整,我可是java出身的啊,这个问题真是难住我了,后来有同事的指导,之前他曾经做过PC版的翻书效果,当时使用的是 ...
最新文章
- 先验概率,后验概率,条件概率,贝叶斯
- 还在用Synchronized?Atomic你了解不?
- CTFshow 信息收集 web13
- C++ Primer 5th笔记(chap 15 OOP)抽象基类
- C语言:构建一个二级链表并完成增删改查
- 通过OData创建C4C Lead时,遇到Account missing的错误消息
- 修改Linux系统日期与时间date clock
- php cbd架构,CBD模式
- linux java url 异常_Java连接虚拟机(Linux)中的Oracle数据库,连接异常~新手求解!
- 缓存中间件技术选型Memcached、MongoDB、Redis
- 腾讯云人脸支付常见问题和解答,以及腾讯云人脸支付相关介绍
- [无线]无线传输距离预估计算
- EOF in header-net core
- JVM之运行时栈帧的结构(基于《深入理解Java虚拟机》之第八章虚拟机字节码执行引擎)(上)
- 计算机各类会议及投稿文章总结(快速入门)
- PDF Expert for mac(最好用的pdf编辑工具)
- computer science 经典书籍及书评
- 关于java中的反射
- 轻松解决网络广播风暴
- 一个意外错误使您无法复制该文件。
热门文章
- 在线预览文档 Office Online
- linux关闭proftpd服务,Linux ProFTPd安装与卸载详细介绍
- win10如何离线安装.NET Framework3.5
- CAD命令行不见了怎么重新恢复?
- 使用Go语言完成文件夹的MD5计算
- ubuntu 双屏显示的设置
- 惠州市城市职业学院计算机考点,2020广东乡镇惠州考区笔试考点地理位置及考场安排表...
- [Swift]语言介绍
- UE5建筑可视化室内场景模型 Evermotion – Archinteriors for UE vol. 8
- ps里面怎么插入流程图_Photoshop制作网站流程图详细过程