zoukankan      html  css  js  c++  java
  • 游戏编程精粹学习

    灯光衰减图可以模拟3D贴图的效果,但也有一定的局限性。给灯光使用衰减图可以一定程度的控制灯光形状。

    应该也是某种程度的灯光cookie。

    使用衰减图与翻页动画制作的灯火效果:

    优点

    • 一定程度上的3D Texture
    • 可以拿来做摇曳灯火等

    缺点:

    • 定制性比较高,真正使用可能要借助CB
    • 相比3D Texture可控程度有限

    原文先从泛光灯公式讲起,后讲到XY与Z的贴图拆分。这里仅大致实现。测试shader如下:

    Shader "Custom/VirtualPointLight"
    {
        Properties
        {
            _MainTex("Texture", 2D) = "white" {}
            _AtteTex_XY("Atte Texture XY", 2D) = "white" {}
            _AtteTex_Z("Atte Texture Z", 2D) = "white" {}
            _VirtualLightPos("Virtual Light Position", vector) = (0, 0, 0, 0)
            _VirtualLightRange("Virtual Light Range", float) = 0.5
            _VirtualLightColor("Virtual Light Color", Color) = (0, 0, 0, 0)
            _Shininess("Shininess", range(0.1, 100)) = 1
        }
    
        SubShader
        {
            Tags{ "RenderType" = "Opaque" }
    
            Pass
            {
                CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag
    
                #include "UnityCG.cginc"
    
                struct appdata
                {
                    float4 vertex : POSITION;
                    float2 uv : TEXCOORD0;
                    float3 normal :  NORMAL;
                };
    
                struct v2f
                {
                    float2 uv : TEXCOORD0;
                    float4 vertex : SV_POSITION;
                    float4 lightVolume : TEXCOORD1;
                    float3 d01 : TEXCOORD2;
                };
    
                sampler2D _MainTex;
    
                sampler2D _AtteTex_XY;
                sampler2D _AtteTex_Z;
    
                float4 _MainTex_ST;
                float4 _VirtualLightPos;
                float4 _VirtualLightColor;
                float _Shininess;
                float _VirtualLightRange;
    
                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);
                    float4 N = normalize(mul(unity_ObjectToWorld, v.normal));
                    float3 d = _VirtualLightPos - worldPosition;
    
                    o.d01 = d / _VirtualLightRange;
    
                    float3 L = d;
                    float3 V = normalize(_WorldSpaceCameraPos.xyz - worldPosition.xyz).xyz;
                    float3 H = normalize(L + V);
    
                    float4 diffuse = max(dot(N, L), 0);
                    float specular = pow(max(0, dot(H, N)), _Shininess);
    
                    o.lightVolume = diffuse + specular;
                    o.lightVolume = o.lightVolume;
    
                    return o;
                }
    
                fixed4 frag(v2f i) : SV_Target
                {
                    fixed4 col = tex2D(_MainTex, i.uv);
                    fixed d01_xy = tex2D(_AtteTex_XY, i.d01.xy + 0.5).r;
                    fixed d01_z = tex2D(_AtteTex_Z, half2(i.d01.z + 0.5, 0.5)).r;
    
                    fixed atte = 1 - (d01_xy + d01_z);
                    return col * _VirtualLightColor * (i.lightVolume * atte);
                }
                ENDCG
            }
        }
    }

    测试C#脚本:

    public class VirtualLightBind : MonoBehaviour
    {
        void Update()
        {
            material.SetVector("_VirtualLightPos", transform.position);
        }
    }
  • 相关阅读:
    elasticsearch 中的Multi Match Query
    activiti 流程部署的各种方式
    elasticsearch 嵌套对象之嵌套类型
    elasticsearch Java High Level REST 相关操作封装
    elasticsearch 字段数据类型
    ubuntu 安装 docker
    elasticsearch 通过HTTP RESTful API 操作数据
    facenet 人脸识别(二)——创建人脸库搭建人脸识别系统
    POJ 3093 Margaritas(Kind of wine) on the River Walk (背包方案统计)
    墨卡托投影, GPS 坐标转像素, GPS 坐标转距离
  • 原文地址:https://www.cnblogs.com/hont/p/10990564.html
Copyright © 2011-2022 走看看