⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 macros.vsh

📁 hl2 source code. Do not use it illegal.
💻 VSH
📖 第 1 页 / 共 3 页
字号:
		dp3 $worldTangentS.x, $vUserData, $blendedMatrix0
		dp3 $worldTangentS.y, $vUserData, $blendedMatrix1
		dp3 $worldTangentS.z, $vUserData, $blendedMatrix2

		; calculate tangent t via cross( N, S ) * S[3]
		&Cross( $worldTangentT, $worldNormal, $worldTangentS );
		mul $worldTangentT.xyz, $vUserData.w, $worldTangentT.xyz

		&FreeRegister( \$boneIndices );
		&FreeRegister( \$blendedMatrix0 );
		&FreeRegister( \$blendedMatrix1 );
		&FreeRegister( \$blendedMatrix2 );
	}
	elsif( $numBones == 3 )
	{
		local( $boneIndices );
		local( $blendedMatrix0 );
		local( $blendedMatrix1 );
		local( $blendedMatrix2 );
		&AllocateRegister( \$boneIndices );
		&AllocateRegister( \$blendedMatrix0 );
		&AllocateRegister( \$blendedMatrix1 );
		&AllocateRegister( \$blendedMatrix2 );

		; Transform position into world space using all bones
		; denormalize d3dcolor to matrix index
		mad $boneIndices, $vBoneIndices, $cColorToIntScale, $cModel0Index
		; r11 = boneindices at this point
		; first matrix
		mov a0.x, $boneIndices.z
		mul $blendedMatrix0, $vBoneWeights.x, c[a0.x]
		mul $blendedMatrix1, $vBoneWeights.x, c[a0.x+1]
		mul $blendedMatrix2, $vBoneWeights.x, c[a0.x+2]
		; second matrix
		mov a0.x, $boneIndices.y
		mad $blendedMatrix0, $vBoneWeights.y, c[a0.x], $blendedMatrix0
		mad $blendedMatrix1, $vBoneWeights.y, c[a0.x+1], $blendedMatrix1
		mad $blendedMatrix2, $vBoneWeights.y, c[a0.x+2], $blendedMatrix2

		; Calculate third weight
		; compute 1-(weight1+weight2) to calculate weight2
		; Use $boneIndices.w as a temp since we aren't using it for anything.
		add $boneIndices.w, $vBoneWeights.x, $vBoneWeights.y
		sub $boneIndices.w, $cOne, $boneIndices.w

		; third matrix
		mov a0.x, $boneIndices.x
		mad $blendedMatrix0, $boneIndices.w, c[a0.x], $blendedMatrix0
		mad $blendedMatrix1, $boneIndices.w, c[a0.x+1], $blendedMatrix1
		mad $blendedMatrix2, $boneIndices.w, c[a0.x+2], $blendedMatrix2
		
		; position
		dp4 $worldPos.x, $vPos, $blendedMatrix0
		dp4 $worldPos.y, $vPos, $blendedMatrix1
		dp4 $worldPos.z, $vPos, $blendedMatrix2
		mov $worldPos.w, $cOne

		; normal
		dp3 $worldNormal.x, $vNormal, $blendedMatrix0
		dp3 $worldNormal.y, $vNormal, $blendedMatrix1
		dp3 $worldNormal.z, $vNormal, $blendedMatrix2

		; tangents
		dp3 $worldTangentS.x, $vUserData, $blendedMatrix0
		dp3 $worldTangentS.y, $vUserData, $blendedMatrix1
		dp3 $worldTangentS.z, $vUserData, $blendedMatrix2

		; calculate tangent t via cross( N, S ) * S[3]
		&Cross( $worldTangentT, $worldNormal, $worldTangentS );
		mul $worldTangentT.xyz, $vUserData.w, $worldTangentT.xyz

		&FreeRegister( \$boneIndices );
		&FreeRegister( \$blendedMatrix0 );
		&FreeRegister( \$blendedMatrix1 );
		&FreeRegister( \$blendedMatrix2 );
	}
}

