shader之——移动端阴影实现

  移动端阴影的实现有很多种方式,用shader实现个人觉得是比较省的方法。原理比较简单,

将模型的沿着y方向压扁,然后按照一个方向把zx做延伸,相当于多渲染一次模型,也多了一个dc

但是比起昂贵的实时阴影,还是相当省的。

阴影相当于一个平面,即使是这样,也可以适应稍有起伏的地形

代码如下:

Shader "Game-X/PlanarShadow" {

    Properties {
        _Strength ("Strength", Range(0.1, 10)) = 3
        _MainTex ("Base (RGB)", 2D) = "white" {}
        _Projplane ("_Projplane", Float) = 0
        _Lightdir ("_Lightdir", Vector) = (0, 0.707, 0.707)
    }
    SubShader {

        Tags { "Queue" = "Geometry+1" "RenderType" = "Opaque" }

        pass {
            Tags { "LightMode" = "ForwardBase" }
            Blend One SrcAlpha
            ZWrite Off
            ZTest Off

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile _BLEND_ALPHA_ON _BLEND_ALPHA_OFF
            #pragma multi_compile _BLEND_ADDITIVE_ON _BLEND_ADDITIVE_OFF
            #include "UnityCG.cginc"
            #include "Lighting.cginc"

            struct vsIn
            {
                float4 vertex   : POSITION;
                #if defined (_BLEND_ALPHA_ON) || defined (_BLEND_ADDITIVE_ON)
                float2 texcoord : TEXCOORD0;
                #endif
            };

            struct vsOut
            {
                float4 wpos        : SV_POSITION;
                #if defined (_BLEND_ALPHA_ON) || defined (_BLEND_ADDITIVE_ON)
                float2 texcoord : TEXCOORD0;
                #endif
            };

            float _Strength;
            float _Projplane;
            float3 _Lightdir;

            sampler2D _MainTex;
            float4 _MainTex_ST;

            vsOut vert(vsIn In)
            {
                vsOut o;
                float4 wp = mul(unity_ObjectToWorld, In.vertex);
                if (wp.y < _Projplane)
                    wp.y = _Projplane;

                wp.xz = wp.xz - ((wp.y - _Projplane) / _Lightdir.y) * _Lightdir.xz;
                wp.y = _Projplane;
                o.wpos = mul(UNITY_MATRIX_VP, wp);
                #if defined (_BLEND_ALPHA_ON) || defined (_BLEND_ADDITIVE_ON)
                o.texcoord = TRANSFORM_TEX(In.texcoord, _MainTex);
                #endif
                return o;
            }

             float4 frag(vsOut In) : COLOR
            {
                float4 ambient = UNITY_LIGHTMODEL_AMBIENT * 2;
                float k = (ambient.r + ambient.g + ambient.b) / _Strength;
                #ifdef _BLEND_ALPHA_ON
                float a = tex2D(_MainTex, In.texcoord).a;
                k = lerp(1, k, a);
                if (a <= 0)
                    clip(-1);
                #endif
                #ifdef _BLEND_ADDITIVE_ON
                float3 t = tex2D(_MainTex, In.texcoord).rgb;
                float q = (t.r + t.g + t.b) / 3;
                if (q <= 0)
                    clip(-1);
                #endif
                return float4(0,0,0,k);
            }

             ENDCG
        }
   }
}
时间: 2024-11-05 18:52:45

shader之——移动端阴影实现的相关文章

shader之——移动端次时代

做ta有两年多了,市面上有比较多的次时代手游出现,然而很多项目组还是望而却步.最纠结的还是效率问题, 今天就按照自己的理解,聊聊如何可以做一个高效率的次时代手游. 次时代手游,最有代表性的一块,是场景,它在人的视野中占据大部分比例,而场景最重要的是地表,所以今天 只谈谈地表的次时代制作. 一.贴图部分 首先,一个地表需要包含diffcuse. bump.spemask 如下图 spemask 是可以放在diffuse的通道里的,但是压缩带通道的贴图就不是那么容易了,所以把它提出来作为一张新的贴图

Unity Shader入门精要学习笔记 - 第3章 Unity Shader 基础

