Entity* entity->setCastShadows(false);

material material_name
{
receive_shadows off
transparency_casts_shadows off

technique
{
pass
{
}
}
}

void Ogre::Material::setReceiveShadows ( bool  enabled  );
void Ogre::Material::setTransparencyCastsShadows ( bool  enabled  );

bool bShadow = true;
Ogre::Entity* ent = ...;
Ogre::MaterialPtr mat = ent->getSubEntity(1)->getMaterial();
mat->setReceiveShadows(bShadow);
mat->setTransparencyCastsShadows(bShadow);
mat = ent->getSubEntity(2)->getMaterial();
mat->setReceiveShadows(bShadow);
mat->setTransparencyCastsShadows(bShadow);
ent->setCastShadows(bShadow);


블로그 이미지

영스파파

3D 세상을 만들기 위한 프로그래밍 정보들을 정리하는 공간

,

1. 쉐이더 코드 작성(GrayScale.cg)

sampler RT : register(s0);

void calculateMaterialColorInDirectionalLight(	float4 position			: POSITION,
								float4 normal			: NORMAL,
								float2 uv				: TEXCOORD0,
						  
								out float4 oPosition	: POSITION,
								out float3 oNormal		: COLOR,
								out float2 oUv			: TEXCOORD0,

								uniform float4x4	worldViewProj,
								uniform float4x4	world,
								uniform float3		ambient,
								uniform float		diffusePower,
								uniform float3		diffuse,
								uniform float3		lightDirection, 
								uniform float3		lightColor
								)
{
	oPosition = mul(worldViewProj, position);
	oUv = uv;
	oNormal = (normalize(mul(world, normal))).xyz;
	oNormal = diffuse * diffusePower * saturate(dot(oNormal, normalize(lightDirection)));
	oNormal = lightColor * (ambient + oNormal);
}

void calculateGrayScaleInMaterialColor(	float3 normal			: COLOR,
							float2 uv				: TEXCOORD0,
										
							out float4 oColor		: COLOR,
										
							uniform sampler2D	RT : register(s0),
							uniform float		grayRatio
							)
{
	float3 tex_col = tex2D(RT, uv).rgb * normal;
	float3 greyscale = tex_col * (1 - grayRatio) + dot(tex_col, float3(0.3, 0.59, 0.11)) * grayRatio;
	oColor = float4(greyscale, 1.0);
}

 - 출력 변수에는 out으로 선언한다.
 - C 코드에서 입력할 데이터들은 uniform으로 선언한다.

2. 메터리얼 작성(GrayScale.material)

vertex_program ColorConvertor/GrayScale_vp cg
{
	source GrayScale.cg
	entry_point calculateMaterialColorInDirectionalLight
	profiles vs_1_1 arbvp1

	default_params
	{
		param_named_auto worldViewProj worldviewproj_matrix
		param_named_auto world world_matrix

		param_named ambient float3 0.2 0.2 0.2
		param_named diffusePower float 1.5
		param_named diffuse float3 0.8 0.8 0.8
		param_named lightDirection float3 0.0 2.0 2.0
		param_named lightColor float3 1.0 1.0 1.0
	}
}

fragment_program ColorConvertor/GrayScale_fp cg
{
	source GrayScale.cg
	entry_point calculateGrayScaleInMaterialColor
	profiles ps_2_0 fp30

	default_params
	{
		param_named grayRatio float 0.0
	}
}

material ColorConvertor/GrayScale
{
	technique
	{
		pass
		{
			vertex_program_ref ColorConvertor/GrayScale_vp
			{
			
			}
			// alternate shadow caster program
			fragment_program_ref ColorConvertor/GrayScale_fp
			{
			}

			texture_unit RT
			{
				texture nskingr.jpg 2d
			}
		}
	}
}

 - vertex_program은 버텍스 쉐이더
 - fragment_program은 픽셀 쉐이더

 - source는 쉐이더 코드 파일명
 - entry_point는 쉐이더 코드 함수명
 - profiles는 컴파일할 쉐이더 버전

 - param_named_auto는 3번째 값(위에서 worldviewproj_matrix, world_matrix)에 따라 ogre에서 매 프레임마다 알아서 갱신시켜주는 데이터
 - param_named는 C 코드에서 설정을 해주어야 하는 데이터

 - texture_unit은 텍스쳐 설정(위에서는 RT라는 이름으로 텍스쳐 설정, 쉐이더 코드의 RT에 매칭)

 - 이름에 '/'가 들어간 것은 계층구조의 의미가 아님. 그냥 통채로 이름이다.

 - 픽셀 쉐이더는 오히려 1.1 지원이 안되는 카드가 있음(여기 참고).

3. 엔터티에 메터리얼 설정

    Entity* head2 = mSceneMgr->createEntity("Head2", "ninja.mesh");
    MaterialPtr material = (Ogre::MaterialPtr)Ogre::MaterialManager::getSingleton().getByName ("ColorConvertor/GrayScale");
    head2->setMaterial(material);
    Ogre::GpuProgramParametersSharedPtr filterParams = material->getTechnique(0)->getPass(0)->getVertexProgramParameters();
    filterParams->setNamedConstant("ambient", Vector3(0.2f, 0.2f, 0.2f));
    filterParams->setNamedConstant("diffusePower", 1.5f);
    filterParams->setNamedConstant("diffuse", Vector3(0.8f, 0.8f, 0.8f));
    filterParams->setNamedConstant("lightDirection", Vector3(0.0f, 2.0f, 2.0f));
    filterParams->setNamedConstant("lightColor", Vector3(1.0f, 1.0f, 1.0f));
    Ogre::GpuProgramParametersSharedPtr filterParams2 = material->getTechnique(0)->getPass(0)->getFragmentProgramParameters();
    filterParams2->setNamedConstant("grayRatio", 0.0f);
- 쉐이더와 메터리얼 파일 경로를 resources_d.cfg에 포함시켜야 한다.
- 메터리얼에서 기본값을 설정해 놓았으면 코드에서 설정할 필요는 없다.
- 메터리얼의 상수값을 각 엔터티에 다르게 설정하고 싶으면 Ogre::Material::clone("새로운 메터리얼 이름") 함수를 사용해서 메터리얼을 복사해서 사용하면 된다. 복사된 메터리얼은 원본 메터리얼의 상수 설정값을 그대로 가지고 있다.
블로그 이미지

영스파파

3D 세상을 만들기 위한 프로그래밍 정보들을 정리하는 공간

,

uniform input은 한 프레임이 렌더링 되는 동안에 변하는 않는 input을 말한다. 예를 들면 월드 매트릭스나 라이트 위치 같은 값들을 말한다.
varying input은 한 프레임이 렌더링 되는 동안에 변하는 input을 말한다. semantic(POSITION, COLOR 등등)이 붙은 input들을 말한다. uniform input이 아닌 모든 input이 varying input이다. 예를 들면 버텍스 위치나 노말, 텍스쳐 좌표들을 말한다.


블로그 이미지

영스파파

3D 세상을 만들기 위한 프로그래밍 정보들을 정리하는 공간

,