unity shader 较完整光照(含有多光源阴影)

在Unity引擎中,开发者可以使用Shader编写自定义着色器,来实现对游戏场景中的模型、材质进行更加高级的渲染。其中,光照是Shader编写中十分重要的一个环节,一个较完整的光照着色器需要包括基础光照、多光源、阴影等要素。下面介绍一些实现这些功能的方法:

1. 基础光照

在Unity中,使用Built-in Shader中的“Surface Shader”或“Unlit Shader”都提供基础光照的功能。如果需要自定义光照模型,则需要使用ShaderLab来手动编写对应的光照部分。

在ShaderLab代码中,可以使用光照计算的内置函数,如Lightinglighthalf4 AmbientLight等。通过计算每个像素点的法线、反射光、漫反射光等参数,可以模拟光照的效果。

以下是一个简单的基础光照示例:

Shader "Custom/LightingExampleShader" {
    Properties {
        _MainTex("Texture", 2D) = "white" {}
    }

    SubShader {
        Tags {
            "RenderType"="Opaque"
        }

        CGPROGRAM
        #pragma surface surf Standard

        struct Input {
            float2 uv_MainTex;
        };

        sampler2D _MainTex;

        void surf (Input IN, inout SurfaceOutputStandard o) {
            o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb;
            o.Metallic = 0.5;
            o.Smoothness = 0.5;
            o.Normal = float3(0,0,1);
        }

        ENDCG
    }

    FallBack "Diffuse"
}

2. 多光源

Unity内置提供了多种光源类型,例如:点光源、方向光,聚光灯等。使用Shader编写的时候,可以通过内置的_LightColor0_LightColor1等Uniform来获取不同光源的颜色。同时也可以自定义Uniform变量,来获取光源的位置、方向、光照范围等属性。

以下是一个简单的多光源示例,在渲染过程中,使用了两个点光源和一个方向光:

Shader "Custom/MultiLightExampleShader" {
    Properties {
        _MainTex("Texture", 2D) = "white" {}
    }

    SubShader {
        Tags {
            "RenderType"="Opaque"
        }

        CGPROGRAM
        #pragma surface surf Standard

        struct Input {
            float2 uv_MainTex;
        };

        sampler2D _MainTex;

        void surf (Input IN, inout SurfaceOutputStandard o) {
            float3 lightingColor = float3(0,0,0);

            // Point Light 1
            float3 pointLight1Dir = _WorldSpaceLightPos0.xyz - UnityObjectToWorldPos(float3(0,0,0));
            float3 pointLight1Color = _LightColor0.rgb;
            float3 pointLight1Attenuation = UnityInverseSquaredDistance(UnityObjectToWorldPos(float3(0,0,0)), _WorldSpaceLightPos0);

            lightingColor += pointLight1Color * pointLight1Attenuation * max(dot(normalize(IN.worldNormal), normalize(pointLight1Dir)), 0);

            // Point Light 2
            float3 pointLight2Dir = _WorldSpaceLightPos1.xyz - UnityObjectToWorldPos(float3(0,0,0));
            float3 pointLight2Color = _LightColor1.rgb;
            float3 pointLight2Attenuation = UnityInverseSquaredDistance(UnityObjectToWorldPos(float3(0,0,0)), _WorldSpaceLightPos1);

            lightingColor += pointLight2Color * pointLight2Attenuation * max(dot(normalize(IN.worldNormal), normalize(pointLight2Dir)), 0);

            // Directional Light
            float3 directionalLightDir = _WorldSpaceLightPos2.xyz;
            float3 directionalLightColor = _LightColor2.rgb;

            lightingColor += directionalLightColor * max(dot(normalize(IN.worldNormal), normalize(directionalLightDir)), 0);

            o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb;
            o.Metallic = 0.5;
            o.Smoothness = 0.5;
            o.Normal = float3(0,0,1);
            o.Emission = lightingColor;
        }

        ENDCG
    }

    FallBack "Diffuse"
}

3. 阴影

Unity的光照计算支持实时阴影。使用Shader绘制的物体在有灯光照射下,会产生阴影效果。Unity提供了内置的ShadowMap,可以通过内置的函数来获取阴影采样。

以下是一个简单的实时阴影示例:

Shader "Custom/ShadowExampleShader" {
    Properties {
        _MainTex("Texture", 2D) = "white" {}
    }

    SubShader {
        Tags {
            "RenderType"="Opaque"
        }

        CGPROGRAM
        #pragma surface surf Standard

        struct Input {
            float2 uv_MainTex;
            float3 worldPos;
            float3 worldNormal;
        };

        sampler2D _MainTex;
        float4x4 _WorldToShadow;
        sampler2D _ShadowMapTexture;
        float4 _ShadowMapTexture_ST;

        void surf (Input IN, inout SurfaceOutputStandard o) {
            float4 shadowUV = UnityShadowCoord(IN.worldPos);
            shadowUV.z += 0.0001;
            float shadowValue = tex2D(_ShadowMapTexture, shadowUV.xy).r;

            float3 lightingColor = float3(0,0,0);

            float3 pointLightDir = _WorldSpaceLightPos0.xyz - IN.worldPos;
            float3 pointLightColor = _LightColor0.rgb;
            float3 pointLightAttenuation = UnityInverseSquaredDistance(IN.worldPos, _WorldSpaceLightPos0);

            lightingColor += pointLightColor * pointLightAttenuation * max(dot(normalize(IN.worldNormal), normalize(pointLightDir)), 0) * shadowValue;

            o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb;
            o.Metallic = 0.5;
            o.Smoothness = 0.5;
            o.Normal = float3(0,0,1);
            o.Emission = lightingColor;
        }

        ENDCG
    }

    FallBack "Diffuse"
}

