首页 > 其他分享 >Unity3D 光照计算方向与法线贴图详解

Unity3D 光照计算方向与法线贴图详解

时间:2024-02-28 09:44:54浏览次数:27  
标签:贴图 Unity3D 法线 MainTex 计算 BumpMap 光照

在Unity3D中,光照计算方向与法线贴图是实现高质量光照效果的重要技术之一。本文将详细介绍光照计算方向与法线贴图的原理和实现方法,并给出相应的代码示例。

对啦!这里有个游戏开发交流小组里面聚集了一帮热爱学习游戏的零基础小白,也有一些正在从事游戏开发的技术大佬,欢迎你来交流学习。

一、光照计算方向

在Unity3D中,光照计算方向是指根据光源的位置和光照强度,计算出每个像素点的光照方向。通过光照计算方向,可以实现不同光源对物体的照明效果,让物体在不同光照条件下呈现出不同的明暗效果。

光照计算方向的原理是根据光源的位置和物体表面的法线向量,计算出光线与法线的夹角,进而确定光照方向。在Unity3D中,可以使用Shader来实现光照计算方向,下面是一个简单的Shader示例:

Shader "Custom/LightDirection"
{
    Properties
    {
        _MainTex ("Base (RGB)", 2D) = "white" {}
        _LightPos ("Light Position", Vector) = (0, 1, 0, 0)
    }
    
    SubShader
    {
        Tags { "RenderType" = "Opaque" }
        
        CGPROGRAM
        #pragma surface surf Lambert
        
        struct Input
        {
            float2 uv_MainTex;
            float3 worldPos;
            float3 worldNormal;
        };
        
        sampler2D _MainTex;
        float4 _LightPos;
        
        void surf (Input IN, inout SurfaceOutput o)
        {
            float3 lightDir = normalize(_LightPos - IN.worldPos);
            float diff = max(0, dot(IN.worldNormal, lightDir));
            o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb * diff;
        }
        ENDCG
    }
    
    FallBack "Diffuse"
}

在上面的Shader中,我们定义了一个光源的位置属性_LightPos,并在surf函数中计算出光照方向lightDir,并根据光照方向和法线向量计算出光照强度diff,最终将光照强度乘以纹理颜色作为物体的颜色输出。

二、法线贴图

法线贴图是一种用来模拟物体表面细节的技术,通过在物体表面上贴上法线贴图,可以让物体在渲染时呈现出更加真实的细节效果。在Unity3D中,法线贴图通常用来模拟表面的凹凸不平,比如褶皱、纹理等。

法线贴图的原理是在物体表面上存储法线向量信息,通过在像素着色器中根据法线贴图的信息计算出新的法线向量,从而影响光照效果。下面是一个简单的法线贴图Shader示例:

Shader "Custom/NormalMap"
{
    Properties
    {
        _MainTex ("Base (RGB)", 2D) = "white" {}
        _BumpMap ("Normalmap", 2D) = "bump" {}
        _BumpScale ("Bump Scale", Range(0.01, 0.2)) = 0.1
    }
    
    SubShader
    {
        Tags { "RenderType" = "Opaque" }
        
        CGPROGRAM
        #pragma surface surf Lambert
        
        struct Input
        {
            float2 uv_MainTex;
            float2 uv_BumpMap;
            float3 worldPos;
            float3 worldNormal;
        };
        
        sampler2D _MainTex;
        sampler2D _BumpMap;
        float _BumpScale;
        
        void surf (Input IN, inout SurfaceOutput o)
        {
            float3 normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
            normal = normalize(normal * 2 - 1);
            o.Normal = normal;
            
            o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb;
        }
        ENDCG
    }
    
    FallBack "Diffuse"
}

在上面的Shader中,我们定义了一个法线贴图属性_BumpMap,并在surf函数中根据法线贴图的信息计算出新的法线向量normal,并将其赋值给SurfaceOutput结构体的Normal属性,从而影响光照效果。同时,我们还将法线贴图的颜色作为物体的颜色输出。

三、光照计算方向与法线贴图的结合

光照计算方向与法线贴图可以结合使用,实现更加逼真的光照效果。在Unity3D中,可以通过在Shader中同时实现光照计算方向和法线贴图,来使物体在不同光照条件下呈现出更加真实的细节效果。下面是一个结合光照计算方向和法线贴图的Shader示例:

Shader "Custom/LightAndNormalMap"
{
    Properties
    {
        _MainTex ("Base (RGB)", 2D) = "white" {}
        _BumpMap ("Normalmap", 2D) = "bump" {}
        _LightPos ("Light Position", Vector) = (0, 1, 0, 0)
    }
    
    SubShader
    {
        Tags { "RenderType" = "Opaque" }
        
        CGPROGRAM
        #pragma surface surf Lambert
        
        struct Input
        {
            float2 uv_MainTex;
            float2 uv_BumpMap;
            float3 worldPos;
            float3 worldNormal;
        };
        
        sampler2D _MainTex;
        sampler2D _BumpMap;
        float4 _LightPos;
        
        void surf (Input IN, inout SurfaceOutput o)
        {
            float3 normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
            normal = normalize(normal * 2 - 1);
            
            float3 lightDir = normalize(_LightPos - IN.worldPos);
            float diff = max(0, dot(normal, lightDir));
            
            o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb * diff;
        }
        ENDCG
    }
    
    FallBack "Diffuse"
}

