900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > Unity Shader 实现简单的宝石渲染

Unity Shader 实现简单的宝石渲染

时间:2022-04-10 14:56:53

相关推荐

Unity Shader 实现简单的宝石渲染

入职实习的第一周过去了,感觉还是相当不错的,找到工作了也就不用再顶着高压去学习了,快乐。

闲话少说,先上效果图啦。

效果还是很棒的,但这不是我写的,哈哈,这个代码可以完全说就是抄Unity的案例。Assset Store搜Gem Shader就可以找到了。

我主要还是分析它的原理,虽然原理我也是不太懂,但是渲染出的效果可以说很不错了。

原理上基本都是参考这一篇演示的(Phat Lewt: Drawing a Diamond),来头貌似还是挺大,国内不知道找没找得到这篇演示,我上传到百度云了Phat Lewt: Drawing a Diamond觉得有需要的可以看一下。

我就基于Phat Lewt: Drawing a Diamond的谷歌翻译说下原理吧。

1.渲染背面的折射颜色到颜色缓冲。

2.将背面的折射颜色与正面进行混合.(正面的有折射和反射以及高光)

3.绘制耀斑。

大功告成!是不是很简单…个屁…还有各种射来射去的光线是用一个立方体贴图来模拟的,Gem Shader里就有这个立方体贴图。

以下是代码,虽然Unity的案例和演示有些出入但我感觉总体相差不大,还有一点就是Unity用菲涅尔效应实现了类似于高光的效果。

Shader "MyShader/Diamond"{Properties{_Color("Color",Color)=(1,1,1,1)_ReflectionStrength("Reflection Strength",Range(0.0,2.0))=1.0_EnvironmentLight ("Environment Light", Range(0.0,2.0)) = 1.0_Emission ("Emission", Range(0.0,2.0)) = 0.0[NoScaleOffset] _RefractTex ("Refraction Texture", Cube) = "" {}}SubShader{Tags {"Queue" = "Transparent" }LOD 100Pass{Cull FrontZWrite Off CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct v2f{float4 pos:SV_POSITION ;float3 uv:TEXCOORD0 ; };fixed4 _Color;samplerCUBE _RefractTex;half _EnvironmentLight;half _Emission;v2f vert ( appdata_base v){v2f o;o.pos = UnityObjectToClipPos(v.vertex);float3 viewDir=normalize(ObjSpaceViewDir(v.vertex));o.uv = -reflect(viewDir,v.normal);o.uv=mul(unity_ObjectToWorld,float4(o.uv,0));return o;}fixed4 frag (v2f i) : SV_Target{half3 refraction=texCUBE(_RefractTex,i.uv).rgb*_Color.rgb;half4 reflection=UNITY_SAMPLE_TEXCUBE(unity_SpecCube0,i.uv);reflection.rgb=DecodeHDR(reflection,unity_SpecCube0_HDR);half3 multiplier=reflection.rgb*_EnvironmentLight+_Emission;return half4(refraction.rgb*multiplier.rgb,1.0f);}ENDCG}Pass{ZWrite OnBlend One OneCGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct v2f{float4 pos:SV_POSITION ;float3 uv:TEXCOORD0 ; half fresnel:TEXCOORD1 ;};fixed4 _Color;samplerCUBE _RefractTex;half _ReflectionStrength;half _EnvironmentLight;half _Emission;v2f vert ( appdata_base v){v2f o;o.pos = UnityObjectToClipPos(v.vertex);float3 viewDir=normalize(ObjSpaceViewDir(v.vertex));o.uv = -reflect(viewDir,v.normal);o.uv=mul(unity_ObjectToWorld,float4(o.uv,0));o.fresnel=1-saturate(dot(v.normal,viewDir));return o;}fixed4 frag (v2f i) : SV_Target{/* unity_SpecCube0保存了环境的立体贴图(天空盒和反射探针形成的立体贴图)UNITY_SAMPLE_TEXCUBE 用于采样立体贴图DecodeHDR将高动态贴图转为正常RGB,如果导入的不是HDR贴图,就没有变化*/half3 refraction=texCUBE(_RefractTex,i.uv).rgb*_Color.rgb;half4 reflection=UNITY_SAMPLE_TEXCUBE(unity_SpecCube0,i.uv);reflection.rgb=DecodeHDR(reflection,unity_SpecCube0_HDR);half3 reflection2=reflection*_ReflectionStrength*i.fresnel;half3 multiplier=reflection.rgb*_EnvironmentLight+_Emission;return half4(reflection2+refraction.rgb*multiplier.rgb,1.0f);}ENDCG }UsePass "VertexLit/SHADOWCASTER"}}

耀斑效果是用屏幕后处理实现的,参考的是Unity3D-实现屏幕特效十字耀斑不得不说这个效果真的是杠杠的,以后我可能回单独写一篇耀斑的效果实现过程以及我自己的理解。以下是加上耀斑的效果图(左边的最明显,而且好像有点错位,尴尬):

好了,本篇博客到此结束,感谢你的阅读,如有错误欢迎指正。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。