原批之星—鲁健—原神项目代码分解(八)

 一、原批之星简介        

        鲁健,2021年9月就读于南京邮电大学自动化学院、人工智能学院智能科学与技术专业,主修人工智能方向的相关课程,极其擅长具身智能的相关开发,曾被誉为“原批之星”,最有希望颠覆三国杀的人之一。鲁健工作积极认真,细心负责,熟练运用办公自动化软件,善于在工作中提出问题、发现问题、解决问题,有较强的分析能力;勤奋好学,踏实肯干,动手能力强,有很强的社会责任感;对新事物的学习兴趣和接收能力强能快速应对项目的转变和学习最新的知识。

二、原神3D视觉

        《原神》的3D视觉是其吸引玩家的重要因素之一,它通过一系列先进的技术和细致的优化,实现了一个既逼真又具有艺术感的游戏体验。以下是对《原神》3D视觉的几个关键方面的详细描述和相关代码示例。《原神》采用了三渲二画风,这是一种结合了3D模型的立体感和2D动画的流畅性及艺术风格的表现形式。这种风格通过高饱和度的颜色和独特的光影效果,使得游戏世界显得既生动又梦幻。在技术上,这涉及到光线追踪、光照模型、纹理映射等多个环节。光线追踪模拟了现实世界中光线的传播和相互作用,使得场景和物体看起来更加真实。光照模型则模拟了光线与物体相交后的光照效果,如环境光照、漫反射光照和镜面反射光照等,为游戏场景增添了丰富的光影效果。

1. 光照模型和纹理映射

        在Unity中,我们可以通过调整材质的Shader和光照设置来模拟《原神》中的光照效果。以下是一个简单的Shader代码,它模拟了环境光照、漫反射光照和镜面反射光照:

Shader "Custom/ToonShader"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _RimColor ("Rim Color", Color) = (1,1,1,1)
        _RimPower ("Rim Power", Float) = 1.0
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float3 normal : TEXCOORD1;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
            fixed4 _RimColor;
            float _RimPower;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                o.normal = UnityObjectToWorldNormal(v.normal);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                // 漫反射光照
                fixed3 worldNormal = normalize(i.normal);
                fixed3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
                fixed diff = max(0, dot(worldNormal, lightDir));

                // 环境光照
                fixed ambient = 0.5;

                // 镜面反射光照
                fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.vertex.xyz);
                fixed spe

2. 光线追踪

Unity目前不支持硬件加速的光线追踪,但可以通过计算Shader来模拟光线追踪的效果。以下是一个简单的光线追踪示例,用于计算光线与物体的相交:

// 这个示例需要在Unity的Shader中实现,而不是C#脚本
// 光线追踪的Shader实现较为复杂,这里仅提供一个概念性的框架

RWStructuredBuffer<float3> rayOrigins : register(u0);
RWStructuredBuffer<float3> rayDirections : register(u1);
RWTexture3D<float4> outputTexture : register(u2);

[numthreads(8, 8, 1)]
void CSMain(uint3 DTid : SV_DispatchThreadID)
{
    float3 rayOrigin = rayOrigins[DTid.x];
    float3 rayDirection = rayDirections[DTid.y];
    // 光线与场景中物体的相交检测逻辑
    // ...
    // 根据光线追踪的结果,更新输出纹理
    outputTexture[DTid] = float4(rayColor, 1.0);
}

3. 高饱和度的颜色和独特的光影效果

在Unity中,我们可以通过后处理来调整颜色饱和度和光影效果。以下是一个简单的后处理脚本,用于调整颜色饱和度:

using UnityEngine;
using UnityEngine.Rendering.PostProcessing;

public class SaturationEffect : MonoBehaviour
{
    public PostProcessVolume volume;
    public float saturation = 1.5f;

    void Start()
    {
        volume.profile.TryGetSettings(out ColorGrading colorGrading);
        colorGrading.saturation.value = saturation;
    }

    void Update()
    {
        // 动态调整饱和度
        volume.profile.TryGetSettings(out ColorGrading colorGrading);
        colorGrading.saturation.value = saturation + Input.GetAxis("Mouse ScrollWheel") * 0.1f;
    }
}

        请注意,这些代码示例仅用于说明如何在Unity中实现类似于《原神》的视觉效果,并不代表《原神》实际使用的代码。实际的实现会更加复杂,并且会涉及到大量的性能优化和细节调整。

