效果图:

使用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
    }
    }
}

Unity3D-RayMarch-几何图元1-添加基本着色模型的更多相关文章

  1. osg 基本几何图元

    转自:osg 基本几何图元 //osg 基本几何图元 // ogs中所有加入场景中的数据都会加入到一个Group类对象中,几何图元作为一个对象由osg::Geode类来组织管理. // 绘制几何图元对 ...

  2. OpenCV入门系列教学(三)绘制几何形状及添加文本

    一.绘制简单的几何形状和添加文本 opencv中绘制图形很简单,我们只需要使用下面这些常用函数即可. #画线 cv2.line() #画圆 cv2.circle() #画矩形 cv. rectangl ...

  3. Django编写RESTful API(五):添加超链接提高模型间的关联性

    前言 在第四篇中,加入了用户模型,以及相关的认证和权限的功能.但是我们在使用的时候,会发现在访问http://127.0.0.1:8000/users/时看到的用户列表,不能够直接点击某个链接然后查看 ...

  4. ROS * 通过launch文件添加多个模型

    我添加的是dae模型,urdf文件过两天贴 方法一 : <launch> <!-- these are the arguments you can pass this launch ...

  5. Unity3D NGUI 给button按钮添加单间事件

    Unity3D中, NGUI 给button按钮添加单间事件的方法很多,在这里只给推荐一种比较常用的方法. 推荐方法:使用UIListener. 1.给button组价添加上UIListener.选择 ...

  6. Unity3D-RayMarch-几何图元-3添加阴影

    效果图: 在RayMarch渲染算法中计算阴影非常简单,当射线碰撞到物体,从碰撞点逆着光源方向再次执行射线步进算法,如果这一过程中碰撞到了其他物体,则碰撞点被其他物体遮挡,该处具有阴影. shader ...

  7. Unity3D Animator控制参数和添加事件

    Animator控制参数和添加事件 using UnityEngine; using System.Collections; public class AniControl : MonoBehavio ...

  8. openGl超级宝典学习笔记 (2) 7个主要的几何图元

    点(GL_POINTS): 点总是正方形的像素,默认情况下,点的大小不受透视除法影响. 即无论与视点的距离怎样,它的大小都不改变.为了获得圆点.必须在抗锯齿模式下绘制点. 能够用glPointSize ...

  9. 【学习笔记】OSG 基本几何图元

    例:geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4)); 来指定要利用这些数据生成一个怎么样的形状. ...

随机推荐

  1. [编码实践]SpringBoot实战:利用Spring AOP实现操作日志审计管理

    设计原则和思路: 元注解方式结合AOP,灵活记录操作日志 能够记录详细错误日志为运营以及审计提供支持 日志记录尽可能减少性能影响 操作描述参数支持动态获取,其他参数自动记录. 1.定义日志记录元注解, ...

  2. 前端人员使用notepad++基本配置

    截图说明: 以上截图说的很明确了,基本满足基本的开发. notepad++前端配置版支持Emmet快速完成:支持Explorer目录管理:支持cmd控制台命令:支持MarkDown编辑预览:其他想用的 ...

  3. (20/24) webpack实战技巧:watch实现热打包和添加代码备注

    在前面的学习中,我们一直使用webpack-dev-server充当(本地)服务器和完成打包任务,但是当出项目团队联合开发,共同使用一个服务器时,这时候我们需要实时进行打包以确保团队间能进行联调或者进 ...

  4. Sublime Text 3 插件

    1.快捷键:ctrl+shift+P 2.输入install package,选择install package 3.输入需要安装的插件,选择安装 4.重启sublime 1. 格式化 html-cs ...

  5. 看Spring注解之IOC记录

    首先看源码里有些是java的元注解记录的有如下几个: @Inherited注释:指明被注解的类会自动继承.更具体地说,如果定义注解时使用了 @Inherited 标记,然后用定义的注解来标注另一个父类 ...

  6. servlet的运行机制,转发和重定向

    一.当发送一个请求到服务器端的时候,容器(tomcat)会判断该路径属于哪一个servlet进行处理,servlet有一个抽象父类“httpservlet”,这个类是一个模板设计模式的类,其中serv ...

  7. ajax的4个字母分别是什么意思

    Asynchronous JavaScript and XML 的缩写,异步的JavaScript和XML.在不重新加载整个页面的情况下 ,AJAX 与服务器交换数据并更新部分网页.

  8. 虚拟机安装及ubuntu-16.04.3-desktop-amd64.iso映像文件的安装

    虚拟机安装及ubuntu-16.04.3-desktop-amd64.iso映像文件 搞了大半天才搞清楚装linux的前提是要先安装虚拟机的 先下载虚拟机,在然后创建虚拟机,在虚拟机里面再安装linu ...

  9. 本地jar包添加至Maven仓库

    Maven命令将本地的jar包方放到maven仓库中 //自定义本地的jar包在pom文件的参数 <dependency> <groupId>com.eee</group ...

  10. MemoryStream说明

    MemoryStream 是内存流,为系统内存提供读写操作,由于 MemoryStream 是通过无符号字节数组组成的,可以说 MemoryStream 的性能可以算比较出色,所以它担当起了一些其他流 ...