菜鸡shader:L5 fresnel、matcap和cubemap

news2024/9/24 15:28:56

文章目录

  • Fresnel
    • shader forge实现
    • UE4蓝图实现
  • Matcap
    • shader forge实现
    • UE4蓝图实现
  • CubeMap
    • SD和PS制作所需的贴图
    • shader forge实现
    • unity代码实现
    • UE4蓝图实现(未实现)

Fresnel

在这里插入图片描述

在这里插入图片描述

shader forge实现

在这里插入图片描述

  • 个人理解是,使用观察方向和法向方向点乘,那就相当于我们的视线看到哪里,哪里就是亮的,相当于头顶探照灯了。
  • 但是菲尼尔效果则是观察方向和法线方向离得越近,折射或者反射效果越弱;而如果观察方向和法线方向越接近90°时,反射的效果就越强。所以我们采用onemiuns(用1减去观察方向和法线方向的点乘),就能取得我们想要的效果。
  • 最后再使用power函数来增强这个菲涅尔的强度。

UE4蓝图实现

然后是ue4中的fresnel效果的实现,跟shader forge的节点差不多:
在这里插入图片描述

  • ue4中对应于shader forge中使用的法线方向的节点是PixelNormalWS,而不是VertexNormalWS这点需要注意。
  • 和unity中不同的时我们的观察方向需要通过摄像机方向取反来得到,因为shader forge的观察方向是从着色点为起点发射到相机的位置。这与ue4中的相机方向刚好相反。

Matcap

具体请参考毛星云大佬的blog
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

不像一般的Shader,需要提供光照,需要在Shader代码中进行漫长的演算,基于MatCap思想的Shader相当于MatCap贴图就把光照结果应该是怎样的标准答案告知Shader,我们只用在试卷下写出答案,进行一些加工即可。

需要注意,MatCap Shader有一定的局限性。因为从某种意义上来说,基于MatCap的Shader,就是某种固定光照条件下,从某个特定方向,特定角度的光照表现结果。

正是因为是选择的固定的MatCap贴图,得到相对固定的整体光照表现,若单单仅使用MatCap,就仅适用于摄像机不调整角度的情形,并不适合摄像机会频繁旋转,调节角度的情形。但我们可以在某些Shader中,用MatCap配合与光照交互的其他属性,如将MatCap结合一个作为光照反射的颜色指导的Reflection
Cube Map,就有了与光照之间的交互表现。这样,就可以适当弥补MatCap太过单一整体光照表现的短板。

shader forge实现

在这里插入图片描述
unity中的效果:
在这里插入图片描述

UE4蓝图实现

在这里插入图片描述

ue4中的效果:
在这里插入图片描述

  • ue和unity的亮度不一样啊…只能手动调参了,这里学习为主,暂时就不折腾这个了。

CubeMap

这个东西其实很多地方都讲过,如果感兴趣可以看看:

  • games202的Precomputed Radiance Transfer的课
  • 或者直接参考LearnOpenGl中IBL章节
  • 庄老师PPT主要是讲了以反射形式为主的环境映射:
    在这里插入图片描述
  • 也就是我们要求的是那根绿线R。

在这里插入图片描述
在这里插入图片描述

SD和PS制作所需的贴图

下面说一下怎么用ps处理cubemap需要的贴图:
首先找到一张全景图,类似于这样的:
在这里插入图片描述
在这里插入图片描述

  • 具体可以上subtance designer里面找3D View里的全景图,打开其中一个的文件夹,然后直接拖到ps里面:
    在这里插入图片描述
  • 拖进ps里后选择作为alpha通道:
    在这里插入图片描述
  • 选择:
    在这里插入图片描述
  • 调整图像大小:
    在这里插入图片描述
  • 然后设置图像模式,默认参数确认就行,这一步是为了将图片的亮度高于1和暗度低于0的部分限制在0到1范围内:
    在这里插入图片描述
    然后导出为tga格式:
    在这里插入图片描述
    在这里插入图片描述
  • 导入到unity中,红色的需要调整,绿色的自己选择调不调整:
    在这里插入图片描述
  • 调整完应用之后就是下面这个样子,一个材质球:
    在这里插入图片描述

