此次用能量罩继续Shader结果的练习。 分析能量罩的结构:
能量罩球体边沿高光能量罩自己实在应当是个半通明光球,但为了可以展现内部的脚色大概物体,正对摄像机的部分要变全通明让内部被清楚的看到,间接用RIM边沿光衬着便可以。由因而通明的,所以要两面都衬着,将视向量和法线的点积成果取绝对值来保证后背的正确衬着。 Tags{ "RenderType"="Transparent" "Queue" = "Transparent" "IgnoreProjector" = "True"}Blend One One ZWrite Off Cull Off fixed4 frag(...) : SV_Target { ... half rim = pow(1 - abs(dot(normalDir,viewDir)) , _RimNum); ... } 和物体订交的边沿高光在游戏中看到的能量罩可以发现,在和空中、物体订交的部分也是会高亮显现的,也算是能量罩的边沿。所以需要正确获得订交的信息,可以经过当前片元能量罩的深度和场景中的深度做对照,假如两个深度是相称,那末就说明能量罩和物体是订交的。 主相机的深度图可以获得场景中的深度信息。可是能量罩由因而通明衬着,没有影子的部分,所以也就没有ShadowCaster的Pass,也就不会出现在主相机的深度图中。可是经过Clip空间获得到能量罩当前片元的深度值,利用ComputeScreenPos函数可以将Clip空间的坐标转换为屏幕坐标,函数内对xy份量做了转换处置,zw份量间接利用了原值。Clip空间的z份量是从-Near到Far的,而深度图中的LinearEyeDepth后的范围是Near到Far,所以经过COMPUTE_EYEDEPTH函数将深度转化到Near到Far。 Unity ComputeScreenPos函数源码 那末我已经经过相机深度图获得到了场景深度信息,Clip空间z份量获得到了能量球的深度信息,接着经过比力计较获得订交的信息。 float diff = pow(1-saturate((sceneZ - partZ)), _EdgePow);像RIM一样,经过_EdgePow来控制定交高亮的范围。 能量罩一个一个Cube订交 能量罩的纹理间接给一个纹理贴图便可以展现出想要的纹理结果,假如加上一个时候偏移便可以做出动画的结果。 fixed4 frag(...) : SV_Target{ fixed4 col = fixed4(0,0,0,0); ... fixed main = tex2D(_MainTex, i.uv + _Time.y * 0.02).r; fixed4 mainColor = _TintColor * pow(1 - main, 3); ... col = lerp(col, _TintColor, diff); col = lerp(col, mainColor, rim); } 我的主纹理是一张噪波图,所以只取了一个通道并做了处置。 根基的结果都完成了,可是看着有点昏暗,能量罩显得有点能量不敷,所以做个简单的处置。 col = lerp(col, mainColor, rim) * 4;这样看起来就好多了,可是还是感受少了点什么,作为一个带能量的发光球体有点Bloom的结果会更好一点。 能量罩的展开能量罩开启实在就是一个定向消融结果,还是利用了我之前的消融结果文章里的方式。 然后便可以从各个偏历来实现能量罩的开启和封闭: 下一步会尝试加上能量罩被击中后的能量波纹结果,做完以后再做文章的更新。 参考: |