sub ColorClamp
{
	; ColorClamp; stomps $color.w
	local( $color ) = shift;
	local( $dst ) = shift;

	; Get the max of RGB and stick it in W
	max $color.w, $color.x, $color.y
	max $color.w, $color.w, $color.z

	; get the greater of one and the max color.
	max $color.w, $color.w, $cOne

	rcp $color.w, $color.w
	mul $dst.xyz, $color.w, $color.xyz
}

sub AmbientLight
{
	local( $worldNormal ) = shift;
	local( $linearColor ) = shift;
	local( $add ) = shift;

	; Ambient lighting
	&AllocateRegister( \$nSquared );
	&AllocateRegister( \$isNegative );

	mul $nSquared.xyz, $worldNormal.xyz, $worldNormal.xyz				; compute n times n
	slt $isNegative.xyz, $worldNormal.xyz, $cZero				; Figure out whether each component is >0
	mov a0.x, $isNegative.x
	if( $add )
	{
		mad $linearColor.xyz, $nSquared.x, c[a0.x + $cAmbientColorPosXOffset], $linearColor			; $linearColor = normal[0]*normal[0] * box color of appropriate x side
	}
	else
	{
		mul $linearColor.xyz, $nSquared.x, c[a0.x + $cAmbientColorPosXOffset]			; $linearColor = normal[0]*normal[0] * box color of appropriate x side
	}
	mov a0.x, $isNegative.y
	mad $linearColor.xyz, $nSquared.y, c[a0.x + $cAmbientColorPosYOffset], $linearColor
	mov a0.x, $isNegative.z
	mad $linearColor.xyz, $nSquared.z, c[a0.x + $cAmbientColorPosZOffset], $linearColor

	&FreeRegister( \$isNegative );
	&FreeRegister( \$nSquared );
}

sub DirectionalLight
{
	local( $worldNormal ) = shift;
	local( $linearColor ) = shift;
	local( $add ) = shift;

	&AllocateRegister( \$nDotL ); # FIXME: This only needs to be a scalar

	; NOTE: Gotta use -l here, since light direction = -l
	; DIRECTIONAL LIGHT
	; compute n dot l
	dp3 $nDotL.x, -c[a0.x + 1], $worldNormal
	max $nDotL.x, $nDotL.x, c0.x			; Clamp to zero
	if( $add )
	{
		mad $linearColor.xyz, c[a0.x], $nDotL.x, $linearColor
	}
	else
	{
		mov $linearColor.xyz, c[a0.x], $nDotL.x
	}

	&FreeRegister( \$nDotL );
}

sub PointLight
{
	local( $worldPos ) = shift;
	local( $worldNormal ) = shift;
	local( $linearColor ) = shift;
	local( $add ) = shift;

	local( $lightDir );
	&AllocateRegister( \$lightDir );
	
	; POINT LIGHT
	; compute light direction
	sub $lightDir, c[a0.x+2], $worldPos
	
	local( $lightDistSquared );
	local( $ooLightDist );
	&AllocateRegister( \$lightDistSquared );
	&AllocateRegister( \$ooLightDist );

	; normalize light direction, maintain temporaries for attenuation
	dp3 $lightDistSquared, $lightDir, $lightDir
	rsq $ooLightDist, $lightDistSquared.x
	mul $lightDir, $lightDir, $ooLightDist.x
	
	local( $attenuationFactors );
	&AllocateRegister( \$attenuationFactors );

	; compute attenuation amount (r2 = 'd*d d*d d*d d*d', r3 = '1/d 1/d 1/d 1/d')
	dst $attenuationFactors, $lightDistSquared, $ooLightDist						; r4 = ( 1, d, d*d, 1/d )
	&FreeRegister( \$lightDistSquared );
	&FreeRegister( \$ooLightDist );
	local( $attenuation );
	&AllocateRegister( \$attenuation );
	dp3 $attenuation, $attenuationFactors, c[a0.x+4]				; r3 = atten0 + d * atten1 + d*d * atten2

	rcp $lightDir.w, $attenuation						; $lightDir.w = 1 / (atten0 + d * atten1 + d*d * atten2)

	&FreeRegister( \$attenuationFactors );
	&FreeRegister( \$attenuation );
	
	local( $tmp );
	&AllocateRegister( \$tmp ); # FIXME : really only needs to be a scalar

	; compute n dot l, fold in distance attenutation
	dp3 $tmp.x, $lightDir, $worldNormal
	max $tmp.x, $tmp.x, c0.x				; Clamp to zero
	mul $tmp.x, $tmp.x, $lightDir.w
	if( $add )
	{
		mad $linearColor.xyz, c[a0.x], $tmp.x, $linearColor
	}
	else
	{
		mov $linearColor.xyz, c[a0.x], $tmp.x
	}

	&FreeRegister( \$lightDir );
	&FreeRegister( \$tmp ); # FIXME : really only needs to be a scalar
}