在上面的Shader中,我们同时定义了光源的位置属性_LightPos和法线贴图属性_BumpMap,并在surf函数中同时计算出光照方向和新的法线向量,从而实现了光照计算方向和法线贴图的结合效果。

总结

光照计算方向与法线贴图是Unity3D中实现高质量光照效果的重要技术之一。通过合理地使用光照计算方向和法线贴图,可以让物体在不同光照条件下呈现出更加真实的细节效果,提升游戏的视觉质量。开发者可以根据项目需求,灵活地使用光照计算方向和法线贴图,来实现更加逼真的光照效果。

标签:贴图,Unity3D,法线,MainTex,计算,BumpMap,光照
From: https://www.cnblogs.com/bycw/p/18039032

相关文章

  • Unity3D 逐顶点光照与逐像素光照详解
    Unity3D提供了丰富的功能和工具,其中包括逐顶点光照和逐像素光照。本文将详细解释这两种光照技术的原理和实现方式,并提供代码示例。对啦!这里有个游戏开发交流小组里面聚集了一帮热爱学习游戏的零基础小白,也有一些正在从事游戏开发的技术大佬,欢迎你来交流学习。一、逐顶点光照逐......
  • 【libGDX】Mesh立方体贴图(6张图)
    1前言​本文通过一个立方体贴图的例子,讲解三维纹理贴图的应用,案例中使用6张不同的图片给立方体贴图,图片如下。​读者如果对libGDX不太熟悉,请回顾以下内容。使用Mesh绘制三角形使用Mesh绘制矩形使用Mesh绘制圆形使用Mesh绘制立方体Mesh纹理贴图2立方体贴......
  • 【libGDX】Mesh纹理贴图
    1前言​纹理贴图的本质是将图片的纹理坐标与模型的顶点坐标建立一一映射关系。纹理坐标的x、y轴正方向分别朝右和朝下,如下。2纹理贴图​本节将使用Mesh、ShaderProgram、Shader实现纹理贴图,OpenGLES的实现见博客→纹理贴图,本节完整代码资源见→libGDXMes......
  • Unity3D 帧同步的原理与常用的处理方式详解
    Unity3D是一款广泛应用于游戏开发的跨平台游戏引擎,其帧同步技术是实现多人游戏联机的关键之一。本文将详细介绍Unity3D帧同步的原理以及常用的处理方式,并给出相关的技术详解和代码实现。对啦!这里有个游戏开发交流小组里面聚集了一帮热爱学习游戏的零基础小白,也有一些正在从事游戏......
  • Unity3D DrawCall和openGL、光栅化等有何内在联系详解
    前言Unity3D是一款跨平台的游戏引擎,广泛应用于游戏开发领域。在Unity3D中,DrawCall是一个重要的概念,它与OpenGL、光栅化等技术有着密切的内在联系。本文将详细解释DrawCall的概念,并给出相关技术的详细解释和代码实现。对惹,这里有一个游戏开发交流小组,希望大家可以点击进来一起交......
  • Unity3D DrawCall和openGL、光栅化等有何内在联系详解
    Unity3D是一款跨平台的游戏引擎,广泛应用于游戏开发领域。在Unity3D中,DrawCall是一个重要的概念,它与OpenGL、光栅化等技术有着密切的内在联系。本文将详细解释DrawCall的概念,并给出相关技术的详细解释和代码实现。对啦!这里有个游戏开发交流小组里面聚集了一帮热爱学习游戏的零基础......
  • Unity3D 游戏中的自动寻路有怎样的算法详解
    前言Unity3D是一款非常流行的游戏引擎,它的自动寻路功能可以使游戏角色在场景中自动找到最短路径并前往目标位置。本文将详细介绍Unity3D中自动寻路的算法原理以及代码实现。对惹,这里有一个游戏开发交流小组,希望大家可以点击进来一起交流一下开发经验呀在游戏开发中,自动寻路是......
  • Unity3D Rts游戏里的群体移动算法是如何实现的详解
    实时战略(RTS)游戏是一种以管理和控制虚拟军队为主题的游戏类型。在这类游戏中,玩家需要控制大量的单位进行战斗、资源采集和建设等操作。其中,群体移动算法是实现这些操作的关键之一。本文将详细介绍Unity3DRTS游戏中群体移动算法的实现原理和代码实现。对啦!这里有个游戏开发交流小......
  • Unity3D Rts游戏里的群体移动算法是如何实现的详解
    前言实时战略(RTS)游戏是一种以管理和控制虚拟军队为主题的游戏类型。在这类游戏中,玩家需要控制大量的单位进行战斗、资源采集和建设等操作。其中,群体移动算法是实现这些操作的关键之一。本文将详细介绍Unity3DRTS游戏中群体移动算法的实现原理和代码实现。对惹,这里有一个游戏开......
  • Unity3D 游戏转场时如何保留节点信息详解
    Unity3D是一款非常强大的游戏开发引擎,它提供了丰富的功能和工具,使开发者能够轻松创建各种类型的游戏。在游戏开发过程中,转场是一个非常常见的需求,它可以使游戏过程更加流畅和连贯。然而,在转场过程中,如何保留节点信息是一个需要解决的问题。本文将详细介绍Unity3D游戏转场时如何保......