Unity3D-RayMarch-几何图元1-添加基本着色模型
2024-10-10 01:36:41
效果图:
使用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 } } }
最新文章
- zozoui
- ORACLE 自定义聚合函数
- 00.PHP学习建议
- GO語言基礎教程:序章
- java攻城师之路--复习java web之jsp入门_El表达式_JSTL标签库
- EntityFramework之创建数据库及基本操作(一)
- 【Sort List】cpp
- Things about single men that women hate
- JS测试浏览器类型的代码
- vijosP1223麦森数
- JavaScript之将JS代码放在什么位置最合适
- Entity Framework细节追踪
- Hadoop化繁为简(二)—层层递进轻松入门hdfs
- 记录一次坑爹的Python脚本抢购低价手机经历!
- es6 语法 (map、set和obj 的对比)
- Prime Permutation
- 11、jQuery其余操作
- noip2017d1t1
- 提交代码到远程GIT仓库,代码自动同步到远程服务器上。
- 为什么程序员老在改 Bug,就不能一次改好吗?