【Unity Shader入门精要 第6章】基础光照(二)

news2024/12/26 20:41:06

1. 获取环境光

unity shader中可以通过 UNITY_LIGHTMODEL_AMBIENT获取当前环境光颜色信息。

fixed4 frag(v2f i) : SV_Target
{
     return UNITY_LIGHTMODEL_AMBIENT;
}

在这里插入图片描述

2. 漫反射

2.1 兰伯特模型

  • 创建Chapter_6_Diffuse_Lambert作为测试材质
  • 创建Chapter_6_Diffuse_Lambert作为测试shader,并赋给Chapter_6_Diffuse_Lambert材质
  • Pass中增加Tags{“LightMode” = “ForwardBase”},并添加引用 #include “Lighting.cginc”
  • 场景中创建胶囊体,将Chapter_6_Diffuse_Lambert材质赋给胶囊体
  • 场景中添加一盏平行光,并调整平行光角度

shader如下:

Shader "MyShader/Chapter_6/Chapter_6_Diffuse_Lambert"
{
    Properties
    {
        _Diffuse("Diffuse", Color) = (1,1,1,1)
    }

    SubShader
    {
        Pass
        {
            Tags{"LightMode" = "ForwardBase"}
            
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #include "Lighting.cginc"
            
            struct a2v
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
            };
            
            struct v2f
            {
                float4 vertex : SV_POSITION;
                fixed4 color : COLOR0;
            };
            
            fixed4 _Diffuse;
            
            v2f vert(a2v i)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(i.vertex);
                fixed3 _ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
                
                float3 _lightDir = normalize(ObjSpaceLightDir(i.vertex));
                float3 _normal = normalize(i.normal);
                fixed3 _diffuse = _LightColor0.rgb * _Diffuse.xyz * saturate(dot(_normal, _lightDir));
                o.color = fixed4(_diffuse + _ambient, 1);

                return o;
            }
            
            fixed4 frag(v2f i) : SV_Target
            {
                return i.color;
            }
            
            ENDCG
        }
    }
}

shader效果如下:
在这里插入图片描述

2.2 半兰伯特模型

  • 将顶点着色器中的 fixed3 _diffuse = _LightColor0.rgb * _Diffuse.xyz * saturate(dot(_normal, _lightDir)); 修改为
    fixed3 _diffuse = _LightColor0.rgb * _Diffuse.xyz * (0.5 * dot(_normal, _lightDir) + 0.5);

效果如下:
在这里插入图片描述

2.3 逐像素的漫反射

  • 以兰伯特模型为基础,将光照计算改为在片元着色器中逐像素处理
  • 需要在顶点着色器中先将顶点的法线转换到世界空间
  • 然后在片元着色器中用插值得到的当前像素的法线方向与世界空间下的光源方向进行光照计算
  • 由于平行光不关心位置信息,因此对于平行光源,_WorldSpaceLightPos0.xyz存储的是光源的方向而不是位置

shader如下:

Shader "MyShader/Chapter_6/Chapter_6_Diffuse_LambertInFragment"
{
    Properties
    {
        _Diffuse("Diffuse", Color) = (1,1,1,1)
    }

    SubShader
    {
        Pass
        {
            Tags{"LightMode" = "ForwardBase"}
            
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #include "Lighting.cginc"
            
            struct a2v
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
            };
            
            struct v2f
            {
                float4 vertex : SV_POSITION;
                float3 worldNormal : COLOR0;
            };
            
            fixed4 _Diffuse;
            
            v2f vert(a2v i)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(i.vertex);
                o.worldNormal = mul(i.normal, (float3x3)unity_WorldToObject);
                return o;
            }
            
            fixed4 frag(v2f i) : SV_Target
            {
                fixed3 _ambient = UNITY_LIGHTMODEL_AMBIENT.rgb;
                
                float3 _worldNormal = normalize(i.worldNormal);
                float3 _worldLight = normalize(_WorldSpaceLightPos0.xyz);
                fixed3 _diffuse = _LightColor0.rgb * _Diffuse.xyz * saturate(dot(_worldNormal, _worldLight));
                
                return fixed4(_diffuse + _ambient, 1);
            }
            
            ENDCG
        }
    }
}

效果如下:
在这里插入图片描述
可见与逐顶点光照相比,阴影边缘明显更加平滑

3. 高光反射

3.1 逐顶点光照的Phong模型

shader如下:

