unity shader立方体纹理中的反射以及折射效果的实现
反射:
如果不考虑反射效果的话,在场景中的问题的镜面表面的效果应该是用表面的法线对立方体纹理进行采样得到该点的颜色。
所以我们进行反射的计算的时候,只需要求得反射方向,再用反射的方向对立方体纹理进行采样即可。
效果:
代码:
Shader "Custom/Chapter10-Reflaction"
{Properties{_Color("Color Tint",Color)=(1,1,1,1)//反射颜色_RefractColor("Reflection Color",Color)=(1,1,1,1)//反射程度_RefractAmount("Reflect Amount",Range(0,1))=1//介质的比例_RefractRatio("Refraction Ratio",Range(0.1,1))=0.5//立方体纹理_Cubemap("Reflection Cubemap",Cube)="_Skybox"{}}SubShader{Tags { "RenderType"="Opaque" "Queue"="Geometry"}Pass{Tags{"LightMode"="ForwardBase"}CGPROGRAM#pragma multi_compile_fwdbase#pragma vertex vert#pragma fragment frag#include "Lighting.cginc"#include "AutoLight.cginc"fixed4 _Color;fixed4 _RefractColor;float _RefractAmount;fixed _RefractRatio;samplerCUBE _Cubemap;struct a2v{float4 vertex:POSITION;float3 normal:NORMAL;};struct v2f{float4 pos:SV_POSITION;float3 worldPos:TEXCOORD0;fixed3 worldNormal:TEXCOORD1;fixed3 worldViewDir:TEXCOORD2;//反射光线方向fixed3 worldRefr:TEXCOORD3;SHADOW_COORDS(4)};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);//反射方向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;UNITY_LIGHT_ATTENUATION(atten,i,i.worldPos);fixed3 color=ambient +lerp(diffuse,Refraction,_RefractAmount)*atten;return fixed4(color,1.0);}ENDCG}}FallBack "Reflective/VertexLit"
}
折射
同理,求得折射的方向,对立方体纹理进行采样。
实现效果:
代码:
Shader "Custom/Chapter10-Reflaction"
{Properties{_Color("Color Tint",Color)=(1,1,1,1)//折射颜色_RefractColor("Reflection Color",Color)=(1,1,1,1)//折射程度_RefractAmount("Reflect Amount",Range(0,1))=1//介质的比例_RefractRatio("Refraction Ratio",Range(0.1,1))=0.5//立方体纹理_Cubemap("Reflection Cubemap",Cube)="_Skybox"{}}SubShader{Tags { "RenderType"="Opaque" "Queue"="Geometry"}Pass{Tags{"LightMode"="ForwardBase"}CGPROGRAM#pragma multi_compile_fwdbase#pragma vertex vert#pragma fragment frag#include "Lighting.cginc"#include "AutoLight.cginc"fixed4 _Color;fixed4 _RefractColor;float _RefractAmount;fixed _RefractRatio;samplerCUBE _Cubemap;struct a2v{float4 vertex:POSITION;float3 normal:NORMAL;};struct v2f{float4 pos:SV_POSITION;float3 worldPos:TEXCOORD0;fixed3 worldNormal:TEXCOORD1;fixed3 worldViewDir:TEXCOORD2;//折射光线方向fixed3 worldRefr:TEXCOORD3;SHADOW_COORDS(4)};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);//折射方向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;UNITY_LIGHT_ATTENUATION(atten,i,i.worldPos);fixed3 color=ambient +lerp(diffuse,Refraction,_RefractAmount)*atten;return fixed4(color,1.0);}ENDCG}}FallBack "Reflective/VertexLit"
}
菲涅尔反射
通过菲涅尔反射来根据视角方向控制反射程度。比如说在现实生活中,我们在近处看湖边的水面,可以看到水下的石头鱼儿等等,但是当我们走远处再去看湖边的水面的时候我们却只能看到水面,而看不到水下的情景,这就是菲涅尔效果。
菲涅尔近似等式:
Schlick菲涅尔近似等式: f是反射系数,控制菲涅尔反射的强度
Empricial菲涅尔近似等式:
效果:
代码:
Shader "Custom/Chapter10-Fresnel"
{Properties{_Color("Color Tint",Color)=(1,1,1,1)//F0_FresnelScale("Fresnel Scale",Range(0,1))=0.5//立方体纹理_Cubemap("Reflection Cubemap",Cube)="_Skybox"{}}SubShader{Tags { "RenderType"="Opaque" "Queue"="Geometry"}Pass{Tags{"LightMode"="ForwardBase"}CGPROGRAM#pragma multi_compile_fwdbase#pragma vertex vert#pragma fragment frag#include "Lighting.cginc"#include "AutoLight.cginc"fixed4 _Color;float _FresnelScale;samplerCUBE _Cubemap;struct a2v{float4 vertex:POSITION;float3 normal:NORMAL;};struct v2f{float4 pos:SV_POSITION;float3 worldPos:TEXCOORD0;fixed3 worldNormal:TEXCOORD1;fixed3 worldViewDir:TEXCOORD2;//反射光线方向fixed3 worldRefl:TEXCOORD3;SHADOW_COORDS(4)};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);//反射方向o.worldRefl = reflect(-o.worldViewDir,o.worldNormal);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 Reflection =texCUBE(_Cubemap,i.worldRefl).rgb;fixed fresnel =_FresnelScale+(1-_FresnelScale)*pow(1-dot(worldViewDir,worldNormal),5);UNITY_LIGHT_ATTENUATION(atten,i,i.worldPos);//用菲涅尔近似差值反射颜色和漫反射颜色fixed3 color =ambient +lerp(diffuse,Reflection,saturate(fresnel))*atten;return fixed4(color,1.0);}ENDCG}}FallBack "Reflective/VertexLit"
}
unity shader立方体纹理中的反射以及折射效果的实现相关推荐
- 【Unity Shader学习笔记】实现反射与折射模拟水面、使用grabPass与环境贴图
文章目录 写在前面 一个水波效果 大致组成部分与对应的实现方案 交界线与深度贴图 折射效果与GrabPass 使用Cubemap与法线信息来模拟反射 在正确的地点创建对应的cubemap 通过贴图获取 ...
- 如何在Unity实现从纹理中生成法线贴图?
本文主要讲解从纹理中生成法线贴图的基本方法,并在 Unity 中进行实现和测试. 预备知识 法线贴图和基本的图形学知识,基本的向量和极限的知识. 高度图或灰度图 一张二维纹理有两个维度 u 和 v,但 ...
- unity shader实现纹理贴图
unity实现纹理贴图很简单,首先在appdata结构体里声明uv语义TEXCOORD0,就可以获得当前顶点的uv坐标,对外部导入的模型来说.这个uv坐标是在3d模型软件例如maya中制作模型的人预先 ...
- 【unity shader 入门精要 读书笔记】折射
当光线从一种介质[例如空气]斜射入另外一种介质[例如玻璃]时,传播方向一般会发生改变. 当给定入射角时,可以使用 斯涅耳定律[Snell's Law]来计算反射角. 当光从介质 1 沿着和表面法线夹角 ...
- Unity Shader - GrabPass 实现武器热扭曲拖尾效果
文章目录 先来看看效果 实现思路 Unity带的TrailRender组件 编写脚本实现 CSharp Shader 参数 注意性能 还可以优化 总结 Project 以前龙之谷喜欢选战士,帅气. 战 ...
- 【Unity Shader】纹理实践4.0:简单尝试渐变纹理和遮罩纹理
写在前面 由于我还是处于刚刚入门(其实还是小菜鸡...)的阶段,关于渐变纹理目前主要是学习一下如何通过渐变纹理控制漫反射光照. 这种用渐变纹理控制颜色效果的想法,是Valve公司(提出半兰伯特光照技术 ...
- Unity Shader学习记录(6) —— 高光反射光照模型和内置计算函数
1 高光反射光照模型计算公式 从公式可以看出,要计算高光反射需要知道 4 个参数:入射光线的颜色和强度c,材质的光反射系数 m,视角方向v以及反射方向r.其中,反射方向r可以由表面法线n和光源i计算得 ...
- UnityShader_天空盒子中的反射、折射、聂菲尔效应
反射 反射的原理在之前的文章中已有,在此不再赘述,这里主要讲一下天空盒子纹理的采集 主要看代码中有注释的部分,其中在 texCUBE 中没有对i.worldRefl进行归一化,是因为仅仅是传递方向变量 ...
- Unity Shader - 实现简单水体 - 浅水到深水颜色控制
文章目录 制作步骤 准备好水体网格 扰动水体网格 添加水体网格色调,纹理 放置海上放哨点(一些随便放的立方体) 添加水的深浅透视效果 添加水光效 重构水顶点法线 正交的相机的深度需要注意 改进 Pro ...
最新文章
- MM夏天化妆不掉妆的技巧
- 前端学习(592):使用snippets辅助debugging
- 安卓自定义View进阶-分类与流程
- css grid布局增加边框,CSS Grid中每行之后的边框
- 产品经理必懂技术术语(后台类)
- 第十一届蓝桥杯省赛C++组试题 第6题
- 5G(1)---5G 协议标准下载
- SpringBoot : Spring容器生命周期管理:SmartLifecycle
- Linux 系统服务漏洞PwnKit 已存在12年,可获得所有主流发布版本的root 权限
- servlet配置log4J
- c++下字符串分割函数split实现
- Multi-Scale Boosted Dehazing Network with Dense Feature Fusion笔记和代码
- 北理工珠海学院计算机分数线,北京理工大学珠海学院
- Intellij IDEA 2019 最新优化配置
- 建设一个网站需要多少钱?
- 苹果手机充电口接触不良怎么办_苹果连充电口都要干掉?
- perf常用命令(perf top perf record perf stat)
- LeetCode-----第139题-----单词拆分
- 西电计算机考研历年分数线,西安电子科技大学研究生,西电历年考研分数线?...
- 简洁好用的jquery 焦点图插件:Basic jQuery Slider
热门文章
- 使用K-means算法进行聚类分析
- Java项目(毕设课设) 之 [含文档+PPT+任务书+中期检查表+源码等]基于S2SH的医院在线挂号系统
- 写一份自动售票机各模块的测试用例
- 电路设计——秒表初步
- Hashmap解决hash冲突为什么使用红黑树
- Image-based 3D Object Reconstruction: State-of-the-Art and Trends in the Deep Learning Era
- 2022广西最新建筑八大员(材料员)模拟考试试题及答案
- 神武4服务器维护中,《神武4》上周更新内容分析与解读
- 文字与图片渐变效果(图层CALayer与属性蒙版mask )
- android游戏1024代码,castlegame 可简单快速开发android游戏。我总结的教程