最近在做unity shader forge和marmoset的优化,TA那边遇到了一个阴影显示的问题,具体如下:

  在Forward Rendering状态下,静态场景使用了是shader forge生成的blendlayer类的shader,使用lightmap烘培贴图后,动态角色走到静态物体附近时,方向光在角色上的投影,无法投射到使用shader forge材质的物体上,但其他材质和使用marmoset的材质可以正常接收。查询了一些网站解决方案后,最终确定是custom shader 写法的问题,shader forge生成的shader属于自己实现vs和ps的功能,和写surface shader不同,除了着色用的shader pass("LightMode" = "ForwardBase")外需要Cast shadow用的第2个pass {"LightMode" = "ForwardAdd"}。
 
下面是一个参考方案的代码
  1.  "Test" {
    SubShader {
    Tags { "RenderType" = "Opaque"} // This pass acts the same as the surface shader first pass.
    // Calculates per-pixel the most important directional light with shadows,
    // then per-vertex the next 4 most important lights,
    // then per-vertex spherical harmionics the rest of the lights,
    // and the ambient light value. Pass {
    Tags {"LightMode" = "ForwardBase"}
    CGPROGRAM #pragma multi_compile_fwdbase
    #pragma vertex vert
    #pragma fragment frag
    #pragma fragmentoption ARB_precision_hint_fastest
    #include "UnityCG.cginc"
    #include "AutoLight.cginc" struct Input
    {
    float4 pos : SV_POSITION;
    float3 vlight : COLOR;
    float3 lightDir : TEXCOORD1;
    float3 vNormal : TEXCOORD2;
    LIGHTING_COORDS(,)
    }; Input vert(appdata_full v)
    {
    Input o;
    o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
    // Calc normal and light dir.
    o.lightDir = normalize(ObjSpaceLightDir(v.vertex));
    o.vNormal = normalize(v.normal).xyz; // Calc spherical harmonics and vertex lights. Ripped from compiled surface shader
    float3 worldPos = mul(_Object2World, v.vertex).xyz;
    float3 worldNormal = mul((float3x3)_Object2World, SCALED_NORMAL);
    o.vlight = float3();
    #ifdef LIGHTMAP_OFF float3 shlight = ShadeSH9(float4(worldNormal, 1.0));
    o.vlight = shlight;
    #ifdef VERTEXLIGHT_ON
    o.vlight += Shade4PointLights ( unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0, unity_LightColor[].rgb, unity_LightColor[].rgb, unity_LightColor[].rgb, unity_LightColor[].rgb, unity_4LightAtten0, worldPos, worldNormal ); #endif // VERTEXLIGHT_ON
    #endif // LIGHTMAP_OFF
    TRANSFER_VERTEX_TO_FRAGMENT(o);
    return o;
    } float4 _LightColor0; // Contains the light color for this pass. half4 frag(Input IN) : COLOR
    {
    IN.lightDir = normalize ( IN.lightDir );
    IN.vNormal = normalize ( IN.vNormal ); float atten = LIGHT_ATTENUATION(IN);
    float3 color;
    float NdotL = saturate( dot (IN.vNormal, IN.lightDir ));
    color = UNITY_LIGHTMODEL_AMBIENT.rgb * ; color += IN.vlight; color += _LightColor0.rgb * NdotL * ( atten * );
    return half4(color, 1.0f);
    } ENDCG
    } // Take this pass out if you don't want extra per-pixel lights.
    // Just set the other lights' Render Mode to "Not Important",
    // and they will be calculated as Spherical Harmonics or Vertex Lights in the above pass instead. Pass { Tags {"LightMode" = "ForwardAdd"} CGPROGRAM #pragma multi_compile_fwdadd
    #pragma vertex vert
    #pragma fragment frag
    #pragma fragmentoption ARB_precision_hint_fastest
    #include "UnityCG.cginc"
    #include "AutoLight.cginc" struct Input
    {
    float4 pos : SV_POSITION;
    float3 lightDir : TEXCOORD1;
    float3 vNormal : TEXCOORD2;
    }; Input vert(appdata_full v)
    {
    Input o;
    o.pos = mul(UNITY_MATRIX_MVP, v.vertex); // Calc normal and light dir.
    o.lightDir = normalize(ObjSpaceLightDir(v.vertex));
    o.vNormal = normalize(v.normal).xyz; // Don't need any ambient or vertex lights in here as this is just an additive pass for each extra light.
    // Shadows won't work here, either.
    return o;
    } float4 _LightColor0; // Contains the light color for this pass. half4 frag(Input IN) : COLOR
    {
    IN.lightDir = normalize ( IN.lightDir );
    IN.vNormal = normalize ( IN.vNormal ); float3 color;
    float NdotL = saturate( dot (IN.vNormal, IN.lightDir ));
    color = _LightColor0.rgb * NdotL;
    return half4(color, 1.0f);
    } ENDCG }
    } FallBack "Diffuse" }
 
而使用surface shader时候,只需要在声明surface时,设置制定的option(fullforwardshadows)就可以了
  1. #pragma surface MarmosetSurfMarmosetDirect vertex:MarmosetVert fullforwardshadows
回过头来说shader forge插件,场景左侧使用sf生成的shader,use lightmap后,实时阴影果断看不到了
 
左边木板为surface shader,右边为VS+PS Shader,阴影无法投射到石头上
 