shader forge实现

  • 然后放下课程上的实现:
    在这里插入图片描述

  • unity中自己的实现:
    在这里插入图片描述

  • 因为我们要得到的是视线看过去与法线形成的反射方向,所以需要获取到观察方向的反方向。

  • 感兴趣的可以去了解下reflect函数的实现。

  • 和课程上的实现图相比多了AO,也就是环境光遮蔽贴图的部分。

unity的效果图:
在这里插入图片描述

unity代码实现

Shader "shader forge/L9_CubeMap2"
{
    Properties
    {
        _normalmap ("normal map", 2D) = "bump" {}
        _cubeMap ("cubeMap", Cube) = "_Skybox" {}
        _AOTex ("AO Texture",2D) = "White" {}
        _n1 ("n1", Float ) = -1
        _MipMap_Level ("MipMap_Level", Range(0, 7)) = 0
        _fresnel_exp ("fresnel_exp", Range(0, 10)) = 1
        _EnvSpecInt ("EnvSpecInt", Range(0, 5)) = 1
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv0 : TEXCOORD0;
                float4 tangent : TANGENT;
                float3 normal : NORMAL;
            };

            struct v2f
            {
                float2 uv0 : TEXCOORD0;                
                float4 pos : SV_POSITION;
                float4 posWorld : TEXCOORD1;
                float3 nDirWS : TEXCOORD2;
                float3 tDirWS : TEXCOORD3;
                float3 biDirWS : TEXCOORD4;               
            };

            uniform sampler2D _normalmap;
            uniform samplerCUBE _cubeMap;
            uniform sampler2D _AOTex;
            uniform float _n1;
            uniform float _MipMap_Level;
            uniform float _fresnel_exp;
            uniform float _EnvSpecInt;

            v2f vert (appdata v)
            {
                v2f o;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.uv0 = v.uv0;
                o.nDirWS = UnityObjectToWorldNormal(v.normal);
                o.tDirWS = normalize(mul(unity_ObjectToWorld, float4(v.tangent.xyz,0.0)).xyz);
                o.biDirWS = normalize(cross(o.nDirWS,o.tDirWS) * v.tangent.w);
                o.posWorld = mul(unity_ObjectToWorld, v.vertex);                
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                //贴图采样
                float3 nDirTS = UnpackNormal(tex2D(_normalmap,i.uv0)).rgb;
                float AO_R = tex2D(_AOTex,i.uv0);

                //向量准备
                float3x3 TBN_Matrix = float3x3(i.tDirWS,i.biDirWS,i.nDirWS);
                float3 nDirWS_FT = normalize(mul(nDirTS,TBN_Matrix));
                float3 nDirVS_FT = normalize(mul(UNITY_MATRIX_V,float4(nDirWS_FT,0.0)).xyz);
                float3 vDirWS = normalize(_WorldSpaceCameraPos.xyz - i.posWorld.xyz);
                float3 vrDirWS = normalize(reflect(-vDirWS,nDirWS_FT));

                //中间量准备
                fresnel
                float NoV = max(0.0,dot(nDirWS_FT,vDirWS));
                float OneMinusNoV = 1 - NoV;
                float fresnel = pow(OneMinusNoV,_fresnel_exp);

                cubemap
                float3 cubemap_uv = vrDirWS;
                float3 cubemap_color = texCUBElod(_cubeMap,float4(cubemap_uv,_MipMap_Level));

                //光照模型
                float3 finalColor = cubemap_color * fresnel;
                float3 EnvSpecLighting = finalColor * _EnvSpecInt * AO_R;

                //后处理

                //最后返回值
                return float4(EnvSpecLighting,1.0);
            }
            ENDCG
        }
    }
}

UE4蓝图实现(未实现)

额,虽然还想在ue4中实现一编,但是ue4的cubemap好像是直接用来制作天空盒的,跟本节课只是单纯作为贴图参与材质的编辑不一样,当然也有可能是我自己原因没有搜到相关教程,如果有大佬知道也可以在评论区告诉我一声。