sub SpotLight
{
	local( $worldPos ) = shift;
	local( $worldNormal ) = shift;
	local( $linearColor ) = shift;
	local( $add ) = shift;
	
	local( $lightDir );
	&AllocateRegister( \$lightDir );

	; SPOTLIGHT
	; compute light direction
	sub $lightDir, c[a0.x+2], $worldPos
	
	local( $lightDistSquared );
	local( $ooLightDist );
	&AllocateRegister( \$lightDistSquared );
	&AllocateRegister( \$ooLightDist );

	; normalize light direction, maintain temporaries for attenuation
	dp3 $lightDistSquared, $lightDir, $lightDir
	rsq $ooLightDist, $lightDistSquared.x
	mul $lightDir, $lightDir, $ooLightDist.x
	
	local( $attenuationFactors );
	&AllocateRegister( \$attenuationFactors );

	; compute attenuation amount (r2 = 'd*d d*d d*d d*d', r3 = '1/d 1/d 1/d 1/d')
	dst $attenuationFactors, $lightDistSquared, $ooLightDist						; r4 = ( 1, d, d*d, 1/d )

	&FreeRegister( \$lightDistSquared );
	&FreeRegister( \$ooLightDist );
	local( $attenuation );	&AllocateRegister( \$attenuation );

	dp3 $attenuation, $attenuationFactors, c[a0.x+4]				; r3 = atten0 + d * atten1 + d*d * atten2
	rcp $lightDir.w, $attenuation						; r1.w = 1 / (atten0 + d * atten1 + d*d * atten2)

	&FreeRegister( \$attenuationFactors );
	&FreeRegister( \$attenuation );
	
	local( $litSrc ); &AllocateRegister( \$litSrc );
	local( $tmp ); &AllocateRegister( \$tmp ); # FIXME - only needs to be scalar

	; compute n dot l
	dp3 $litSrc.x, $worldNormal, $lightDir
	
	; compute angular attenuation
	dp3 $tmp.x, c[a0.x+1], -$lightDir				; dot = -delta * spot direction
	sub $litSrc.y, $tmp.x, c[a0.x+3].z				; r2.y = dot - stopdot2
	&FreeRegister( \$tmp );
	mul $litSrc.y, $litSrc.y, c[a0.x+3].w			; r2.y = (dot - stopdot2) / (stopdot - stopdot2)
	mov $litSrc.w, c[a0.x+3].x						; r2.w = exponent
	local( $litDst ); &AllocateRegister( \$litDst );
	lit $litDst, $litSrc							; r3.y = N dot L or 0, whichever is bigger
	&FreeRegister( \$litSrc );
													; r3.z = pow((dot - stopdot2) / (stopdot - stopdot2), exponent)
	min $litDst.z, $litDst.z, $cOne		 			; clamp pow() to 1
	
	local( $tmp1 ); &AllocateRegister( \$tmp1 );
	local( $tmp2 ); &AllocateRegister( \$tmp2 );  # FIXME - could be scalar

	; fold in distance attenutation with other factors
	mul $tmp1, c[a0.x], $lightDir.w
	mul $tmp2.x, $litDst.y, $litDst.z
	if( $add )
	{
		mad $linearColor.xyz, $tmp1, $tmp2.x, $linearColor
	}
	else
	{
		mov $linearColor.xyz, $tmp1, $tmp2.x
	}

	&FreeRegister( \$lightDir );
	&FreeRegister( \$litDst );
	&FreeRegister( \$tmp1 );
	&FreeRegister( \$tmp2 );
}