来源作者:candycat   http://blog.csdn.net/candycat1992/article/ 概述 总体来说,在Unity中我们需要配合使用材质和Unity Shader才能达到需要的效果.一个最常见的流程是. 1)创建一个材质 2)创建一个Unity Shader,并把它赋给上一步创建的材质 3)把材质赋给要渲染的对象 4)在材质面板中调整Unity Shader的属性,以得到满意的效果 下图显示了Unity Shader和材质是如何一起工作来控制物体的渲染的. Uni

搭建 Optix 环境

我参考了 第0个示例 OptixHello 学习Optix的工程配置以及基本框架 的配置过程,该文对于 Optix 的框架介绍的很好,但是按照该文配置遇到了一些问题,我花费了一番功夫自己摸索终于配置好了环境,实现了用Optix计算然后在OpenGL上展示结果的一个简单的Demo. 我的配置环境为:Win10,GTX1080,驱动版本431.6,Cuda9.0,Optix6.0,VS2015 Cuda我很早就安装了,很简单,这里就不做介绍了. 1.下载Optix6.0 地址:https://dev

NeHe OpenGL教程 第三十七课:卡通映射

转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线教程的编写,以及yarn的翻译整理表示感谢. NeHe OpenGL第三十七课:卡通映射 卡通映射: 什么是卡通了,一个轮廓加上少量的几种颜色.使用一维纹理映射,你也可以实现这种效果. 看到人们仍然e-mail我请求在文章中使用我方才在GameDev.net上写的源代码,还看到文章的第二版(在那每一

Unity3d的批渲染 batch rendering

批渲染(Batch) batch render 是大部分引擎提高渲染效率的方法,基本原理就是通过将一些渲染状态一致的物体合成一个大物体,一次提交给gpu进行绘制,如果不batch的话,就要提交给很多次,这可以显著的节省drawcall,实际上这主要节省了cpu的时间,cpu从提交多次到提交一次,对gpu来说也不用多次切换渲染状态.当然能batch的前提一定是渲染状态一致的一组物体. Unity3d的批渲染分为两种,动态和静态 静态批 要求:必须使用同一张material,然后在编辑器里设置为st

Unity3D 中的灯光与渲染

最近仔细研究了Unity3D中的灯光以及渲染,有了全新的认识,在这里整理记录下来.博主所使用的是Unity3D 2017.3.1f1这个版本. 一.Unity3D中的灯光 Directional Light:平行光,用来模拟太阳发射的光. Point Light:点光源,用于模拟场景中的灯和其他本地光源. Spot Light:聚光灯,通常用于人造光源,如手电筒,汽车前灯和探照灯. Area Light:区域光,只能用于烘焙中. Reflection Group:反射探针,用于准确反射周围环境.

Cg入门17:Fragment shader - 片段级光照(添加阴影)

投射阴影 方法一:添加一个单独的pass通道 pass { Tags{"LightMode" = "ShadowCaster"} } ShadowCaster:阴影投射器,可以投射阴影 方法二:添加物体默认阴影投射 FallBack "Diffuse" 然后给光线开启阴影: 效果如下:(效果图为添加平行光) 如果要让我们的shader支持点光源阴影投射,就添加 FallBack "Diffuse" 添加点光源后效果: 接收阴影

Shader 1:能接受阴影的透明shader

第一次接触Shader,项目需要,直接说需求吧,需要一个透明并且能接受阴影的shader.unity系统自带的shader已经满足不了了.上一段代码吧 Shader "GreenArch/Transparent Plane Shadow2" { Properties { } SubShader { Tags { "RenderType"="Opaque" } Pass { Name "DEFERRED" Tags { &quo

Unity Shader 阴影

最近在看Unity shader开发实战详解,刚开始看阴影部分,稍微有了点思路.在这里写点笔记,算是小结吧. .阴影实现方法 一种是通过模拟光照的原理,用向量的方法 找到被光线照射的点 映射到平面的位置.这个需要高中的立体几何知识就能解决,通过向量的计算找到一条线相交于一个平面的点.将点的颜色改变 一般是改成灰色,模拟阴影.并不是说只能显示灰色,其他颜色也是可以的. 另外一种就是通过改变光照的强度值,首先判断物体的每个顶点是否被照射到,计算出没有被光线照射到的顶点光照值 改变光照值来实现阴影效果