将shader forge设置为multi-light,他会自动生成ForwardAdd的pass,这样阴影就显示出来了。但照明效果也完全变了样子
 
这个问题,在shader forge的论坛上也有提过,作者也说修改过这个bug了,但实际上最新的0.36还是没有完全解决
 
如果设置ForwardAdd后还没有投影,可以把light的lightmapping 设置为realtimeOnly。或者是再复制一个投影的主光源。
 
结论,Shader forge还是慎用吧,而且shader node也远没有比sky shop这类 uber shader要节省,为了投影,导致使用lightmap和real time的效果差别很大,
完全是得不偿失的。
 
 
 
 
 
 
 

关于Unity动态物体无法向使用使用custom shader和lightmap的物体投射阴影的更多相关文章

  1. Unity 3D动态修改Shader状态,使物体透明等等

    Unity动态改Shader状态透明 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- ...

  2. Unity动态加载和内存管理(三合一)

    原址:http://game.ceeger.com/forum/read.php?tid=4394#info 最近一直在和这些内容纠缠,把心得和大家共享一下: Unity里有两种动态加载机制:一是Re ...

  3. Unity动态批处理和静态批处理学习

    本文转自:http://blog.csdn.net/lyh916/article/details/45725499,请点击链接查看楼主大神原文,尊重楼主版权. 参考链接:Unity圣典:http:// ...

  4. [Unity][Heap sort]用Unity动态演示堆排序的过程(How Heap Sort Works)

    [Unity][Heap sort]用Unity动态演示堆排序的过程 How Heap Sort Works 最近做了一个用Unity3D动态演示堆排序过程的程序. I've made this ap ...

  5. Unity动态字体在手机上出现字体丢失问题解决

    在我们游戏的开发过程中,在部分手机上运行游戏的时候,出现了字体丢失的问题,出问题的手机似乎用的都是高通芯片. 使用的unity是4.2.0版本,ngui是3.4.9版本. 在unity的论坛及unit ...

  6. 【Unity Shaders】使用CgInclude让你的Shader模块化——Unity内置的CgInclude文件

    本系列主要參考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同一时候会加上一点个人理解或拓展. 这里是本书全部的插图. 这里是本书所需的代码 ...

  7. Unity动态改变物体遮挡关系

    在动态创建物体时,通常同父级下先创建的子物体会被后创建的遮挡,此时就需要我们用代码改变对象的层级. GameObject go;go.transform.SetAsLastSibling();//设置 ...

  8. unity动态加载(翻译) .

    AssetBundles are files which you can export from Unity to contain assets of your choice. These files ...

  9. Unity 动态载入Panel并实现淡入淡出

    unity版本:4.5 NGUI版本:3.6.5 参考链接:http://tieba.baidu.com/p/3206366700,作者:百度贴吧 水岸上 动态载入NGUI控件,这里用Panel为例说 ...

随机推荐

  1. ES6新特性:Function函数扩展, 扩展到看不懂

    本文所有Demo的运行环境为nodeJS, 参考:让nodeJS支持ES6的词法----babel的安装和使用 : 函数的默认值: 如果有参数 ,那就用参数, 如果没有参数, 那就用默认的参数: aj ...

  2. jQuery 图片等比缩放

    $(function(){ $('.img-box img').load(function(){ var w = $(this).width(); var h =$(this).height(); i ...

  3. SpringMVC学习系列(8) 之 国际化

    一.基于浏览器请求的国际化实现: 1)在 spring的配置文件中添加 <bean id="messageSource" class="org.springfram ...

  4. bzoj4349: 最小树形图&&bzoj2260: 商店购物

    双倍经验大法吼 昨天发现不会最小属性图&朱刘算法啊 吓得我赶紧补了一发 朱刘算法模板题 #include <iostream> #include <cstdio> #i ...

  5. OPENGL若干重要基础概念

    投影:3D数据“压平”到2D的计算机屏幕上,即将真正的三维物体显示到二维屏幕上,这种3D压平到2D的过程称为投影. 投影类型:正投影,透视投影 正投影:垂直于投影平面的平行投影(不垂直的投影平面的平行 ...

  6. Redis_持久化之RDB

    rdb - Redis DataBase 官网介绍: 在指定的时间间隔内存中的数据集快照写入磁盘,也就是行话将的Snapshot快照,它恢复时是将快照文件直接读到内存中. 是什么: Redis会单独创 ...

  7. wpf中textbox与textblock有什么区别

    textbox是windows.form控件,textblock是WPF控件. 功能类似,但后者功能更强,也节省系统资源 wpf是基于directx技术的系统,向后兼容性更好. textblock只用 ...

  8. MAC上快速调出终端的设置(保持和Windows的操作一致)

    在Windows上可以这样操作[Win+R]键->输入[cmd/cmder]打开终端. 在MAC下需要做些设置:打开[系统偏好设置]->打开[键盘]->打开[快捷键]->找到[ ...

  9. Android成长日记-使用ViewFlipper实现屏幕切换动画效果

    (一) ViewFlipper介绍 Android系统自带的一个多页面管理控件,它可以实现子界面的自动切换 (二) 为ViewFlipper加入View 1. 静态导入:在Layout布局文件中直接导 ...

  10. WAF(Web Appliction Firewall) Bypass Technology Research

    catalog . What is Firewall . Detecting the WAF . Different Types of Encoding Bypass . Bypass本质 1. Wh ...