如果对制作ue4的cubemap有兴趣的话也可移步至:

  • Unreal Engine UE4虚幻引擎,生成Cubemap(HDR高动态范围贴图)
  • UE4笔记:引擎内部制作cubemap步骤
  • UE4_SkyLight立方体贴图的创建与应用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/696698.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

adb-命令大全

目录 一、ADB简介 二、为什么要用ADB 三、ADB架构和原理 四、ADB日志状态 五、ADB常用命令 🎁更多干货 完整版文档下载方式: 一、ADB简介 ADB全称Android Debug Bridge,起到调试桥的作用,是一个客户端-服务端程序。其中客…

C++数据结构X篇_06_C++单向循环链表实现

本篇参考C单向循环链表实现整理,先搞懂结构框架,后期根据视频利用c对内容实现,也可以对c有更高的提升。 文章目录 1. 链表定义2. 链表插入3. 链表打印(注意打印过程是跳过头节点head的)4. 实验 单向循环链表与单向链表十分相似,具…

ST - NUCLEO-H723ZG ITM不生效的问题

文章目录 ST - NUCLEO-H723ZG ITM不生效的问题概述CubeMX配置点END ST - NUCLEO-H723ZG ITM不生效的问题 概述 在用NUCLEO-H723ZG官方板子做实验, 想用ITM打印一些调试信息出来. 不好使啊. 后来查问题, 发现 NUCLEO-H723ZG上的HSE, LSE的晶振无效, 等于是不能用外部的HSE, LS…

如何找到更多音视频开发学习资料和资源?

如果你对学习音视频开发感兴趣,以下是一些建议,可以帮助你获取更多相关的资料和资源: 在线学习平台:参考一些知名的在线学习平台,如Coursera、Udemy、edX等,搜索他们的课程目录,看是否有与音视频…

【SWAT水文模型】SWAT水文模型建立及应用第六期:SWAT模型率定(SWAT CUP)

SWAT模型率定(SWAT CUP) 1 准备工作2 水文模型率定(SWAT CUP)数据准备运行流程 参考 SWAT CUP的下载及安装参见另一博客-【SWAT水文模型】SWAT-CUP安装及使用 下面将具体介绍基于实测水文站数据进行水文模型的率定。 1 准备工作…

【Centos系统故障】虚拟机断电后centos7无法正常启动 XFS(sda3)

1. 背景: 虚拟机断电后centos7无法正常启动 XFS(sda3),通常都是断电以及非法关机,杀掉虚拟机等突然中断系统的情况,会导致内存数据损坏,从而导致linux操作系统无法启动。 2. 解决办法: 清理掉内存数据&a…

windows10 安装wsl2+docker+php+nginx+mysql

第一步在windows10 上安装docker(可视化桌面) 第二步确定本地电脑开启虚拟化,同时确认下方图内容已经勾选 在cmd下使用命令:wsl --install 安装wsl2。因 wsl2 默认安装ubuntu系统。如果安装wsl2后没有安装ubuntu系统,则需要去谷歌商店里搜索…

AutoJs案例---登录界面

"ui";showLoginUI(); ui.statusBarColor("#000000") //顶部颜色为黑色//显示登录界面 function showLoginUI(){ui.layout(<frame><vertical h"auto" align"center" margin"0 50"><linear><text w"…

Nextcloud实现协同办公 -V2

V1在这里&#xff1a;https://blog.csdn.net/philosophyatmath/article/details/130594037。V2没有继续使用onlyoffice而是使用nextcloud office Nextcloud 安装 LAMP&#xff08;LinuxApacheMySQLPHP&#xff09;方式。局域网单机模式。 安装环境&#xff1a; OS:ubuntu 2…

【Redis】Redis配置以及常用命令

文章目录 一、关系型数据库 与 非关系型数据库1. 关系型数据库的概念2. 非关系型数据库的概念3. 关系型数据库和非关系型数据库区别3.1 数据存储方式不同3.2 扩展方式不同3.3 对事务性的支持不同 4. 非关系型数据库产生背景5. 总结5.1 两组区别5.2 创建实例过程 二、Redis 的概…