Shader "MyShader/Chapter_6/Chapter_6_Specular_PhongInVertex"
{
    Properties
    {
        _Diffuse("Diffuse", Color) = (1,1,1,1)
        _Specular("Specular", Color) = (1,1,1,1)
        _Gloss("Gloss", Range(1.0, 256.0)) = 20
    }

    SubShader
    {
        Pass
        {
            Tags{"LightMode" = "ForwardBase"}
            
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #include "Lighting.cginc"
            
            struct a2v
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
            };
            
            struct v2f
            {
                float4 vertex : SV_POSITION;
                fixed4 color : COLOR0;
            };
            
            fixed4 _Diffuse;
            fixed4 _Specular;
            half _Gloss;
            
            v2f vert(a2v i)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(i.vertex);
                
                fixed3 _ambient = UNITY_LIGHTMODEL_AMBIENT.rgb;
                
                float3 _lightDir = normalize(ObjSpaceLightDir(i.vertex));
                float3 _normalDir = normalize(i.normal);
                fixed3 _diffuse = _LightColor0.rgb * _Diffuse.xyz * saturate(dot(_lightDir, _normalDir));
                
                float3 _viewDir = normalize(ObjSpaceViewDir(i.vertex));
                float3 _reflDir = normalize(2 * dot(_lightDir, _normalDir) * _normalDir - _lightDir);
                fixed3 _specular = _LightColor0.rgb * _Specular.xyz * pow(saturate(dot(_viewDir, _reflDir)), _Gloss);
                o.color = fixed4(_diffuse + _specular + _ambient, 1);
                
                return o;
            }
            
            fixed4 frag(v2f i) : SV_Target
            {   
                return i.color;
            }
            
            ENDCG
        }
    }
}

效果如下:
在这里插入图片描述

3.2 逐像素光照的Phong模型

  • 这里用 reflect(-_worldLight, _worldNormal) 方法代替了原来手动计算反射光线的过程,二者结果是一样的
  • reflect方法要求传入的入射光方向是从光源指向照射点,因此需要将原来计算得到的光源方向先取反再传入

shader如下:

Shader "MyShader/Chapter_6/Chapter_6_Specular_PhongInFragment"
{
    Properties
    {
        _Diffuse("Diffuse", Color) = (1,1,1,1)
        _Specular("Specular", Color) = (1,1,1,1)
        _Gloss("Gloss", Range(1.0, 256.0)) = 20
    }

    SubShader
    {
        Pass
        {
            Tags{"LightMode" = "ForwardBase"}
            
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #include "Lighting.cginc"
            
            struct a2v
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
            };
            
            struct v2f
            {
                float4 vertex : SV_POSITION;
                float3 worldNormal : COLOR0;
                float3 worldPos : COLOR1;
            };
            
            fixed4 _Diffuse;
            fixed4 _Specular;
            half _Gloss;
            
            v2f vert(a2v i)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(i.vertex);
                o.worldNormal = mul(i.normal, (float3x3)unity_WorldToObject);
                o.worldPos = mul(unity_ObjectToWorld, i.vertex).xyz;
                return o;
            }
            
            fixed4 frag(v2f i) : SV_Target
            {
                fixed3 _ambient = UNITY_LIGHTMODEL_AMBIENT.rgb;
                
                float3 _worldNormal = normalize(i.worldNormal);
                float3 _worldLight = normalize(_WorldSpaceLightPos0.xyz);
                fixed3 _diffuse = _LightColor0.rgb * _Diffuse.xyz * saturate(dot(_worldNormal, _worldLight));
                
                float3 _viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos);
//                float3 _reflDir = normalize(2 * dot(_worldNormal, _worldLight) * _worldNormal - _worldLight);
                float3 _reflDir = normalize(reflect(-_worldLight, _worldNormal));
                fixed3 _specular = _LightColor0.rgb * _Specular.xyz * pow(saturate(dot(_viewDir, _reflDir)), _Gloss);
                
                return fixed4(_diffuse + _specular + _ambient, 1);
            }
            
            ENDCG
        }
    }
}

效果如下:
在这里插入图片描述

3.3 逐像素光照的Blinn-Phong模型

shader如下:

Shader "MyShader/Chapter_6/Chapter_6_Specular_BlinnPhongInFragment"
{
    Properties
    {
        _Diffuse("Diffuse", Color) = (1,1,1,1)
        _Specular("Specular", Color) = (1,1,1,1)
        _Gloss("Gloss", Range(1.0, 256.0)) = 20
    }

    SubShader
    {
        Pass
        {
            Tags{"LightMode" = "ForwardBase"}
            
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #include "Lighting.cginc"
            
            struct a2v
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
            };
            
            struct v2f
            {
                float4 vertex : SV_POSITION;
                float3 worldNormal : COLOR0;
                float3 worldPos : COLOR1;
            };
            
            fixed4 _Diffuse;
            fixed4 _Specular;
            half _Gloss;
            
            v2f vert(a2v i)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(i.vertex);
                o.worldNormal = mul(i.normal, (float3x3)unity_WorldToObject);
                o.worldPos = mul(unity_ObjectToWorld, i.vertex).xyz;
                return o;
            }
            
            fixed4 frag(v2f i) : SV_Target
            {
                fixed3 _ambient = UNITY_LIGHTMODEL_AMBIENT.rgb;
                
                float3 _worldNormal = normalize(i.worldNormal);
                float3 _worldLight = normalize(_WorldSpaceLightPos0.xyz);
                fixed3 _diffuse = _LightColor0.rgb * _Diffuse.xyz * saturate(dot(_worldNormal, _worldLight));
                
                float3 _worldView = normalize(_WorldSpaceCameraPos.xyz - i.worldPos);
                float3 _h = normalize(_worldLight + _worldView);
                fixed3 _specular = _LightColor0.rgb * _Specular.xyz * pow(saturate(dot(_h, _worldNormal)), _Gloss);
                
                return fixed4(_diffuse + _specular + _ambient, 1);
            }
            
            ENDCG
        }
    }
}

效果如下:
在这里插入图片描述
相同Gloss下感觉Blinn-Phong好像要更发散一些,逐顶点的Blinn-Phong就不做了。

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

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

相关文章

AI智能写作网站推荐:好用的工具看这几款就够了!

在近年来的科技发展浪潮中,人工智能写作工具以其独特的优势和魅力,引起了行业内外的广泛关注。从技术层面来看,这种工具的应用和发展已经取得了重要的突破,而从应用层面来看,它们对内容创作领域的深远影响更是不可忽视…

关于Speech processing Universal PERformance Benchmark (SUPERB)基准测试及衍生版本

Speech processing Universal PERformance Benchmark (SUPERB)是由台湾大学、麻省理工大学,卡耐基梅隆大学和 Meta 公司联合提出的评测数据集,其中包含了13项语音理解任务,旨在全面评估模型在语音处理领域的表现。这些…

EasyExcel简单使用

EasyExcel简单使用 ​ 之前一直用的Apache POI来做数据的导入导出&#xff0c;但听说阿里的EasyExcel也拥有POI的功能的同时&#xff0c;在处理大数据量的导入导出的时候性能上比POI更好&#xff0c;所以就来尝试使用一下 导入Maven依赖&#xff1a; <dependency><…

图和网络笔记

文章目录 1. 图(节点边) 1. 图(节点边) 一个图可以由节点和边组成&#xff0c;假设我们有一个节点notes &#xff1a;n4,边edges&#xff1a;m5的有向图&#xff0c;表示如下 通过以上电路图可以得到关联矩阵(incident matrix),我们定义边&#xff0c;开始端用-1表示&#x…

Elasticsearch查看集群信息,设置ES密码,Kibana部署

Elasticsearch查看集群信息&#xff0c;设置ES密码&#xff0c;Kibana部署 查看集群信息查看节点信息查看集群健康状态查看分片信息查看其他集群信息 Kibana部署安装设置ES密码 查看集群信息 查看节点信息 curl http://127.0.0.1:9200/_cat/nodes?v 参数说明&#xff1a; ip…

基于大模型的idea提炼:围绕论文和引用提炼idea之ResearchAgent

前言 对本博客比较熟悉的朋友知道&#xff0c;我司论文项目组正在基于大模型做论文的审稿(含CS英文论文审稿、和金融中文论文审稿)、翻译&#xff0c;且除了审稿翻译之外&#xff0c;我们还将继续做润色/修订、idea提炼(包含论文检索)&#xff0c;是一个大的系统&#xff0c;包…

星辰考古:TiDB v1.0 再回首

“ 1.0 版本只是个开始&#xff0c;是新的起点&#xff0c;愿我们一路相扶&#xff0c;不负远途。 前言 TiDB 是 PingCAP 公司自主设计、研发的开源分布式关系型数据库。 近日&#xff0c;TiDB v8.0.0 DMR 发布&#xff0c;详细发版说明戳这里&#xff1a; https://docs.pingca…

【C/C++】C/C++ KTV点歌系统设计与实现(源码+数据+报告)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

3588 pwm android12 的操作