三、LOD技术的应用

        为了处理《原神》中庞大的场景和众多的物体,《原神》采用了LOD(Level Of Detail)技术。LOD技术的核心思想是“好钢用在刀刃上”,即为近处的物体分配较高细节程度的模型,而远处的物体则分配较低细节程度的模型,以达到减少资源消耗的目的。这不仅适用于模型,也适用于纹理等信息。在代码层面,LOD的实现可能涉及到对模型和纹理的动态加载和卸载,以及根据摄像机距离动态调整模型和纹理的分辨率。

1.PBR渲染方程

        《原神》还采用了基于物理的渲染(PBR)技术,这是一种模拟真实世界光照效果的关键技术。PBR渲染方程能够模拟光源对模型表面的照射效果,产生逼真的明暗、阴影和质感。在Unity中,PBR的实现可以通过调整材质的金属度、粗糙度等属性来实现,这些属性影响光线如何与物体表面相互作用。

Shader "Custom/PBRShader"
{
    Properties
    {
        _Albedo("Albedo", Color) = (1,1,1,1)
        _Metallic("Metallic", Range(0,1)) = 0
        _Roughness("Roughness", Range(0,1)) = 1
        _Normal("Normal Map", 2D) = "bump" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
        #pragma surface surf Standard fullforwardshadows

        // Use shader model 3.0 target, which is compatible with Unity's built-in PBR shaders
        #pragma target 3.0

        struct Input
        {
            float2 uv_MainTex;
            float2 uv_Normal;
        };

        half4 _Albedo;
        half _Metallic;
        half _Roughness;
        sampler2D _Normal;

        // Add instancing support for this shader. You need to check 'Enable Instancing' in the
        // shader settings if you want this shader to be used with instanced rendering.
        // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information
        // #pragma instancing_options assumeuniformscaling
        UNITY_INSTANCING_BUFFER_START(Props)
            // put more per-instance properties here
        UNITY_INSTANCING_BUFFER_END(Props)

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            // Albedo comes from a texture tinted by color
            fixed4 albedo = _Albedo;
            o.Albedo = albedo.rgb;

            // Metallic and smoothness come from slider variables
            o.Metallic = _Metallic;
            o.Smoothness = 1 - _Roughness; // Smoothness is the opposite of roughness

            // Normal comes from a texture
            o.Normal = UnpackNormal(tex2D(_Normal, IN.uv_MainTex));
        }
        ENDCG
    }
    FallBack "Diffuse"
}

        这个Shader定义了四个属性:基础颜色(_Albedo)、金属度(_Metallic)、粗糙度(_Roughness)和一个法线贴图(_Normal)。在CGPROGRAM块中,我们定义了一个输入结构体Input,它包含了纹理坐标,以及一个surf函数,该函数计算表面的输出。

2.人物移动和镜头变换

        在《原神》中,玩家可以环绕人物随便转动视觉,人物也可以随意走动。这种自由的相机控制是通过脚本来实现的。以下是一个简单的CameraControl脚本,它允许玩家通过鼠标和键盘控制相机围绕角色旋转和缩放:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraControl : MonoBehaviour
{
    private Transform player;
    private Vector3 dir;

    void Start()
    {
        player = GameObject.FindGameObjectWithTag("Player").transform;
        dir = player.transform.position - transform.position;
    }

    void Update()
    {
        if (Input.GetKeyUp(KeyCode.LeftAlt))
        {
            Cursor.lockState = Cursor.lockState == CursorLockMode.Locked ? CursorLockMode.None : CursorLockMode.Locked;
        }
        transform.position = player.transform.position - dir;

        if (Input.GetAxis("Mouse ScrollWheel") > 0)
        {
            transform.Translate(dir / 6f, Space.World);
            dir = player.transform.position - transform.position;
        }
        else if (Input.GetAxis("Mouse ScrollWheel") < 0)
        {
            transform.Translate(-dir / 6f, Space.World);
            dir = player.transform.position - transform.position;
        }

        if (Input.GetAxis("Mouse X") != 0f)
        {
            float mouseX = Input.GetAxis("Mouse X");
            transform.RotateAround(player.position, Vector3.up, mouseX);
        }
    }
}

        这段代码通过监听玩家的输入来调整相机的位置和旋转,实现了类似于《原神》中的相机控制效果。通过这些技术和代码实现,我们可以看到《原神》的3D视觉是如何通过精心设计和技术创新来提供给玩家一个既美观又流畅的游戏体验。