以上就是一个较完整的光照Shader的几个要点,开发者可以根据自己的需求来进行进一步的改良。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:unity shader 较完整光照(含有多光源阴影) - Python技术站

(0)
上一篇 2023年6月3日
下一篇 2023年6月3日

相关文章

  • .Net 对于PDF生成以及各种转换的操作

    以下是关于”.Net 对于PDF生成以及各种转换的操作”的完整攻略。 准备工作 在开始操作之前,需要准备以下工具: Visual Studio,用于编写 .Net 程序。 iTextSharp,用于生成 PDF 文件。 Ghostscript,用于将 PDF 文件转换为图片或其他格式文件。 生成 PDF 文件 1. 安装 iTextSharp 在 Visua…

    C# 2023年6月3日
    00
  • C#求数组中元素全排列的方法

    C#求数组中元素全排列的方法 我们可以通过递归的方式来实现在C#中获取一个数组中元素的全排列。 public static void FullPermutation<T>(T[] arr, int startIndex, int endIndex) { if (startIndex == endIndex) { Console.WriteLine…

    C# 2023年6月7日
    00
  • VisualStudio怎么设置粘贴时格式不变? vs粘贴时自动缩进的技巧

    当在VisualStudio中使用复制粘贴操作时,有时候会出现格式混乱的情况,这时候我们可以进行设置来使得粘贴时不改变格式。同时,还可以设置粘贴时自动缩进,方便代码的编写与阅读。 以下是VisualStudio设置粘贴时格式不变或自动缩进的方法: 1. 设置粘贴时格式不变 步骤: 打开VisualStudio,进入“工具”菜单,选择“选项”。 在弹出的“选项…

    C# 2023年6月6日
    00
  • C#中的composite模式示例详解

    C#中的Composite模式示例详解 Composite模式是一种结构型设计模式,它可以通过组合多个对象来创建一个复杂的结构,并且与它们的父对象一起使用。这种模式可以让客户端代码以统一的方式来处理单个对象和对象组合的结构,而不需要区分它们之间的差异,从而提高了代码的可维护性和可扩展性。接下来,我们将通过两个示例来详细讲解C#中的Composite模式。 示…

    C# 2023年5月15日
    00
  • 利用C#实现合并Word文档功能

    实现合并Word文档功能主要涉及到以下几个步骤: 1. 安装OpenXML SDK OpenXML SDK是用于处理Office文件的开源API,我们可以使用它来处理Word文档。 安装方法: 在Visual Studio中打开NuGet包管理器(Tools -> NuGet Package Manager -> Manage NuGet Pac…

    C# 2023年6月1日
    00
  • C# 使用Tcp/Udp协议的示例代码

    C#是一种面向对象的编程语言,它可以通过Tcp/Udp协议与其他网络设备进行通信。为了更好地掌握C#使用Tcp/Udp协议的示例代码,我们需要专门制定一套攻略,下面是具体的过程: 1.了解Tcp/Udp协议 在编写C#代码之前,需要先了解Tcp/Udp协议。Tcp协议是一种面向连接的协议,它提供可靠的数据传输和错误恢复机制,并保证数据的无序交付;Udp协议是…

    C# 2023年5月31日
    00
  • C#实现泛型List分组输出元素的方法

    下面是详细讲解“C#实现泛型List分组输出元素的方法”的完整攻略。 1. 题目背景 在 C# 中, 泛型(Generic)是指写代码时不必指定具体的类型,而是在使用时在指定类型。List 是 C# 中常用的泛型集合类型。当我们需要对一个 List 进行分组后输出元素,就需要用到泛型 List 分组的方法。 2. 泛型 List 分组的方法 2.1 Grou…

    C# 2023年6月7日
    00
  • C#字符串与正则表达式的图文详解

    C#字符串与正则表达式的图文详解 1. 什么是正则表达式 正则表达式(Regular Expression)是一种用来描述、匹配文本字符串的工具,它是由元字符和字符组成的表达式。使用正则表达式可以快捷方便的实现字符串的匹配、查找与替换等操作。 2. 正则表达式的基本语法 2.1 元字符 元字符是正则表达式中的特殊字符,其在匹配过程中具有特殊含义,常见的元字符…

    C# 2023年6月7日
    00
合作推广
合作推广
分享本页
返回顶部