sub DoLight
{
	local( $lightType ) = shift;
	local( $worldPos ) = shift;
	local( $worldNormal ) = shift;
	local( $linearColor ) = shift;
	local( $add ) = shift;

	if( $lightType eq "spot" )
	{
		&SpotLight( $worldPos, $worldNormal, $linearColor, $add );
	}
	elsif( $lightType eq "point" )
	{
		&PointLight( $worldPos, $worldNormal, $linearColor, $add );
	}
	elsif( $lightType eq "directional" )
	{
		&DirectionalLight( $worldNormal, $linearColor, $add );
	}
	else
	{
		die "don't know about light type \"$lightType\"\n";
	}
}

sub DoLighting
{
	local( $staticLightType ) = shift;
	local( $ambientLightType ) = shift;
	local( $localLightType1 ) = shift;
	local( $localLightType2 ) = shift;
	local( $worldPos ) = shift;
	local( $worldNormal ) = shift;

	# special case for no lighting
	if( $staticLightType eq "none" && $ambientLightType eq "none" &&
		$localLightType1 eq "none" && $localLightType2 eq "none" )
	{
		return;
	}

	# special case for static lighting only
	# Don't need to bother converting to linear space in this case.
	if( $staticLightType eq "static" && $ambientLightType eq "none" &&
		$localLightType1 eq "none" && $localLightType2 eq "none" )
	{
		mov oD0, $vSpecular
		return;
	}

	alloc $linearColor
	alloc $gammaColor

	local( $add ) = 0;
	if( $staticLightType eq "static" )
	{
		; The static lighting comes in in gamma space and has also been premultiplied by $cOverbrightFactor
		; need to get it into
		; linear space so that we can do adds.
		rcp $gammaColor.w, $cOverbrightFactor
		mul $gammaColor.xyz, $vSpecular, $gammaColor.w
		&GammaToLinear( $gammaColor, $linearColor );
		$add = 1;
	}

	if( $ambientLightType eq "ambient" )
	{
		&AmbientLight( $worldNormal, $linearColor, $add );
		$add = 1;
	}

	if( $localLightType1 ne "none" )
	{
		mov a0.x, c3.x
		&DoLight( $localLightType1, $worldPos, $worldNormal, $linearColor, $add );
		$add = 1;
	}

	if( $localLightType2 ne "none" )
	{
		mov a0.x, c3.y
		&DoLight( $localLightType2, $worldPos, $worldNormal, $linearColor, $add );
		$add = 1;
	}

	;------------------------------------------------------------------------------
	; Output color (gamma correction)
	;------------------------------------------------------------------------------

	&LinearToGamma( $linearColor, $gammaColor );
	if( 0 )
	{
		mul oD0.xyz, $gammaColor.xyz, $cOverbrightFactor
	}
	else
	{
		mul $gammaColor.xyz, $gammaColor.xyz, $cOverbrightFactor
		&ColorClamp( $gammaColor, "oD0" );
	}

;	mov oD0.xyz, $linearColor
	mov oD0.w, c0.y				; make sure all components are defined

	free $linearColor
	free $gammaColor
}

sub DoDynamicLightingToLinear
{
	local( $ambientLightType ) = shift;
	local( $localLightType1 ) = shift;
	local( $localLightType2 ) = shift;
	local( $worldPos ) = shift;
	local( $worldNormal ) = shift;
	local( $linearColor ) = shift;

	# No lights at all. . note that we don't even consider static lighting here.
	if( $ambientLightType eq "none" &&
		$localLightType1 eq "none" && $localLightType2 eq "none" )
	{
		mov $linearColor, $cZero
		return;
	}

	local( $add ) = 0;
	if( $ambientLightType eq "ambient" )
	{
		&AmbientLight( $worldNormal, $linearColor, $add );
		$add = 1;
	}

	if( $localLightType1 ne "none" )
	{
		mov a0.x, c3.x
		&DoLight( $localLightType1, $worldPos, $worldNormal, $linearColor, $add );
		$add = 1;
	}

	if( $localLightType2 ne "none" )
	{
		mov a0.x, c3.y
		&DoLight( $localLightType2, $worldPos, $worldNormal, $linearColor, $add );
		$add = 1;
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -