首页 > 编程知识 正文

Unity 镜面反射,镜面反射模拟软件

时间:2023-05-06 00:30:25 阅读:224313 作者:4035

一、公式
specuColor = Kd*_LightColor0*pow(max(R·V 0), _jwdyg);
Kd–环境光颜色、顶点颜色、点光源的距离衰减
_LightColor0–光源颜色
R·V–反射光向量 · 观察向量

二、逐顶点着色(古罗着色)

Shader "Custom/MySpecular_Vertex"{ Properties { _MainTex ("Texture", 2D) = "white" {} _Bright("Bright",Float) = 2 _jwdyg("jwdyg",Float) = 10 } SubShader { Tags { "RenderType" = "Opaque" } LOD 100 Pass { Tags{ "LightMode" = "ForwardBase" } CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #include "Lighting.cginc" uniform float _jwdyg; uniform float _Bright; uniform sampler2D _MainTex; struct appdata { float4 vertex:POSITION; float2 texcoord:TEXCOORD0; half3 normal:NORMAL; }; struct v2f { float4 pos:SV_POSITION; float2 uv:TEXCOORD0; fixed4 difColor : COLOR0; fixed4 specuColor : COLOR1; }; v2f vert(in appdata v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.uv = v.texcoord; float3 vertexWorldPos = mul(unity_ObjectToWorld, v.vertex); float3 N = normalize(mul((float3x3)unity_ObjectToWorld, v.normal));//法线 float3 L;//入射光方向 float atten;//点光源的距离衰减系数 if (_WorldSpaceLightPos0.w == 0)//_WorldSpaceLightPos0:平行光: (world space direction, 0); { L = normalize(_WorldSpaceLightPos0); atten = 1; } else //_WorldSpaceLightPos0: 其他光: (world space position, 1). { float3 light2Vertex = _WorldSpaceLightPos0 - vertexWorldPos; L = normalize(light2Vertex); float Length = length(light2Vertex); atten = 1 / Length; } float Kd = atten*_Bright/**UNITY_LIGHTMODEL_AMBIENT*/; //计算入射光和法线的夹角的余弦值,并剔除小于零的值(小于0的值相当于从物体的背面向物体表面照射,没有物理意义) float cos = max(dot(N, L), 0); fixed4 difColor = Kd*_LightColor0 *cos;//漫反射光的颜色 //镜面反射 float3 R = reflect(-L, N); float3 V= normalize(_WorldSpaceCameraPos - vertexWorldPos); fixed4 specuColor = Kd* _LightColor0*pow(max(dot(R, V), 0), _jwdyg); o.difColor = difColor; o.specuColor = specuColor; return o; } fixed4 frag(in v2f i) :SV_Target { fixed4 col; //纹理采样 col = tex2D(_MainTex, i.uv); col *= i.difColor; col += i.specuColor; return col; } ENDCG } }}

三、逐像素着色(冯式着色)

Shader "Custom/MySpecular_Fragment"{ Properties { _MainTex("Texture", 2D) = "white" {} _Bright("Bright",Float) = 2 _jwdyg("jwdyg",Float) = 10 } SubShader { Tags{ "RenderType" = "Opaque" } LOD 100 Pass { Tags{ "LightMode" = "ForwardBase" } CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #include "Lighting.cginc" uniform float _jwdyg; uniform float _Bright; uniform sampler2D _MainTex; struct appdata { float4 vertex:POSITION; float2 texcoord:TEXCOORD0; float3 normal:NORMAL; }; struct v2f { float4 pos:SV_POSITION; float2 uv:TEXCOORD0; float3 normalDir:TEXCOORD1; float3 worldPos:TEXCOORD2; }; v2f vert(in appdata v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.uv = v.texcoord; o.normalDir = normalize(mul((float3x3)unity_ObjectToWorld, v.normal)); o.worldPos = mul((float3x3)unity_ObjectToWorld, v.vertex); return o; } fixed4 frag(in v2f i) :SV_Target { fixed4 col; col = tex2D(_MainTex, i.uv); float3 N = normalize(i.normalDir); float3 L; float atten; if (_WorldSpaceLightPos0.w == 0) { L = normalize(_WorldSpaceLightPos0); atten = 1; } else { float3 light2Vertex = _WorldSpaceLightPos0 - i.worldPos; L = normalize(light2Vertex); float Length = length(light2Vertex); atten = 1 / Length; } float Kd = atten*_Bright; float4 difColor = Kd*_LightColor0*max(0, dot(N, L)); float3 R = reflect(-L, N); float3 V = normalize(_WorldSpaceCameraPos - i.worldPos); float4 specuColor = Kd*_LightColor0*pow(max(dot(R,V), 0), _jwdyg); col *= difColor; col += specuColor; return col; } ENDCG } } }

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。