shader学习之路——折射

斯涅尔定律来计算反射角  介质1*sinA1 = 介质2*sinA2

Shader "Custom/RefractionShader" {
	Properties {
		_Color ("Color", Color) = (1,1,1,1)
		_RefractColor("Refract Color",Color) = (1,1,1,1)
		_RefractAmount("Refract Amount",Range(0.1,1)) = 0.5
		_RefractRatio("Refraction Ratio",Range(0.1,1)) = 0.5
		_Cubemap("Refraction Cubemap",cube) = "_Skybox"{}
	}

	SubShader {
		Pass{
			Tags { "RenderType"="Opaque" }
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#include "Lighting.cginc"
			#include "AutoLight.cginc"
			#include "UnityCG.cginc"

			fixed4 _Color;
			fixed4 _RefractColor;
			float _RefractAmount;
			float _RefractRatio;
			samplerCUBE _Cubemap;

			struct a2v{
				float4 vertex:POSITION;
				float3 normal:NORMAL;			
			};			

			struct v2f{
				float4 pos:SV_POSITION;
				float3 worldNormal:TEXCOORD0;
				float3 worldPos:TEXCOORD1;
				float3 worldViewDir:TEXCOORD2;
				float3 worldRefr:TEXCOORD3;
			};

			v2f vert(a2v v){
				v2f o;
				o.pos = UnityObjectToClipPos(v.vertex);
				o.worldNormal = UnityObjectToWorldNormal(v.normal);
				o.worldPos = mul(unity_ObjectToWorld,v.vertex).xyz;
				o.worldViewDir = UnityWorldSpaceViewDir(o.worldPos);
				//refract计算折射方向   第一个参数为入射光线方向  第二个参数是表面发现 
				//第三个参数是入射光线所在介质的折射率和折射光线所在介质的折射率之间的比值
				o.worldRefr = refract(-normalize(o.worldViewDir),normalize(o.worldNormal),_RefractRatio);
				TRANSFER_SHADOW(o);
				return o;
			}

			fixed4 frag(v2f i):SV_Target
			{
				fixed3 worldNormal = normalize(i.worldNormal);
				fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
				fixed3 worldViewDir = normalize(i.worldViewDir);
				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
				fixed3 diffuse = _LightColor0.rgb * _Color.rgb * max(0,dot(worldNormal,worldLightDir));
				fixed3 refraction = texCUBE(_Cubemap,i.worldRefr).rgb * _RefractColor.rgb;//texCUBE采样只需要提供
				UNITY_LIGHT_ATTENUATION(atten,i,i.worldPos);
				fixed3 color = ambient + lerp(diffuse , refraction ,_RefractAmount) * atten; //lerp插值函数
				return fixed4(color,1.0);
			}
			ENDCG
		}
	}
	FallBack "Diffuse"
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Shader(着色器)是用于在图形渲染过程中处理和操作像素数据的一种程序。学习Shader需要一定的编程基础,特别是对C++、OpenGL或DirectX等图形编程框架的熟悉。以下是一个关于学习Shader的计划: 1. 学习基本概念: - 了解计算机图形学的基本概念,如顶点、纹理、光照等。 - 学习Shader的基本组成部分,包括顶点着色器(Vertex Shader)、片段着色器(Fragment Shader)和几何着色器(Geometry Shader)。 2. 选择合适的编程语言和图形编程框架: - 根据个人喜好和项目需求,选择C++、C#或HLSL(High Level Shading Language)作为编写Shader的编程语言。 - 学习所选编程语言的基本语法和图形编程框架的使用方法。 3. 学习Shader语言: - 熟悉所选编程语言的Shader库,了解常用的Shader函数和结构。 - 学习编写基本的顶点着色器和片段着色器,掌握如何描述图形渲染的过程。 4. 学习高级Shader技术: - 学习纹理贴图、光照模型、阴影技术等高级Shader技术。 - 掌握如何使用多个着色器(如几何着色器和光栅化着色器)组合在一起实现复杂的渲染效果。 5. 实践项目: - 参与开源项目或自己创建项目,将所学的Shader知识应用到实际项目中。 - 通过不断地实践和优化,提高自己的Shader编程能力。 6. 深入学习: - 阅读相关书籍和教程,了解更多关于Shader的高级技术和实现方法。 - 参加线上或线下的技术社区,与其他开发者交流学习经验,共同进步。 总之,学习Shader需要时间和耐心,通过不断地学习和实践,你将能够掌握这一技能并在图形渲染领域取得突破。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值