效果图:

使用phong着色模型,将环境光、物体的漫反射光、镜面光三种光效加合而得到上图的效果

raymarch 的shader代码:

// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'

Shader "RayMarch/Primitives1_phong"
{
    Properties
    {
        _MainTex("Texture", 2D) = "white" {}
    }
        SubShader
    {
        Tags{ "RenderType" = "Opaque" }
        LOD 

        Pass
    {
        CGPROGRAM
#pragma vertex vert
#pragma fragment frag

#include "UnityCG.cginc"
#include "Lighting.cginc"

#define PointLightPos fixed3(0, 3, 0)
#define LightColor float3(1,1,1)
#define GlobalAmibent float3(0.1,0.1,0.1)

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

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

    sampler2D _MainTex;
    float4 _MainTex_ST;

    //###################################################################################
    //sdf:define primitives
    float sdPlane(float3 p,float planeYPos)
    {
        return p.y - planeYPos;
    }

    float sdSphere(float3 p, float3 spherePos, float radius)
    {
        return length(p - spherePos) - radius;
    }
    //###################################################################################

    //###################################################################################
    //primitives boolean operation
    //求并集
    float2 opU(float2 d1, float2 d2)
    {
        return (d1.x<d2.x) ? d1 : d2;
    }
    //###################################################################################

    // define the scene
    float2 map(in float3 pos)
    {
        //plane
        //float2(x,y)的第二个参数定义了该物体的材质id,在render环节,可以根据id做不同处理
        float2 plane = float2(sdPlane(pos, -);
        float2 ball_1 = float2(sdSphere(pos, float3(, , ), );
        float2 ball_2 = float2(sdSphere(pos, float3(, , ), );
        float2 ball_3 = float2(sdSphere(pos, float3(-, , ), );
        //求物体的并集
        float2 res = opU(opU(opU(ball_1, ball_2), ball_3),plane);
        return res;
    }

    float2 castRay(in float3 ro, in float3 rd)
    {
        float tmin = 1.0;
        //射线最大允许经过的距离
        float tmax = 100.0;
        //当前已经过的距离
        float t = tmin;
        //材质id
        float m = -1.0;
        //最大迭代次数定位64
        ; i<; i++)
        {
            //距离精度随距离的增加而减小
            float precis = 0.0005*t;
            //获得场景中物体距离该点的距离,及距离最近物体的材质id
            float2 res = map(ro + rd*t);
            //如果与场景物体发生碰撞,或者射线行进距离超出最大范围,则跳出迭代
            if (res.x<precis || t>tmax) break;
            t += res.x;
            m = res.y;
        }
        if (t>tmax) m = -1.0;
        return float2(t, m);
    }

    //计算碰撞点处物体表面的法线
    float3 calcNormal(in float3 pos)
    {
        float3 eps = float3(0.0005, 0.0, 0.0);
        float3 nor = float3(
            map(pos + eps.xyy).x - map(pos - eps.xyy).x,
            map(pos + eps.yxy).x - map(pos - eps.yxy).x,
            map(pos + eps.yyx).x - map(pos - eps.yyx).x);
        return normalize(nor);
    }

    float3 BasicPhong(fixed3 lightDir, fixed3 normalDir, fixed3 viewDir, int matIndex) {
        , Kd = , Ks = , Shininess = ;
        float3 matColor = float3();
        switch (matIndex) {
        :
            //极远处
            matColor = float3(, , );
            break;
        :
            matColor = float3(0.1, 0.1, 0.1);
            break;
        :
            matColor = float3(); Shininess = ;
            break;
        :
            matColor = float3(, 0.5, 0.5);
            break;
        :
            matColor = float3(, 0.5);
            break;
        default:
            break;
        }
        float3 amibent = Ka * GlobalAmibent * matColor;
        float3 diffuse = Kd * LightColor * clamp(dot(normalDir, lightDir), , ) * matColor;
        fixed3 reflectDir = reflect(-lightDir, normalDir);
        float3 specular = Ks * LightColor * pow(clamp(dot(viewDir, reflectDir), , ), Shininess) * matColor;
        float3 color = amibent + diffuse + specular;
        return color;
    }

    float3 render(in float3 ro, in float3 rd)
    {
        //投掷射线,获得与所场景物体的碰撞信息
        float2 res = castRay(ro, rd);
        float t = res.x;
        float m = res.y;
        float3 pos = ro + t*rd;
        float3 nor = calcNormal(pos);
        fixed3 lightPos = PointLightPos;
        fixed3 lightDir = normalize(lightPos - pos);

        float3 col = BasicPhong(lightDir, nor, rd, m);
        return col;

    }

    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
    {
        //虚拟摄像机坐标
        float3 ro = float3(,,-);
        //投影面某点坐标
        float3 p = float3(i.uv - float2();
        //投掷射线
        float3 rd = normalize(p - ro);
        fixed4 col = fixed4(render(ro, rd).rgb, );
        // gamma校正
        col.rgb = pow(col.rgb, float3(0.4545, 0.4545, 0.4545));
        return col;
    }
        ENDCG
    }
    }
}

最新文章

  1. zozoui
  2. ORACLE 自定义聚合函数
  3. 00.PHP学习建议
  4. GO語言基礎教程:序章
  5. java攻城师之路--复习java web之jsp入门_El表达式_JSTL标签库
  6. EntityFramework之创建数据库及基本操作(一)
  7. 【Sort List】cpp
  8. Things about single men that women hate
  9. JS测试浏览器类型的代码
  10. vijosP1223麦森数
  11. JavaScript之将JS代码放在什么位置最合适
  12. Entity Framework细节追踪
  13. Hadoop化繁为简(二)—层层递进轻松入门hdfs
  14. 记录一次坑爹的Python脚本抢购低价手机经历!
  15. es6 语法 (map、set和obj 的对比)
  16. Prime Permutation
  17. 11、jQuery其余操作
  18. noip2017d1t1
  19. 提交代码到远程GIT仓库,代码自动同步到远程服务器上。
  20. 为什么程序员老在改 Bug,就不能一次改好吗?

热门文章

  1. 对Spring Ioc的理解
  2. Python的闭包和装饰器
  3. ADB抓取内存命令
  4. Mybatis学习 day02
  5. 注解@Transactional(rollbackFor = Exception.class) 的用法
  6. Stack类常用api
  7. MPC学习笔记1:基于状态空间模型的预测控制(2)
  8. 【源】ensp 绑定本地网卡与仿真设备进行通信 场景下 仿真设备ping 不通 本机IP 问题
  9. centos7.4重置root密码
  10. ajax请求aspx.cs后台方法