Need for Speed RIVALS
There will be more information soon
SuperSimple&Fake SSS [Sub Surface Scattering]
Playing Remedy’s Alan Wake for Xbox, and feeling lost seeing its marvelous forest environment, wondering about how to procedurally animate trees and vegetation using vertex colors, the idea of SS&F-SSS came out: use mesh thickness to modulate a SSS color. [Yes…it’s not related to trees and vegetations actually]
I’m confident that this approach was discovered a lot of time ago, but I implemented it as coding exercise.
As first step I developed a maxscript function to evaluate the mesh thickness; the function casts a ray for every vertex normal (inverting their direction) and store the collision distance in the vertex’s color. After that some tuning is needed to get better results; this tune is usually a couple of blur passes.
This is the maxscript code to find the mesh thickness:
--convert a value to 0-255 range fn UT_to255 _min _max n = ( local result = ((n + (-1*_min))/float(_max))*255 return int(ceil(result)) ) --cast a ray for every mesh vertex and store the ray distance in the vertex color --NOTE: a vertex color tune is needed!! use the vertexPaint modifier fn aa_bakeMeshThickness theMesh = ( local rm = RayMeshGridIntersect() rm.Initialize 10 --init. the voxel grid size to 10x10x10 rm.addNode theMesh rm.buildGrid() --build the grid data (collecting faces into the grid voxels) local theGSMesh = snapshotasmesh theMesh local theColorArray = #() for v = 1 to theGSMesh.numverts do --go through all verts of the Geosphere ( local thePos = getVert theGSMesh v --get the position of the vertex local theNormal = -(getNormal theGSMesh v) --get the normal of the vertex, reverse direction local theHitsCount = rm.intersectRay thePos theNormal true --intersect the ray with the sphere if theHitsCount > 0 then --if have hit anything... ( local theIndex = rm.getClosestHit() --get the index of the closest hit by the ray local theFace = rm.getHitFace theIndex --get the face index corresponding to that indexed hit --append theFacesArray theFace --add to the face array to select the face... --find the distance from the current verte to the hit point local theFaceID = rm.getHitFace theIndex local theFaceCenter = meshop.getFaceCenter $ theFaceID local theDist = distance theFaceCenter thePos append theColorArray theDist --print theDist ) else format "The Ray % Missed\n" v ) --assign the vertex colors local vMin = amin theColorArray local vMax = amax theColorArray for v = 1 to theGSMesh.numverts do --go through all verts of the Geosphere ( local vColor = 255 - (UT_to255 vMin vMax theColorArray[v]) --print vColor meshop.setVertColor theMesh 0 v ((color vColor vColor vColor)) ) --vertex color tuning local vPaint = VertexPaint() addModifier theMesh vPaint ) --run global curMesh = $ if(classof curMesh != Editable_mesh) then convertToMesh curMesh aa_bakeMeshThickness curMesh curMesh.showVertexColors = on curMesh.vertexColorsShaded = off curMesh.vertexColorType = 0 |
And the HLSL code to use this information is:
float4 sssColor = float4(0,0,0,0); if(g_sssEnable) { float sssInterpolation = pow(max(dot(-IN.eyeVector, IN.LightVec.xyz), 0), 2); sssColor = lerp(float4(0,0,0,1), g_SSSColor, sssInterpolation) * float4(IN.vertColor, 1) * g_sssMultiplier; } |
Finally I simply add the sssColor to the output pixel.
dinamically load .net assemblies in 3dsMax
During intensive 3dsMax+C# development, a really annoyng issue is the blocking loading of .dll assemblies performed by 3dsMax.
The technique by Denis Trofimov solves the issue:
assemblyPath = @"\\aardolino\aa_imageMosaic.dll" assembly = (dotnetclass "System.Reflection.Assembly").Load ((dotnetclass "System.IO.File").ReadAllBytes assemblyPath) imgMosaic = dotNetObject "aa_imageMosaic_namespace.aa_imageMosaic_class" imgMos.showForm() |
More information here: http://forums.cgsociety.org/showpost.php?p=6864094&postcount=480