问题&#xff1a; 客户需要在android12 的界面上操作板卡上的 PWM 蜂鸣器设备。 过程&#xff1a; 1 了解一下 3588 android12 源码的 关于PWM 的驱动。 设备树找不到 pwm 但是&#xff0c; 还不知道&#xff0c;android12 最终包含的 设备树是哪个&#xff0c;但是经过我的…

MyCat实现分库分表

两个集群 两个库 两个表 搭建数据库服务使用docker启动两个mysql 3506 3507连接MyCat创建两个数据源连接MyCat创建集群 mycat创建逻辑库MyCat创建全局表广播表创建分片表mycat逻辑库MyCat插入数据mycat查看数据物理库3506查看数据物理库3507查看数据 ER表创建ER表mycat插入数据…

蓝桥杯练习系统(算法训练)ALGO-946 Q神的足球赛

资源限制 内存限制&#xff1a;256.0MB C/C时间限制&#xff1a;1.0s Java时间限制&#xff1a;3.0s Python时间限制&#xff1a;5.0s 问题描述 足球赛上&#xff0c;只见Q神如闪电般的速度带球时而左&#xff0c;时而右&#xff0c;时而前&#xff0c;时而后&#xff…

HDFS HA 修改nameservice

本例中修改将原来的hdfs-ha 修改为 hdfs-ns 停止HDFS, 防止新的业务操作 等待停止结束 KDE中需要调整的配置项如下图所示 a.搜索栏找到fs.defaultFS&#xff0c;将hdfs://hdfs-ha改为hdfs://hdfs-ns b.搜索栏找到dfs.nameservices&#xff0c;将hdfs-ha改为hdfs-ns c.搜索栏找…

HBuilder报错--openssl-legacy-provider is not allowed in NODE_OPTIONS解决方法

目录 一、问题描述二、解决方法 一、问题描述 HBuilder编译时报错&#xff1a;–openssl-legacy-provider is not allowed in NODE_OPTIONS 二、解决方法 将 windows 环境变量 NODE_OPTIONS 的值设置为空&#xff0c;由&#xff1a; 改为&#xff1a;

并发-判断线程对象是否处于活动状态 - isAlive

t.isAlive() 测试线程t是否处于活动状态&#xff0c;只要线程启动并且没有终止&#xff0c;方法返回值就是truestart()之前&#xff0c;线程不处于活动状态&#xff0c;之后就处于活动状态示例&#xff1a;运行结果&#xff1a;但是事情并没有这么简单&#xff0c;先来看一下以…

【每日刷题】Day37

【每日刷题】Day37 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. 2391. 收集垃圾的最少总时间 - 力扣&#xff08;LeetCode&#xff09; 2. 1614. 括号的最大嵌套深度…

软件库V1.5版本iApp源码V3

软件库V1.5版本iApp源码V3 配置教程在【mian.iyu】的【载入事件】 更新内容&#xff1a; 1、分类对接蓝奏&#xff08;免费&#xff0c;付费&#xff0c;会员&#xff0c;广告&#xff09;&#xff0c;支持蓝奏文件描述设置为简介&#xff08;改动&#xff1a;首页.iyu&#…

【算法】二叉树中的dfs

快乐的流畅&#xff1a;个人主页 个人专栏&#xff1a;《算法神殿》《数据结构世界》《进击的C》 远方有一堆篝火&#xff0c;在为久候之人燃烧&#xff01; 文章目录 引言一、计算布尔二叉树的值二、求根节点到叶节点数字之和三、二叉树剪枝四、验证搜索二叉树五、二叉搜索树中…

该从哪些方面提升系统的吞吐量?

更多大厂面试内容可见 -> http://11come.cn 该从哪些方面提升系统的吞吐量&#xff1f; 我们平时自己做的项目一般没有用户量&#xff0c;都是练手项目&#xff0c;所以并不会在吞吐量上做出很多的优化&#xff0c;但是这样的话&#xff0c;又会导致项目和其他人相比并没有…

mysql设置远程访问权限,允许其他IP访问

文章目录 更改mysql配置文件登录mysql 更改mysql配置文件 查找.ini或者.cnf文件 更改bind-address为0.0.0.0 [mysqld] character-set-serverutf8mb4 bind-address0.0.0.0 default-storage-engineINNODB [mysql] default-character-setutf8mb4 [client] default-character-s…

ppt保存文件奇怪问题

我发现ppt中的形状保存成jpg,png和pdf时&#xff0c;格式不一样 比如 当右键单击时&#xff0c;然后选择另存为图片 png格式 jpg格式 pdf格式 感觉还是很奇怪&#xff0c;就pdf的格式比较靠谱一点