Search
  • Ziv

VSFX 755 Procedural 3D Shader Programming - Project 2




This project is to use C++ language to create Arnold shaders. The SideMask provides the functionality of applying two colors on the same geometry based on the normal.

The second sharder is to change the colors and blending it depending on the height of the object / world space.


You can find this two code down below at the bottom of this page.


Here are the steps that shows how to make this project.


Step 1:

Prepar the models.

I created two neon signs for lighting up the scene and a wall without thickness.


Step 2:













SideMask:

/*
Determines which color to use on the front / rear facing normals.
*/
#include <ai.h>
#include <cstring>

AI_SHADER_NODE_EXPORT_METHODS(SampleMethods);
 
namespace {
	enum paramIndex { k_rearColor, k_frontColor, k_swap };
	};
 
node_parameters {
	AiParameterRGBA("rearColor", 0.7f, 0.7f, 0, 0);
	AiParameterRGBA("frontColor", 0.7f, 0.7f, 0, 0);
	AiParameterBool("swap", 0);
	}
 
shader_evaluate {
	AtRGBA rearColor = AiShaderEvalParamRGBA(k_rearColor);
	AtRGBA frontColor = AiShaderEvalParamRGBA(k_frontColor);
	bool swap = AiShaderEvalParamBool(k_swap);

	// We are shading a front face...
	if(sg->N == sg->Nf)
		sg->out.RGBA() = (swap) ? rearColor : frontColor;
	else	
		sg->out.RGBA() = (swap) ? frontColor : rearColor;
	}
 
node_loader {
    if (i > 0)
        return false; 
    node->methods        = SampleMethods;
    node->output_type    = AI_TYPE_RGBA;
	node->name           = "zlSideMask";
    node->node_type      = AI_NODE_SHADER;
    strcpy(node->version, AI_VERSION);
    return true;
	}
	
// The remaining macros can be left "empty"
node_initialize { }
node_update { }
node_finish { }


Changing Color by Height:


/*
Malcolm Kesson
Sept 7 2019
*/
#include <ai.h>
#include <cstring>
  
// The sdk does not appear to implement the standart RenderMan style "mix" function.
// Consequently, we implement here!
AtRGB mix(AtRGB c1, AtRGB c2, float alpha) {
    return c1 * (1.0 - alpha) + c2 * alpha;
    }
    
AI_SHADER_NODE_EXPORT_METHODS(SampleMethods);
 
namespace {
    enum paramIndex { k_emissionColor, k_rearColor, k_frontColor, k_swap, 
					k_minEmissionColor, k_maxEmissionColor,	k_minEmissionHeight, k_maxEmissionHeight, k_blur,
					k_mode, k_matrix };
    };
    
static const char* space_mode[] = { "Object", "World", "User", NULL };
  
node_parameters {
    AiParameterRGB("emissionColor", 0.7f, 0.7f, 0);
	AiParameterRGB("rearColor", 0.7f, 0.7f, 0);
    AiParameterRGB("frontColor", 0.7f, 0, 0);
	AiParameterBool("swap", 0);
	AiParameterRGB("minEmissionColor", 0.7f, 0.7f, 0);
    AiParameterRGB("maxEmissionColor", 0.7f, 0, 0);
	AiParameterFlt("minEmissionHeight", 0.1);
	AiParameterFlt("maxEmissionHeight", 0.5);
	AiParameterFlt("blur", 0.5);
	AiParameterEnum("mode", 0, space_mode);
	AiParameterMtx("matrixInput", AI_M4_IDENTITY);
    }
  
shader_evaluate {
	AtRGB emissionColor = AiShaderEvalParamRGB(k_emissionColor);
	AtRGB rearColor = AiShaderEvalParamRGB(k_rearColor);
	AtRGB frontColor = AiShaderEvalParamRGB(k_frontColor);
	bool swap = AiShaderEvalParamBool(k_swap);
	AtRGB minEmissionColor = AiShaderEvalParamRGB(k_minEmissionColor);
	AtRGB maxEmissionColor = AiShaderEvalParamRGB(k_maxEmissionColor);
	float minEmissionHeight = AiShaderEvalParamFlt(k_minEmissionHeight);
	float maxEmissionHeight = AiShaderEvalParamFlt(k_maxEmissionHeight);
	float blur = AiShaderEvalParamFlt(k_blur);
	int   mode = AiShaderEvalParamEnum(k_mode); 
	float blend, height;
	
	switch(mode) {
        case 0:     height = sg->Po.y; // object space
                    break;
        case 1:     height = sg->P.y;  // world space
                    break;
        default:    AtMatrix m = *AiShaderEvalParamMtx(k_matrix); // user space
                    AtMatrix mm = AiM4Invert(m);
                    AtVector transformedP = AiM4PointByMatrixMult(mm, sg->P);
                    height = transformedP.y; 
                    break;
        }
	blend = AiSmoothStep(minEmissionHeight, maxEmissionHeight, height);
	sg->out.RGB() =  mix(minEmissionColor, maxEmissionColor, blend);
	
    //if(sg->N == sg->Nf)
	//	sg->out.RGB() = (swap) ? rearColor : frontColor;
	//else	
	//	sg->out.RGB() = (swap) ? frontColor : rearColor;
    }
 
node_loader {
    if (i > 0)
        return false; 
    node->methods        = SampleMethods;
    node->output_type    = AI_TYPE_RGB;
	node->name           = "zlEmission";
    node->node_type      = AI_NODE_SHADER;
    strcpy(node->version, AI_VERSION);
    return true;
    }
    
// The remaining macros can be left "empty"
node_initialize { }
node_update { }
node_finish { }



12 views

(912) 572-3743

  • artstation

©2020 by Ziv. Proudly created with Wix.com