Color GetLightPathColor(Vector3 pos, Vector3 dir, float length) { RayTrace.Ray ray = new RayTrace.Ray(pos, dir, length); RayTrace.Intersect(ref ray); if (ray.geomID == RayTrace.Invalid) { return(Color.white); } else { SimpleModel model = scene.models[(int)ray.geomID]; SimpleMesh mesh = model.mesh; int t0 = mesh.triangles[ray.primID * 3 + 0]; int t1 = mesh.triangles[ray.primID * 3 + 1]; int t2 = mesh.triangles[ray.primID * 3 + 2]; Vector2 uv = RayTraceTool.Lerp(mesh.uv[t0], mesh.uv[t1], mesh.uv[t2], ray.u, ray.v); Vector3 hitPos = ray.pos + ray.dir * ray.length; Color texColor = model.material.PointSample(uv); if (texColor.a < 0.99f) { Color aheadColor = GetLightPathColor(hitPos, dir * 0.01f, length - ray.length); Color blendColor = (aheadColor * (1 - texColor.a)) + (texColor * texColor.a); return(blendColor); } } return(Color.black); }
Color TraceColor(Vector3 startPos, Vector3 rayDir, int sample, int depth) { if (depth <= 0) { return(Color.black); } RayTrace.Ray ray = new RayTrace.Ray(startPos, rayDir, 1000); RayTrace.Intersect(ref ray); if (ray.geomID == RayTrace.Invalid) { return(skyColor); } else { SimpleModel model = scene.models[(int)ray.geomID]; SimpleMesh mesh = model.mesh; int t0 = mesh.triangles[ray.primID * 3 + 0]; int t1 = mesh.triangles[ray.primID * 3 + 1]; int t2 = mesh.triangles[ray.primID * 3 + 2]; Vector2 uv = RayTraceTool.Lerp(mesh.uv[t0], mesh.uv[t1], mesh.uv[t2], ray.u, ray.v); Color texColor = model.material.LinearSample(uv); if (!ignoreMaterialColor) { texColor *= model.material.GetColor(); } if (model.material.GetRenderMode() == SimpleMaterial.RenderMode.Opaque) { texColor.a = 1; } Vector3 hitPos = ray.pos + ray.dir * ray.length; Vector3 hitNormal = RayTraceTool.Lerp(mesh.normals[t0], mesh.normals[t1], mesh.normals[t2], ray.u, ray.v); hitNormal = (model.rst.rot * hitNormal); float transFactor = 1 - texColor.a; float glossiness = model.material.glossiness; float reflectFactor = Mathf.Lerp(0.2f * glossiness, 1f, model.material.metallic); if (reflectFactor > 0.01f) { reflectFactor = Fresnel_Schlick(Vector3.Dot(-rayDir, hitNormal), reflectFactor); } float grayscale = texColor.grayscale; float diffuseFactor = Mathf.Clamp01(1 - transFactor - reflectFactor); int transSample = (int)(sample * grayscale * transFactor); int reflectSample = (int)(sample * reflectFactor); int diffuseSample = (int)(sample * grayscale * diffuseFactor); Color finaleColor = Color.black; Color reflectColor = Color.black; { Color finalLightColor = Color.black;// GetAllLightsColor(model, hitPos, hitNormal) * (reflectFactor + scene.lights.Length);//光源直接贡献 if (reflectSample > 0) { Vector3 reflectDir = Vector3.Reflect(rayDir, hitNormal); Vector3[] dirs = RayTraceTool.GetRandomDirs_BlinnPhong_Importance2(hitNormal, reflectDir, glossiness, reflectSample); for (int i = 0; i < reflectSample; i++) { finalLightColor += TraceColor(hitPos + hitNormal * 0.01f, dirs[i], 1, depth - 1);//间接光贡献 } finalLightColor /= (reflectSample); } reflectColor = Color.Lerp(Color.white, texColor, model.material.metallic) * finalLightColor; } Color diffuseColor = Color.black; { Color finalLightColor = GetAllLightsColor(model, hitPos, hitNormal) * (diffuseSample + scene.lights.Length);//光源直接贡献 if (diffuseSample > 0) { Vector3 reflectDir = Vector3.Reflect(rayDir, hitNormal); Vector3[] dirs = RayTraceTool.GetRandomDirs_RoundProj(hitNormal, diffuseSample); for (int i = 0; i < diffuseSample; i++) { finalLightColor += TraceColor(hitPos + hitNormal * 0.01f, dirs[i], 1, depth - 1);//间接光贡献 } } finalLightColor /= (diffuseSample + scene.lights.Length); diffuseColor = texColor * finalLightColor; } //Color reflectColor = Color.black; //if(reflectFactor > 0.01f){ // Vector3 refDir = Vector3.Reflect(rayDir,hitNormal); // Color finalLightColor = TraceColor(hitPos + refDir * 0.01f, refDir,reflectSample ,depth - 1); // reflectColor = finalLightColor; //} finaleColor = reflectColor * reflectFactor + diffuseColor * diffuseFactor; if (texColor.a < 0.99f) { Color transColor = TraceColor(hitPos + rayDir * 0.01f, rayDir, transSample, depth); if (model.material.GetRenderMode() == SimpleMaterial.RenderMode.Alphablend) { finaleColor = finaleColor * texColor.a + transColor * (1 - texColor.a); } else if (model.material.GetRenderMode() == SimpleMaterial.RenderMode.Multiply) { finaleColor = finaleColor * transColor; } else if (model.material.GetRenderMode() == SimpleMaterial.RenderMode.Additive) { finaleColor = finaleColor + transColor; } } return(finaleColor); } }