三、进阶分析

        对于《原神》这样的高级3D游戏,进阶的代码分析会涉及到更复杂的技术和算法。以下是一些进阶的代码分析和实现细节,这些技术在《原神》中可能被用于提升游戏的视觉效果和性能。

1. 高级光照和阴影处理

        在《原神》中,为了实现逼真的光照效果,可能使用了高级的光照技术,如全局光照(Global Illumination, GI)、动态阴影(Dynamic Shadows)和HDR光照(High Dynamic Range Lighting)。以下是Unity中实现动态阴影的一个示例代码:

using UnityEngine;

[RequireComponent(typeof(Light))]
public class DynamicShadow : MonoBehaviour
{
    public float shadowStrength = 1.0f;
    public float shadowDistance = 10.0f;

    private Light lightSource;

    void Start()
    {
        lightSource = GetComponent<Light>();
    }

    void Update()
    {
        // 动态调整阴影强度和距离
        lightSource.shadowStrength = shadowStrength;
        lightSource.shadows = LightShadows.HardShadows;
        lightSource.shadowBias = 0.1f; // 减少阴影中的伪影
    }
}

2. 环境光遮蔽(Ambient Occlusion)

        环境光遮蔽是一种用于增强场景深度感的技术,它通过模拟光线在场景中的散射来增加暗部细节。以下是一个简单的环境光遮蔽着色器代码示例:

Shader "Custom/AmbientOcclusion"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                // 这里添加环境光遮蔽的计算逻辑
                fixed4 col = tex2D(_MainTex, i.uv);
                // 假设我们有一个环境光遮蔽的纹理
                fixed ao = tex2D(_AmbientOcclusionTex, i.uv).r;
                col.rgb *= ao; // 应用环境光遮蔽
                return col;
            }
            ENDCG
        }
    }
    FallBack "Diffuse"
}

3. 体积雾(Volumetric Fog)

体积雾是一种用于模拟雾、烟等半透明物质的技术,它通过在3D空间中模拟光线的散射来实现。以下是一个简单的体积雾着色器代码示例:

Shader "Custom/VolumetricFog"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _FogDensity ("Fog Density", Float) = 1.0
    }
    SubShader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
                float4 fogFactor : TEXCOORD1;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
            float _FogDensity;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                float4 worldPosition = mul(unity_ObjectToWorld, v.vertex);
                o.fogFactor = worldPosition.z * _FogDensity; // 计算雾的因子
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv);
                // 应用体积雾效果
                float fogIntensity = exp(-i.fogFactor);
                col.rgb = lerp(col.rgb, _FogColor, fogIntensity);
                return col;
            }
            ENDCG
        }
    }
    FallBack "Diffuse"
}

4. 后处理效果(Post-Processing)

后处理是提升游戏视觉效果的重要环节,它包括色调映射、颜色校正、景深、运动模糊等多种效果。以下是一个简单的后处理脚本示例,用于实现色调映射:

using UnityEngine;
using UnityEngine.Rendering.PostProcessing;

public class ToneMapping : MonoBehaviour
{
    public PostProcessVolume volume;

    void Start()
    {
        volume.profile.TryGetSettings(out Tonemapping tonemapping);
        tonemapping.mode.value = TonemappingMode.ACES;
    }

    void Update()
    {
        // 动态调整色调映射参数
        tonemapping.exposure.value = Mathf.Max(0.1f, Input.GetAxis("Mouse ScrollWheel"));
    }
}

        这些代码示例展示了《原神》可能使用的高级视觉效果技术的一部分。实际的实现会更加复杂,并且会涉及到大量的性能优化和细节调整。这些技术的应用和优化是《原神》能够提供高质量游戏体验的关键因素之一。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值