【玩转Linux操作】详细讲解Shell的判断,循环语句

&#x1f38a;专栏【玩转Linux操作】 &#x1f354;喜欢的诗句&#xff1a;更喜岷山千里雪 三军过后尽开颜。 &#x1f386;音乐分享【如愿】 大一同学小吉&#xff0c;欢迎并且感谢大家指出我的问题&#x1f970; 文章目录 &#x1f354;判断语句⭐单层if&#x1f388;示例 ⭐…

什么是动态住宅代理?

随着网络的迅速发展&#xff0c;许多人对代理IP已经有了比较深刻的认识&#xff0c;并且广泛地运用到了各自的业务中&#xff0c;尤其在跨境的相关业务中表现尤其卓越。对于代理IP的类别&#xff0c;也需要根据自己的业务类型具体选择最合适的&#xff0c;那么今天就给大家具体…

Redis之哨兵模式以及RedisTemplate的使用

Redis之哨兵模式 一 哨兵模式原理 说明&#xff1a; Sentinel具有三个作用&#xff1a;监控&#xff0c;故障转移和通知Sentinel如何判断Redis是否健康 ① 每隔1秒发送一次ping命令&#xff0c;如果超过一定时间没有响应则认为主观下线 ② 如果超过一半以上的sentinel认为实…

【软考网络管理员】2023年软考网管初级常见知识考点(25)- 网络地址转换NAT

涉及知识点 什么是NAT技术&#xff1f;静态网络地址转换&#xff0c;动态网络地址转换&#xff0c;基于端口的网络地址转换,NAPT的配置命令和动态NAT配置命令&#xff0c;软考网络管理员常考知识点&#xff0c;软考网络管理员网络安全&#xff0c;网络管理员考点汇总。 原创于…

Axure教程—下拉刷新

本文从元件的实现、交互的实现两个角度&#xff0c;拆解了APP顶部下拉刷新动效制作&#xff0c;并展示了相应的预览效果。 预览效果 预览地址&#xff1a;https://o95k8e.axshare.com 具体的实现方法 一、元件制作 拖入一个矩形元件&#xff0c;设置大小为375552&#xff0c…

Day41

思维导图 类和结构体的区别 1、结构体是一种值类型&#xff0c;类是引用类型。值类型用于存储数据的值&#xff0c;引用类型用于存储对实际数据的引用。即结构体就是当成值来使用的&#xff0c;类则通过引用来对实际数据操作。 2、结构使用栈存储&#xff08;Stack Allocation&…

最小化安装的Red Hat 9安装完Zabbix后没有中文字体报错解决

Redhat9最小化安装后&#xff0c;将 Zabbix 的界面设置为中文&#xff0c;但是系统提示你服务器上没有安装相应的语言包。这是因为 Zabbix 需要在服务器上安装相应的语言环境才能正常显示相应的语言。 报错提示&#xff1a; You are not able to choose some of the languages,…

MySQLSQL性能调优

1.对查询进行优化&#xff0c;应尽量避免全表扫描&#xff0c;首先应考虑在 where 及 order by 涉及的列上建立索引。 2.应尽量避免在 where 子句中对字段进行 null 值判断&#xff0c;否则将导致引擎放弃使用索引而进行全表扫描&#xff0c; Sql 代码 : select id from t wh…

直流无刷电机FOC控制算法 理论到实践 —— 实践

直流无刷电机FOC控制算法 理论到实践 —— 实践 文章目录 直流无刷电机FOC控制算法 理论到实践 —— 实践1. 前言2. FOC控制整体流程3. FOC实现3.1 定时器实现3.1.1 代码实现 3.2 角度识别3.2.1 机械角度计算3.2.2 电角度计算3.2.3 代码实现 3.3 角度识别初步验证3.4 电流采集3…

【八股】【C++】STL

这里写目录标题 STL定义两大特点两个层次STL构成 容器容器概念容器分类vectorvector概念vector数据结构常用操作 dequestack常用操作 queuelistlist概念常用操作list优势 set 与 multiset容器概念基本函数 set遍历multiset unordered_setmap/multimap容器概念基本函数multimap …