zoukankan      html  css  js  c++  java
  • 多光源 MultipleLight

    使用2个Pass增加光照效果;

    第一个Pass是基础光源,一般是第一个平行光;Tags{"LightMode" = "ForwardBase"}

    第二个光源是增加的光源,一般是点光源;Tags{"LightMode" = "ForwardAdd"} Blend One One

    混合:Blend

     
    这里例如我们给一个模型贴一个材质,那么在某个点计算出来颜色值称为源,而该点之前累积的颜色值,叫目标。
     
    语法
    Blend SrcFactor DstFactor  SrcFactor是源系数,DstFactor是目标系数
    最终颜色 = (Shader计算出的点颜色值 * 源系数)+(点累积颜色 * 目标系数)
     
    属性(往SrcFactor,DstFactor 上填的值)
    one                          1
    zero                         0
    SrcColor                         源的RGB值,例如(0.5,0.4,1)
    SrcAlpha                         源的A值, 例如0.6
    DstColor                   混合目标的RGB值例如(0.5,0.4,1)
    DstAlpha                         混合目标的A值例如0.6
    OneMinusSrcColor          (1,1,1) - SrcColor
    OneMinusSrcAlpha          1- SrcAlpha
    OneMinusDstColor          (1,1,1) - DstColor
    OneMinusDstAlpha          1- DstAlpha

    我们在Pass中计算光源时,需要注意,是平行光还是点光源:

     1                 float3 lightDirection; 
     2                 float atten; 
     3 
     4                 if(_WorldSpaceLightPos0.w==0.0)//平行光
     5                 {
     6                     atten = 1.0;
     7                     lightDirection = normalize(_WorldSpaceLightPos0.xyz);
     8                 }
     9                 else
    10                 {
    11                     float3 fragmentToLightSource = _WorldSpaceLightPos0.xyz -i.posWorld.xyz;
    12                     float distance = length(fragmentToLightSource);
    13                     atten  = 1.0/distance;
    14                     lightDirection = normalize(fragmentToLightSource);
    15                 }

    源代码:

      1 Shader "JQM/MultipleLight"
      2 {
      3     Properties
      4     {
      5         _Color("Color", color) = (1.0,1.0,1.0,1.0)
      6         _SpecColor("Specular Color", color) = (1.0,1.0,1.0,1.0)
      7         _Shininess("Shininess",float) = 10
      8         _RimColor("Rim Coloe Color", color) = (1.0,1.0,1.0,1.0)
      9         _RimPower("Rim Power",Range(0.1,10.0)) = 3.0
     10 
     11     }
     12     SubShader{
     13         Pass{
     14             
     15             Tags { "LightMode" = "ForwardBase"}
     16 
     17             CGPROGRAM
     18             #pragma vertex vert
     19             #pragma fragment frag
     20 
     21             //使用自定义变量
     22             uniform float4 _Color;
     23             uniform float4 _SpecColor;
     24             uniform float4 _RimColor;
     25             uniform float _Shininess;
     26             uniform float _RimPower;
     27 
     28             //使用Unity定义的变量
     29             uniform float4 _LightColor0;
     30 
     31             struct vertexInput{
     32                 float4 vertex:POSITION;
     33                 float3 normal:NORMAL;
     34             };
     35 
     36             struct vertexOutput{
     37                 float4 pos:SV_POSITION;
     38                 float4 posWorld:TEXCOORD0;
     39                 float3 normalDir:TEXCOORD1;
     40             };
     41 
     42             //顶点程序
     43             vertexOutput vert(vertexInput v)
     44             {
     45                 vertexOutput o;
     46                 o.posWorld = mul(_Object2World, v.vertex);
     47                 o.normalDir =  normalize( mul(float4(v.normal,0.0),_World2Object).xyz);
     48                 o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
     49                 return o;
     50             }
     51 
     52             //片段程序
     53             float4 frag(vertexOutput i):COLOR
     54             {
     55 
     56                 float3 normalDirection = i.normalDir;
     57                 float3 viewDirection = normalize(_WorldSpaceCameraPos.xyz- i.posWorld.xyz);
     58                 float3 lightDirection; 
     59                 float atten; 
     60 
     61                 if(_WorldSpaceLightPos0.w==0.0)//平行光
     62                 {
     63                     atten = 1.0;
     64                     lightDirection = normalize(_WorldSpaceLightPos0.xyz);
     65                 }
     66                 else
     67                 {
     68                     float3 fragmentToLightSource = _WorldSpaceLightPos0.xyz -i.posWorld.xyz;
     69                     float distance = length(fragmentToLightSource);
     70                     atten  = 1.0/distance;
     71                     lightDirection = normalize(fragmentToLightSource);
     72                 }
     73                 
     74                 //灯光
     75                 float3 diffuseReflection = atten * _LightColor0.xyz *  saturate( dot(normalDirection,lightDirection));
     76                 float3 specularReflection = atten * _LightColor0.xyz * _SpecColor.rgb*saturate( dot(normalDirection,lightDirection))*pow(saturate(dot(reflect(-lightDirection,normalDirection),viewDirection)),_Shininess);
     77                 
     78                 //Rim Light
     79                 float rim= 1-dot(normalize(viewDirection),normalDirection);
     80                 float3 rimLighting = atten * _LightColor0.xyz * _RimColor.rgb*saturate(dot(normalDirection,lightDirection))*pow(rim,_RimPower);
     81                 float3 lightFinal = rimLighting + diffuseReflection+specularReflection+UNITY_LIGHTMODEL_AMBIENT.xyz;
     82                 return float4(lightFinal*_Color.xyz,1.0);
     83             }
     84 
     85             ENDCG
     86         }
     87 
     88         Pass{
     89             
     90             Tags { "LightMode" = "ForwardAdd"}
     91             Blend  One One
     92 
     93             CGPROGRAM
     94             #pragma vertex vert
     95             #pragma fragment frag
     96 
     97             //使用自定义变量
     98             uniform float4 _Color;
     99             uniform float4 _SpecColor;
    100             uniform float4 _RimColor;
    101             uniform float _Shininess;
    102             uniform float _RimPower;
    103 
    104             //使用Unity定义的变量
    105             uniform float4 _LightColor0;
    106 
    107             struct vertexInput{
    108                 float4 vertex:POSITION;
    109                 float3 normal:NORMAL;
    110             };
    111 
    112             struct vertexOutput{
    113                 float4 pos:SV_POSITION;
    114                 float4 posWorld:TEXCOORD0;
    115                 float3 normalDir:TEXCOORD1;
    116             };
    117 
    118             //顶点程序
    119             vertexOutput vert(vertexInput v)
    120             {
    121                 vertexOutput o;
    122                 o.posWorld = mul(_Object2World, v.vertex);
    123                 o.normalDir =  normalize( mul(float4(v.normal,0.0),_World2Object).xyz);
    124                 o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
    125                 return o;
    126             }
    127 
    128             //片段程序
    129             float4 frag(vertexOutput i):COLOR
    130             {
    131 
    132                 float3 normalDirection = i.normalDir;
    133                 float3 viewDirection = normalize(_WorldSpaceCameraPos.xyz- i.posWorld.xyz);
    134                 float3 lightDirection; 
    135                 float atten; 
    136 
    137                 if(_WorldSpaceLightPos0.w==0.0)//平行光
    138                 {
    139                     atten = 1.0;
    140                     lightDirection = normalize(_WorldSpaceLightPos0.xyz);
    141                 }
    142                 else
    143                 {
    144                     float3 fragmentToLightSource = _WorldSpaceLightPos0.xyz -i.posWorld.xyz;
    145                     float distance = length(fragmentToLightSource);
    146                     atten = 1.0/distance;
    147                     lightDirection = normalize(fragmentToLightSource);
    148                 }
    149                 
    150                 //灯光
    151                 float3 diffuseReflection = atten * _LightColor0.xyz *  saturate( dot(normalDirection,lightDirection));
    152                 float3 specularReflection = atten * _LightColor0.xyz * _SpecColor.rgb*saturate( dot(normalDirection,lightDirection))*pow(saturate(dot(reflect(-lightDirection,normalDirection),viewDirection)),_Shininess);
    153                 
    154                 //Rim Light
    155                 float rim= 1-dot(normalize(viewDirection),normalDirection);
    156                 float3 rimLighting = atten * _LightColor0.xyz * _RimColor.rgb*saturate(dot(normalDirection,lightDirection))*pow(rim,_RimPower);
    157                 float3 lightFinal = rimLighting + diffuseReflection+specularReflection+UNITY_LIGHTMODEL_AMBIENT.xyz;
    158                 return float4(lightFinal*_Color.xyz,1.0);
    159             }
    160 
    161             ENDCG
    162         }
    163     }
    164     
    165 }
  • 相关阅读:
    yolo_to_onnx ValueError: need more tan 1 value to unpack
    yolo_to_onnx killed
    C++ 实现二维矩阵的加减乘等运算
    Leetcode 1013. Partition Array Into Three Parts With Equal Sum
    Leetcode 1014. Best Sightseeing Pair
    Leetcode 121. Best Time to Buy and Sell Stock
    Leetcode 219. Contains Duplicate II
    Leetcode 890. Find and Replace Pattern
    Leetcode 965. Univalued Binary Tree
    Leetcode 700. Search in a Binary Search Tree
  • 原文地址:https://www.cnblogs.com/jqm304775992/p/4896522.html
Copyright © 2011-2022 走看看